Add a new function to emulate extended capability list for host,
and call it in init_header(). So that, it will be easy to hide
a capability whose initialization fails.

As for the extended capability list of guest, keep hiding it.

Signed-off-by: Jiqian Chen <jiqian.c...@amd.com>
---
cc: "Roger Pau Monné" <roger....@citrix.com>
---
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 0910eb940e23..6833d456566b 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -815,6 +815,39 @@ static int vpci_init_capability_list(struct pci_dev *pdev)
     return rc;
 }
 
+static int vpci_init_ext_capability_list(struct pci_dev *pdev)
+{
+    int rc;
+    u32 header;
+    unsigned int pos = 0x100U, ttl = 480;
+
+    if ( !is_hardware_domain(pdev->domain) )
+    {
+        /* Extended capabilities read as zero, write ignore */
+        rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL,
+                               pos, 4, (void *)0);
+        if ( rc )
+            return rc;
+    }
+
+    while ( pos && ttl-- )
+    {
+        header = pci_conf_read32(pdev->sbdf, pos);
+
+        rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL,
+                               pos, 4, (void *)(uintptr_t)header);
+        if ( rc )
+            return rc;
+
+        if ( (header == 0) || (header == -1) )
+            return 0;
+
+        pos = PCI_EXT_CAP_NEXT(header);
+    }
+
+    return 0;
+}
+
 static int cf_check init_header(struct pci_dev *pdev)
 {
     uint16_t cmd;
@@ -867,14 +900,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


Reply via email to