[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v8 1/8] vpci/header: Emulate extended capability list for dom0
Add a new function to emulate extended capability list for dom0, and call it in init_header(). So that it will be easy to hide an extended capability whose initialization fails. As for the extended capability list of domU, just move the logic into above function and keep hiding it for domU. Signed-off-by: Jiqian Chen <Jiqian.Chen@xxxxxxx> --- cc: "Roger Pau Monné" <roger.pau@xxxxxxxxxx> --- v7->v8 changes: * Remove the unnecessary function vpci_hw_write32, since it can cause the value of the extended capability header cached in vPCI of dom0 is inconsistent with the hardware. v6->v7 changes: * Change word "guest" to "DomU" in vpci_init_ext_capability_list(). * Change parameter of vpci_init_ext_capability_list() to be const. * Delete check "if ( !header )" in the while loop of vpci_init_ext_capability_list(). * Change the loop from while to do while in vpci_init_ext_capability_list(). v5->v6 changes: * Delete unnecessary parameter "ttl" in vpci_init_ext_capability_list() since vpci_add_register() can already detect the overlaps. v4->v5 changes: * Add check: if capability list of hardware has a overlap, print warning and return 0. v3->v4 changes: * Add check "if ( !header ) return 0;" to avoid adding handler for device that has no extended capabilities. v2->v3 changes: * In vpci_init_ext_capability_list(), when domain is domU, directly return after adding a handler(hiding all extended capability for domU). * In vpci_init_ext_capability_list(), change condition to be "while ( pos >= 0x100U && ttl-- )" instead of "while ( pos && ttl-- )". * Add new function vpci_hw_write32, and pass it to extended capability handler for dom0. v1->v2 changes: new patch Best regards, Jiqian Chen. --- xen/drivers/vpci/header.c | 44 ++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c index bb76e707992c..f537f3f25d2a 100644 --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -825,6 +825,39 @@ static int vpci_init_capability_list(struct pci_dev *pdev) PCI_STATUS_RSVDZ_MASK); } +static int vpci_init_ext_capability_list(const struct pci_dev *pdev) +{ + unsigned int pos = PCI_CFG_SPACE_SIZE; + + if ( !is_hardware_domain(pdev->domain) ) + /* Extended capabilities read as zero, write ignore for DomU */ + return vpci_add_register(pdev->vpci, vpci_read_val, NULL, + pos, 4, (void *)0); + + do + { + uint32_t header = pci_conf_read32(pdev->sbdf, pos); + int rc; + + rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL, + pos, 4, (void *)(uintptr_t)header); + if ( rc == -EEXIST ) + { + printk(XENLOG_WARNING + "%pd %pp: overlap in extended cap list, offset %#x\n", + pdev->domain, &pdev->sbdf, pos); + return 0; + } + + if ( rc ) + return rc; + + pos = PCI_EXT_CAP_NEXT(header); + } while ( pos >= PCI_CFG_SPACE_SIZE ); + + return 0; +} + static int cf_check init_header(struct pci_dev *pdev) { uint16_t cmd; @@ -877,14 +910,9 @@ static int cf_check init_header(struct pci_dev *pdev) if ( rc ) return rc; - if ( !is_hwdom ) - { - /* Extended capabilities read as zero, write ignore */ - rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL, 0x100, 4, - (void *)0); - if ( rc ) - return rc; - } + rc = vpci_init_ext_capability_list(pdev); + if ( rc ) + return rc; if ( pdev->ignore_bars ) return 0; -- 2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |