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

[PATCH v3 4/4] vpci: allow 32-bit BAR writes with memory decoding enabled


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
  • Date: Mon, 23 Mar 2026 23:05:01 -0400
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • 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=QSf/Y6hBGzyirIB8wL+Tv2JZc0KdiMNKBUOutJwXS6A=; b=JrbzySqIyWd1xL0qglXI3FD9FJJMq8FsYBequF9FzfUzCmQ7hgHByw4PaMftxNpwn66qFZPh2LTPj7N9wCfLXTSlZlHbsBekY5JDDavuurb/jQDbX2BfTwNanUii3MI90AYgAE6TuiFFdqHpFAa+5Utc7+Dk6PZaQUiJDaalqwN3aiTenhCuWqfhtj7VZcZBASTQOFEZPyEnN1Bh93a2JU/tiiR7KSZ1K7LENXeq2PUk0+OG1SvubEJLXoaTsCWsYdKUwxHma8EL6o3KQFA7PK4gvBZskrkbFjKUG19a5ffHniQ/gG7cmq//BrAYLKSJ0/NAypMtddo0SDPFrKahdw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=fBWYCrztVbacYgALLFzAoFrtSd7diFq16O9xyAjjysgqj3aGwVvSVI1OuCp/V7bmcl1QTXYtuWnbuO1AGP44jQi4WZwnstimzC070LB7C8H4Cohe/62lURpKQdNvuLl77335JIjVWCk6/hRrl2T/LiSxRXVl+/PjeVlYqKVaEHoXZqunfa/r5qMH7IEdRO89MtvGZgOYynOvArtLGxZQCr0eo1x1EKDAU5DqKRDyAuBa8vcHufzjYSYlBeprntvtzHHChNQjhpyWnB4yWzvtAXU9FXeUTYbwW6mtsP3rm8ZW/lVVLGEVjFNBxzIFbCU/3L81bz8LIW2QYmhjAxLP+g==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=amd.com header.i="@amd.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Cc: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Tue, 24 Mar 2026 03:05:55 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Currently, Xen vPCI refuses BAR writes if the BAR is mapped in p2m. If
firmware initializes a 32-bit BAR to a bad address, Linux may try to
write a new address to the 32-bit BAR without disabling memory decoding.
Since Xen refuses such writes, the BAR (and thus PCI device) will be
non-functional.

Allow the hardware domain to issue 32-bit BAR writes with memory
decoding enabled. This increases the compatibility of PVH dom0 with more
hardware.

Note that Linux aims at disabling memory decoding before writing 64-bit
BARs. Continue to refuse 64-bit BAR writes in Xen while those BARs are
mapped for now to avoid mapping half-updated BARs in p2m.

Increase number of unmap/map slots to 2.

Resolves: https://gitlab.com/xen-project/xen/-/issues/197
Signed-off-by: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
---
v2->v3:
* minor tweaks for fixed number of map/unmap slots

v1->v2:
* rework on top of queued BAR map/unmap operation machinery

RFC->v1:
* keep memory decoding enabled in hardware
* allow write while memory decoding is enabled for 32-bit BARs only
* rework BAR mapping machinery to support unmap-then-map operation
---
 xen/drivers/vpci/header.c | 33 ++++++++++++++++++++++++---------
 xen/include/xen/vpci.h    |  2 +-
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index 9856840c3c87..2df992468383 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -605,6 +605,8 @@ static void cf_check bar_write(
 {
     struct vpci_bar *bar = data;
     bool hi = false;
+    uint16_t cmd = 0;
+    unsigned int map_slot = 0;
 
     ASSERT(is_hardware_domain(pdev->domain));
 
@@ -618,19 +620,29 @@ static void cf_check bar_write(
         val &= PCI_BASE_ADDRESS_MEM_MASK;
 
     /*
-     * Xen only cares whether the BAR is mapped into the p2m, so allow BAR
-     * writes as long as the BAR is not mapped into the p2m.
+     * Allow 64-bit BAR writes only when the BAR is not mapped in p2m. Always
+     * allow 32-bit BAR writes.
      */
     if ( bar->enabled )
     {
-        /* If the value written is the current one avoid printing a warning. */
-        if ( val != (uint32_t)(bar->addr >> (hi ? 32 : 0)) )
-            gprintk(XENLOG_WARNING,
-                    "%pp: ignored BAR %zu write while mapped\n",
-                    &pdev->sbdf, bar - pdev->vpci->header.bars + hi);
-        return;
-    }
+        if ( bar->type == VPCI_BAR_MEM32 )
+        {
+            if ( val == bar->addr )
+                return;
 
+            cmd = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
+            modify_bars(pdev, cmd, false, false, map_slot++);
+        }
+        else
+        {
+            /* If the value written is the same avoid printing a warning. */
+            if ( val != (uint32_t)(bar->addr >> (hi ? 32 : 0)) )
+                gprintk(XENLOG_WARNING,
+                        "%pp: ignored BAR %zu write while mapped\n",
+                        &pdev->sbdf, bar - pdev->vpci->header.bars + hi);
+            return;
+        }
+    }
 
     /*
      * Update the cached address, so that when memory decoding is enabled
@@ -650,6 +662,9 @@ static void cf_check bar_write(
     }
 
     pci_conf_write32(pdev->sbdf, reg, val);
+
+    if ( bar->enabled )
+        modify_bars(pdev, cmd, false, true, map_slot++);
 }
 
 static void cf_check guest_mem_bar_write(const struct pci_dev *pdev,
diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h
index a6f8cb67dcac..a458b722cea6 100644
--- a/xen/include/xen/vpci.h
+++ b/xen/include/xen/vpci.h
@@ -168,7 +168,7 @@ struct vpci_vcpu {
         bool rom_only : 1;
         bool map : 1;
         bool pending : 1;
-    } task[1];
+    } task[2];
 };
 
 void vpci_dump_msi(void);
-- 
2.53.0




 


Rackspace

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