[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v3 3/8] xen/vpci: introduce has_vpci_bridge


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Mykyta Poturai <Mykyta_Poturai@xxxxxxxx>
  • Date: Tue, 18 Nov 2025 13:36:33 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=hTGuoCs2WHO4MzRcHi6p/mnMsry/Pk1E1urssND/pzw=; b=xIYXcSFU4Q9s5zJ0j1z7VkfOKFfAF5hPGrFe+/vojLFDVcpjGfFrPTsew0P+8iZmpNTRPWX+OiGwrWLvpJbZOkgPZTpm3DKwEk1klKT2C4vsjxgrAyy+a67QNPoEkGhfbvzHJWoP1dEmlFF8huOr96hpkxfdZDCIrnYyB0hIdWWUrw0qi5VcwDqTV9Q43sucxtOSzyxVX1EycfpbQZqQGGCRtUrfheWi5TiS6EweOVtzcmIKPIbIN3hK7Hmg1T7jk2IGrIh1iIIGrvvhdy7FvqmmKrXs7LJEXxriL+468W83lXSE+2BDwElBUYoSzyjKCNOksubwTu9HlH5LHd1w1A==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FymBHOQ5qqRyn4hne7vE/T9D6noxTf2bSZwhHrEj345SS5IFvu3/PTnN9MlNONOoWPBj8I+50wJzzC7K5xJmrGPDgI8solUGnIEpWPkiMaTjhC2qSisv2nqh+7tCoALu2hVtk9GoyE0QdtoyrgdbOaKIwjcP7brjulf801K0K5zfS3o4isUcg49U2y/g1DN+al9pYXBD+pIhNDPdvaccI1v4NcYxLnLwx0jXH/RHwj2gwxljsYMVUu5nsiE9Qa/fynQ0uz3MOZNm3m6eBzLfypvW54nzOEB/wFtn3pdWSE4FwkK28devawJxNRwIFcgRI9hxrIuR+V8OzY7scL9dVw==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=epam.com;
  • Cc: Stefano Stabellini <stefano.stabellini@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Stewart Hildebrand <stewart.hildebrand@xxxxxxx>, Mykyta Poturai <Mykyta_Poturai@xxxxxxxx>
  • Delivery-date: Tue, 18 Nov 2025 13:36:49 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHcWJBaPhgfVTH0K0SSYJwd1HNNWw==
  • Thread-topic: [PATCH v3 3/8] xen/vpci: introduce has_vpci_bridge

From: Stefano Stabellini <stefano.stabellini@xxxxxxx>

With Dom0 now being able to use a virtual bridge we need a way to
distinguish Dom0 using HW bridghe from Dom0 using virtual bridge.
Introduce a new macro has_vpci_bridge that would determine if a domain
should be treated as using HW bridge (only Dom0 with pci-scan disabled)
or as using a virtual one (all DomUs and Dom0 with pci-scan enabled)

Use the macro in drivers/vpci.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxx>
Signed-off-by: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
Signed-off-by: Mykyta Poturai <mykyta_poturai@xxxxxxxx>
---
v2->v3:
* s/is_hwdom/is_hw_bridge/

v1->v2:
* simplify definition
---
 xen/arch/arm/include/asm/pci.h |  1 +
 xen/arch/arm/pci/pci.c         |  2 +-
 xen/drivers/vpci/header.c      | 74 +++++++++++++++++-----------------
 xen/drivers/vpci/vpci.c        |  4 +-
 xen/include/xen/vpci.h         |  8 ++++
 5 files changed, 50 insertions(+), 39 deletions(-)

diff --git a/xen/arch/arm/include/asm/pci.h b/xen/arch/arm/include/asm/pci.h
index 0680b2f50c..7289f7688b 100644
--- a/xen/arch/arm/include/asm/pci.h
+++ b/xen/arch/arm/include/asm/pci.h
@@ -23,6 +23,7 @@
 #define pci_to_dev(pcidev) (&(pcidev)->arch.dev)
 
 extern bool pci_passthrough_enabled;
+extern bool pci_scan_enabled;
 
 struct rangeset;
 
diff --git a/xen/arch/arm/pci/pci.c b/xen/arch/arm/pci/pci.c
index 49ee003c5e..951639eb3f 100644
--- a/xen/arch/arm/pci/pci.c
+++ b/xen/arch/arm/pci/pci.c
@@ -92,7 +92,7 @@ bool __read_mostly pci_passthrough_enabled;
 boolean_param("pci-passthrough", pci_passthrough_enabled);
 
 /* By default pci scan is disabled. */
-static __ro_after_init bool pci_scan_enabled;
+__ro_after_init bool pci_scan_enabled;
 boolean_param("pci-scan", pci_scan_enabled);
 
 static int __init pci_init(void)
diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index 469f497744..528e8b660b 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -230,7 +230,7 @@ bool vpci_process_pending(struct vcpu *v)
 
             read_unlock(&v->domain->pci_lock);
 
-            if ( !is_hardware_domain(v->domain) )
+            if ( has_vpci_bridge(v->domain) )
                 domain_crash(v->domain);
 
             return false;
@@ -492,7 +492,7 @@ static int modify_bars(const struct pci_dev *pdev, uint16_t 
cmd, bool rom_only)
             }
         }
 
-        if ( !is_hardware_domain(d) )
+        if ( has_vpci_bridge(d) )
             break;
 
         d = dom_xen;
@@ -522,7 +522,7 @@ static void cf_check cmd_write(
 {
     struct vpci_header *header = data;
 
-    if ( !is_hardware_domain(pdev->domain) )
+    if ( has_vpci_bridge(pdev->domain) )
     {
         const struct vpci *vpci = pdev->vpci;
 
@@ -564,7 +564,7 @@ static void cf_check bar_write(
     struct vpci_bar *bar = data;
     bool hi = false;
 
-    ASSERT(is_hardware_domain(pdev->domain));
+    ASSERT(!has_vpci_bridge(pdev->domain));
 
     if ( bar->type == VPCI_BAR_MEM64_HI )
     {
@@ -747,7 +747,7 @@ 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);
+    bool is_hw_bridge = !has_vpci_bridge(pdev->domain);
 
     if ( pci_conf_read16(pdev->sbdf, PCI_STATUS) & PCI_STATUS_CAP_LIST )
     {
@@ -758,17 +758,17 @@ static int vpci_init_capability_list(struct pci_dev *pdev)
             PCI_CAP_ID_MSIX,
         };
         /*
-         * For dom0, we should expose all capabilities instead of a fixed
+         * For hw bridge, we should expose all capabilities instead of a fixed
          * capabilities array, so setting n to 0 here is to get the next
          * capability position directly in pci_find_next_cap_ttl.
          */
-        const unsigned int n = is_hwdom ? 0 : ARRAY_SIZE(supported_caps);
+        const unsigned int n = is_hw_bridge ? 0 : ARRAY_SIZE(supported_caps);
 
         next = pci_find_next_cap_ttl(pdev->sbdf, PCI_CAPABILITY_LIST,
                                      supported_caps, n, &ttl);
 
         rc = vpci_add_register(pdev->vpci, vpci_read_val,
-                               is_hwdom ? vpci_hw_write8 : NULL,
+                               is_hw_bridge ? vpci_hw_write8 : NULL,
                                PCI_CAPABILITY_LIST, 1,
                                (void *)(uintptr_t)next);
         if ( rc )
@@ -776,7 +776,7 @@ static int vpci_init_capability_list(struct pci_dev *pdev)
 
         next &= ~3;
 
-        if ( !next && !is_hwdom )
+        if ( !next && !is_hw_bridge )
             /*
              * If we don't have any supported capabilities to expose to the
              * guest, mask the PCI_STATUS_CAP_LIST bit in the status
@@ -792,7 +792,7 @@ static int vpci_init_capability_list(struct pci_dev *pdev)
                                          pos + PCI_CAP_LIST_NEXT,
                                          supported_caps, n, &ttl);
 
-            if ( !is_hwdom )
+            if ( !is_hw_bridge )
             {
                 rc = vpci_add_register(pdev->vpci, vpci_hw_read8, NULL,
                                        pos + PCI_CAP_LIST_ID, 1, NULL);
@@ -801,7 +801,7 @@ static int vpci_init_capability_list(struct pci_dev *pdev)
             }
 
             rc = vpci_add_register(pdev->vpci, vpci_read_val,
-                                   is_hwdom ? vpci_hw_write8 : NULL,
+                                   is_hw_bridge ? vpci_hw_write8 : NULL,
                                    pos + PCI_CAP_LIST_NEXT, 1,
                                    (void *)(uintptr_t)next);
             if ( rc )
@@ -811,8 +811,8 @@ static int vpci_init_capability_list(struct pci_dev *pdev)
         }
     }
 
-    /* Return early for the hw domain, no masking of PCI_STATUS. */
-    if ( is_hwdom )
+    /* Return early for the hw bridge, no masking of PCI_STATUS. */
+    if ( is_hw_bridge )
         return 0;
 
     /* Utilize rsvdp_mask to hide PCI_STATUS_CAP_LIST from the guest. */
@@ -829,7 +829,7 @@ 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) )
+    if ( has_vpci_bridge(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);
@@ -866,7 +866,7 @@ int vpci_init_header(struct pci_dev *pdev)
     struct vpci_header *header = &pdev->vpci->header;
     struct vpci_bar *bars = header->bars;
     int rc;
-    bool is_hwdom = is_hardware_domain(pdev->domain);
+    bool is_hw_bridge = !has_vpci_bridge(pdev->domain);
 
     ASSERT(rw_is_write_locked(&pdev->domain->pci_lock));
 
@@ -893,15 +893,15 @@ int vpci_init_header(struct pci_dev *pdev)
      * PCI_COMMAND_PARITY, PCI_COMMAND_SERR, and PCI_COMMAND_FAST_BACK.
      */
     rc = vpci_add_register_mask(pdev->vpci,
-                                is_hwdom ? vpci_hw_read16 : guest_cmd_read,
+                                is_hw_bridge ? vpci_hw_read16 : guest_cmd_read,
                                 cmd_write, PCI_COMMAND, 2, header, 0, 0,
-                                is_hwdom ? 0
-                                         : PCI_COMMAND_RSVDP_MASK |
-                                           PCI_COMMAND_IO |
-                                           PCI_COMMAND_PARITY |
-                                           PCI_COMMAND_WAIT |
-                                           PCI_COMMAND_SERR |
-                                           PCI_COMMAND_FAST_BACK,
+                                is_hw_bridge ? 0
+                                             : PCI_COMMAND_RSVDP_MASK |
+                                               PCI_COMMAND_IO |
+                                               PCI_COMMAND_PARITY |
+                                               PCI_COMMAND_WAIT |
+                                               PCI_COMMAND_SERR |
+                                               PCI_COMMAND_FAST_BACK,
                                 0);
     if ( rc )
         return rc;
@@ -925,7 +925,7 @@ int vpci_init_header(struct pci_dev *pdev)
      * start with memory decoding disabled, and modify_bars() will not be 
called
      * at the end of this function.
      */
-    if ( !is_hwdom )
+    if ( !is_hw_bridge )
         cmd &= ~(PCI_COMMAND_VGA_PALETTE | PCI_COMMAND_INVALIDATE |
                  PCI_COMMAND_SPECIAL | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY 
|
                  PCI_COMMAND_IO);
@@ -933,7 +933,7 @@ int vpci_init_header(struct pci_dev *pdev)
     header->guest_cmd = cmd;
 
     /* Disable memory decoding before sizing. */
-    if ( !is_hwdom || (cmd & PCI_COMMAND_MEMORY) )
+    if ( !is_hw_bridge || (cmd & PCI_COMMAND_MEMORY) )
         pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd & ~PCI_COMMAND_MEMORY);
 
     for ( i = 0; i < num_bars; i++ )
@@ -945,9 +945,10 @@ int vpci_init_header(struct pci_dev *pdev)
         {
             bars[i].type = VPCI_BAR_MEM64_HI;
             rc = vpci_add_register(pdev->vpci,
-                                   is_hwdom ? vpci_hw_read32
-                                            : guest_mem_bar_read,
-                                   is_hwdom ? bar_write : guest_mem_bar_write,
+                                   is_hw_bridge ? vpci_hw_read32
+                                                : guest_mem_bar_read,
+                                   is_hw_bridge ? bar_write
+                                                : guest_mem_bar_write,
                                    reg, 4, &bars[i]);
             if ( rc )
                 goto fail;
@@ -959,7 +960,7 @@ int vpci_init_header(struct pci_dev *pdev)
         if ( (val & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO )
         {
             bars[i].type = VPCI_BAR_IO;
-            if ( !IS_ENABLED(CONFIG_X86) && !is_hwdom )
+            if ( !IS_ENABLED(CONFIG_X86) && !is_hw_bridge )
             {
                 rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL,
                                        reg, 4, (void *)0);
@@ -988,7 +989,7 @@ int vpci_init_header(struct pci_dev *pdev)
         {
             bars[i].type = VPCI_BAR_EMPTY;
 
-            if ( !is_hwdom )
+            if ( !is_hw_bridge )
             {
                 rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL,
                                        reg, 4, (void *)0);
@@ -1005,17 +1006,18 @@ int vpci_init_header(struct pci_dev *pdev)
         bars[i].prefetchable = val & PCI_BASE_ADDRESS_MEM_PREFETCH;
 
         rc = vpci_add_register(pdev->vpci,
-                               is_hwdom ? vpci_hw_read32 : guest_mem_bar_read,
-                               is_hwdom ? bar_write : guest_mem_bar_write,
+                               is_hw_bridge ? vpci_hw_read32
+                                            : guest_mem_bar_read,
+                               is_hw_bridge ? bar_write : guest_mem_bar_write,
                                reg, 4, &bars[i]);
         if ( rc )
             goto fail;
     }
 
     /* Check expansion ROM. */
-    rc = is_hwdom ? pci_size_mem_bar(pdev->sbdf, rom_reg, &addr, &size,
-                                     PCI_BAR_ROM)
-                  : 0;
+    rc = is_hw_bridge ? pci_size_mem_bar(pdev->sbdf, rom_reg, &addr, &size,
+                                         PCI_BAR_ROM)
+                      : 0;
     if ( rc > 0 && size )
     {
         struct vpci_bar *rom = &header->bars[num_bars];
@@ -1038,7 +1040,7 @@ int vpci_init_header(struct pci_dev *pdev)
                 goto fail;
         }
     }
-    else if ( !is_hwdom )
+    else if ( !is_hw_bridge )
     {
         /* TODO: Check expansion ROM, we do not handle ROM for guests for now 
*/
         header->bars[num_bars].type = VPCI_BAR_EMPTY;
diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index 07c7071d0a..8ea89b9805 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -48,7 +48,7 @@ static int assign_virtual_sbdf(struct pci_dev *pdev)
 
     ASSERT(rw_is_write_locked(&pdev->domain->pci_lock));
 
-    if ( is_hardware_domain(d) )
+    if ( !has_vpci_bridge(d) )
         return 0;
 
     /*
@@ -429,7 +429,7 @@ static const struct pci_dev *translate_virtual_device(const 
struct domain *d,
 #ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
     const struct pci_dev *pdev;
 
-    ASSERT(!is_hardware_domain(d));
+    ASSERT(has_vpci_bridge(d));
     ASSERT(rw_is_locked(&d->pci_lock));
 
     for_each_pdev ( d, pdev )
diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h
index 9ae75d946a..d4695cb353 100644
--- a/xen/include/xen/vpci.h
+++ b/xen/include/xen/vpci.h
@@ -339,6 +339,14 @@ static inline int __must_check vpci_reset_device(struct 
pci_dev *pdev)
     return vpci_assign_device(pdev);
 }
 
+#ifdef CONFIG_ARM
+#include <asm/pci.h>
+
+#define has_vpci_bridge(d) (!is_hardware_domain(d) || pci_scan_enabled)
+#else
+#define has_vpci_bridge(d) (!is_hardware_domain(d))
+#endif
+
 #endif
 
 /*
-- 
2.51.2



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.