Current logic of emulating legacy capability list is only for domU. So, expand it to emulate for dom0 too. Then it will be easy to hide a capability whose initialization fails in a function.
Signed-off-by: Jiqian Chen <jiqian.c...@amd.com> --- cc: "Roger Pau Monné" <roger....@citrix.com> --- v2->v3 changes: * Not to add handler of PCI_CAP_LIST_ID when domain is dom0. v1->v2 changes: new patch. Best regards, Jiqian Chen. --- xen/drivers/vpci/header.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c index 3e9b44454b43..c98cd211d9d7 100644 --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -749,9 +749,9 @@ static int vpci_init_capability_list(struct pci_dev *pdev) { int rc; bool mask_cap_list = false; + bool is_hwdom = is_hardware_domain(pdev->domain); - if ( !is_hardware_domain(pdev->domain) && - pci_conf_read16(pdev->sbdf, PCI_STATUS) & PCI_STATUS_CAP_LIST ) + if ( pci_conf_read16(pdev->sbdf, PCI_STATUS) & PCI_STATUS_CAP_LIST ) { /* Only expose capabilities to the guest that vPCI can handle. */ unsigned int next, ttl = 48; @@ -759,10 +759,11 @@ static int vpci_init_capability_list(struct pci_dev *pdev) PCI_CAP_ID_MSI, PCI_CAP_ID_MSIX, }; + const unsigned int *caps = is_hwdom ? NULL : supported_caps; + const unsigned int n = is_hwdom ? 0 : ARRAY_SIZE(supported_caps); next = pci_find_next_cap_ttl(pdev->sbdf, PCI_CAPABILITY_LIST, - supported_caps, - ARRAY_SIZE(supported_caps), &ttl); + caps, n, &ttl); rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL, PCI_CAPABILITY_LIST, 1, @@ -772,7 +773,7 @@ static int vpci_init_capability_list(struct pci_dev *pdev) next &= ~3; - if ( !next ) + if ( !next && !is_hwdom ) /* * If we don't have any supported capabilities to expose to the * guest, mask the PCI_STATUS_CAP_LIST bit in the status @@ -786,13 +787,15 @@ static int vpci_init_capability_list(struct pci_dev *pdev) next = pci_find_next_cap_ttl(pdev->sbdf, pos + PCI_CAP_LIST_NEXT, - supported_caps, - ARRAY_SIZE(supported_caps), &ttl); + caps, n, &ttl); - rc = vpci_add_register(pdev->vpci, vpci_hw_read8, NULL, - pos + PCI_CAP_LIST_ID, 1, NULL); - if ( rc ) - return rc; + if ( !is_hwdom ) + { + rc = vpci_add_register(pdev->vpci, vpci_hw_read8, NULL, + pos + PCI_CAP_LIST_ID, 1, NULL); + if ( rc ) + return rc; + } rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL, pos + PCI_CAP_LIST_NEXT, 1, -- 2.34.1