Linux CXL
 help / color / mirror / Atom feed
From: <mhonap@nvidia.com>
To: <alex@shazbot.org>, <ankita@nvidia.com>, <jic23@kernel.org>,
	<dave.jiang@intel.com>, <alejandro.lucero-palau@amd.com>,
	<smadhavan@nvidia.com>, <pierrick.bouvier@oss.qualcomm.com>,
	<mst@redhat.com>, <imammedo@redhat.com>, <anisinha@redhat.com>,
	<pbonzini@redhat.com>, <eric.auger@redhat.com>,
	<peter.maydell@linaro.org>, <richard.henderson@linaro.org>,
	<clg@redhat.com>, <cohuck@redhat.com>
Cc: <kjaju@nvidia.com>, <vsethi@nvidia.com>, <zhiw@nvidia.com>,
	<mhonap@nvidia.com>, <qemu-devel@nongnu.org>,
	<qemu-arm@nongnu.org>, <linux-cxl@vger.kernel.org>,
	Shameer Kolothum <skolothumtho@nvidia.com>
Subject: [PATCH v2 10/10] hw/pci-host: Emit a _DSM on pxb-cxl to preserve firmware PCI config
Date: Thu, 17 Sep 2026 00:14:12 +0530	[thread overview]
Message-ID: <20260916184412.3825713-11-mhonap@nvidia.com> (raw)
In-Reply-To: <20260916184412.3825713-1-mhonap@nvidia.com>

From: Manish Honap <mhonap@nvidia.com>

A pxb-cxl host bridge had no PCI host-bridge _DSM method, so it could not
emit function 5 (preserve firmware PCI configuration) even when the
machine asks OSPM to keep the firmware resource assignments.

That preservation is required by the accelerated SMMUv3 (accel=on), which
describes MSI 1:1 mappings through IORT RMR nodes. An RMR reserves a fixed
IOVA range, so OSPM must not re-enumerate and reassign the PCI resources
underneath it. virt sets pci_preserve_config for that case and expects
every host bridge to emit the _DSM; the pxb-cxl bridge was the one that
did not, so a CXL topology under an accelerated SMMU lost the guarantee.

The BAR configuration itself is safe without this. vfio-pci marks every BAR
dword ALL_VIRT, so a guest BAR write updates only the virtual config and
cannot move the host resource; QEMU's trapped comp-regs region is a
subregion of the BAR MemoryRegion and follows any guest-visible relocation,
while the kernel's physical decoder mapping stays fixed. The CXL.mem window
comes through CEDT/CFMWS and is likewise unaffected by PCI resource
assignment.

Wire preserve_config through GPEXConfig into the CXL host bridge OSC path
so pxb-cxl bridges emit the _DSM function 5 when the machine preserves the
firmware configuration. Rename build_cxl_osc_method() to
acpi_dsdt_add_cxl_host_bridge_methods() to match the pxb-pcie analogue
acpi_dsdt_add_host_bridge_methods(), since it now appends the _OSC and,
under preserve_config, the _DSM. Gate the _DSM on preserve_config: x86 q35
passes false as it does not use the accelerated SMMU, so it emits no _DSM
and its ACPI tables stay byte for byte what they were.

AI-used-for: code (prototype)
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
Signed-off-by: Manish Honap <mhonap@nvidia.com>
---
 hw/acpi/Kconfig         |  1 +
 hw/acpi/cxl-stub.c      |  2 +-
 hw/acpi/cxl.c           | 12 +++++++++++-
 hw/acpi/pci.c           | 40 +++++++++++++++++++++++++++++++++++++++
 hw/i386/acpi-build.c    |  2 +-
 hw/pci-host/gpex-acpi.c | 42 ++---------------------------------------
 include/hw/acpi/cxl.h   |  2 +-
 include/hw/acpi/pci.h   |  1 +
 8 files changed, 58 insertions(+), 44 deletions(-)

diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index daabbe6cd1..9490b75c94 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -88,3 +88,4 @@ config ACPI_ERST
 config ACPI_CXL
     bool
     depends on ACPI
+    select ACPI_PCI
diff --git a/hw/acpi/cxl-stub.c b/hw/acpi/cxl-stub.c
index 15bc21076b..d7c6731975 100644
--- a/hw/acpi/cxl-stub.c
+++ b/hw/acpi/cxl-stub.c
@@ -6,7 +6,7 @@
 #include "hw/acpi/aml-build.h"
 #include "hw/acpi/cxl.h"
 
-void build_cxl_osc_method(Aml *dev)
+void acpi_dsdt_add_cxl_host_bridge_methods(Aml *dev, bool preserve_config)
 {
     g_assert_not_reached();
 }
diff --git a/hw/acpi/cxl.c b/hw/acpi/cxl.c
index 77c1db6561..dc2a5fcdfe 100644
--- a/hw/acpi/cxl.c
+++ b/hw/acpi/cxl.c
@@ -23,6 +23,7 @@
 #include "hw/pci/pci_host.h"
 #include "hw/cxl/cxl.h"
 #include "hw/cxl/cxl_host.h"
+#include "hw/acpi/pci.h"
 #include "hw/mem/memory-device.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/aml-build.h"
@@ -320,11 +321,20 @@ static Aml *__build_cxl_osc_method(void)
     return method;
 }
 
-void build_cxl_osc_method(Aml *dev)
+void acpi_dsdt_add_cxl_host_bridge_methods(Aml *dev, bool preserve_config)
 {
     aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
     aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
     aml_append(dev, aml_name_decl("SUPC", aml_int(0)));
     aml_append(dev, aml_name_decl("CTRC", aml_int(0)));
     aml_append(dev, __build_cxl_osc_method());
+    /*
+     * Only a machine that asks OSPM to preserve the firmware PCI configuration
+     * needs the _DSM (function 5). Emitting it unconditionally would change the
+     * DSDT of machines that pass preserve_config=false (x86 q35), breaking the
+     * golden-table tests for no functional gain, so gate it on preserve_config.
+     */
+    if (preserve_config) {
+        aml_append(dev, build_pci_host_bridge_dsm_method(preserve_config));
+    }
 }
diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c
index c82924be86..f1feb33fc2 100644
--- a/hw/acpi/pci.c
+++ b/hw/acpi/pci.c
@@ -351,3 +351,43 @@ Aml *build_pci_host_bridge_osc_method(bool enable_native_pcie_hotplug)
     aml_append(method, aml_return(aml_arg(3)));
     return method;
 }
+
+Aml *build_pci_host_bridge_dsm_method(bool preserve_config)
+{
+    Aml *method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
+    Aml *UUID, *ifctx, *ifctx1, *buf;
+    uint8_t byte_list[1] = {0};
+
+    /*
+     * PCI Firmware Specification 3.0
+     * 4.6.1. _DSM for PCI Express Slot Information
+     * The UUID in _DSM in this context is
+     * {E5C937D0-3553-4D7A-9117-EA4D19C3434D}
+     */
+    UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
+    ifctx = aml_if(aml_equal(aml_arg(0), UUID));
+    ifctx1 = aml_if(aml_equal(aml_arg(2), aml_int(0)));
+    if (preserve_config) {
+        /* support functions other than 0, specifically function 5 */
+        byte_list[0] = 0x21;
+    }
+    buf = aml_buffer(1, byte_list);
+    aml_append(ifctx1, aml_return(buf));
+    aml_append(ifctx, ifctx1);
+    if (preserve_config) {
+        Aml *ifctx2 = aml_if(aml_equal(aml_arg(2), aml_int(5)));
+        /*
+         * 0 - The operating system must not ignore the PCI configuration that
+         *     firmware has done at boot time.
+         */
+        aml_append(ifctx2, aml_return(aml_int(0)));
+        aml_append(ifctx, ifctx2);
+    }
+
+    aml_append(method, ifctx);
+
+    byte_list[0] = 0;
+    buf = aml_buffer(1, byte_list);
+    aml_append(method, aml_return(buf));
+    return method;
+}
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 6d7308b4e4..c8f02ea608 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1019,7 +1019,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
                 aml_append(aml_pkg, aml_eisaid("PNP0A08"));
                 aml_append(aml_pkg, aml_eisaid("PNP0A03"));
                 aml_append(dev, aml_name_decl("_CID", aml_pkg));
-                build_cxl_osc_method(dev);
+                acpi_dsdt_add_cxl_host_bridge_methods(dev, false);
             } else if (pci_bus_is_express(bus)) {
                 aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
                 aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index d9820f9b41..014f647c7f 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -51,45 +51,6 @@ static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq,
     }
 }
 
-static Aml *build_pci_host_bridge_dsm_method(bool preserve_config)
-{
-    Aml *method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
-    Aml *UUID, *ifctx, *ifctx1, *buf;
-    uint8_t byte_list[1] = {0};
-
-    /* PCI Firmware Specification 3.0
-     * 4.6.1. _DSM for PCI Express Slot Information
-     * The UUID in _DSM in this context is
-     * {E5C937D0-3553-4D7A-9117-EA4D19C3434D}
-     */
-    UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
-    ifctx = aml_if(aml_equal(aml_arg(0), UUID));
-    ifctx1 = aml_if(aml_equal(aml_arg(2), aml_int(0)));
-    if (preserve_config) {
-        /* support functions other than 0, specifically function 5 */
-        byte_list[0] = 0x21;
-    }
-    buf = aml_buffer(1, byte_list);
-    aml_append(ifctx1, aml_return(buf));
-    aml_append(ifctx, ifctx1);
-    if (preserve_config) {
-        Aml *ifctx2 = aml_if(aml_equal(aml_arg(2), aml_int(5)));
-        /*
-         * 0 - The operating system must not ignore the PCI configuration that
-         *     firmware has done at boot time.
-         */
-        aml_append(ifctx2, aml_return(aml_int(0)));
-        aml_append(ifctx, ifctx2);
-    }
-
-    aml_append(method, ifctx);
-
-    byte_list[0] = 0;
-    buf = aml_buffer(1, byte_list);
-    aml_append(method, aml_return(buf));
-    return method;
-}
-
 static void acpi_dsdt_add_host_bridge_methods(Aml *dev,
                                               bool enable_native_pcie_hotplug,
                                               bool preserve_config)
@@ -164,7 +125,8 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
             aml_append(dev, aml_name_decl("_CRS", crs));
 
             if (is_cxl) {
-                build_cxl_osc_method(dev);
+                acpi_dsdt_add_cxl_host_bridge_methods(dev,
+                                                      cfg->preserve_config);
             } else {
                 /* pxb bridges do not have ACPI PCI Hot-plug enabled */
                 acpi_dsdt_add_host_bridge_methods(dev, true,
diff --git a/include/hw/acpi/cxl.h b/include/hw/acpi/cxl.h
index 8f22c71530..6fe6c9c58d 100644
--- a/include/hw/acpi/cxl.h
+++ b/include/hw/acpi/cxl.h
@@ -24,7 +24,7 @@
 void cxl_build_cedt(GArray *table_offsets, GArray *table_data,
                     BIOSLinker *linker, const char *oem_id,
                     const char *oem_table_id, CXLState *cxl_state);
-void build_cxl_osc_method(Aml *dev);
+void acpi_dsdt_add_cxl_host_bridge_methods(Aml *dev, bool preserve_config);
 void build_cxl_dsm_method(Aml *dev);
 
 #endif
diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h
index 20b672575f..c7de33f8cf 100644
--- a/include/hw/acpi/pci.h
+++ b/include/hw/acpi/pci.h
@@ -42,6 +42,7 @@ void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope);
 void build_srat_generic_affinity_structures(GArray *table_data);
 
 Aml *build_pci_host_bridge_osc_method(bool enable_native_pcie_hotplug);
+Aml *build_pci_host_bridge_dsm_method(bool preserve_config);
 Aml *build_pci_bridge_edsm(void);
 
 #endif
-- 
2.25.1


  parent reply	other threads:[~2026-09-16 18:46 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-16 18:44 [PATCH v2 00/10] QEMU: CXL Type-2 device passthrough via vfio-pci mhonap
2026-09-16 18:44 ` [PATCH v2 01/10] linux-headers: Update vfio.h for CXL Type-2 passthrough mhonap
2026-09-16 18:44 ` [PATCH v2 02/10] hw/vfio/region: Add vfio_region_setup_with_ops() mhonap
2026-09-17 13:27   ` Cédric Le Goater
2026-09-21 10:48     ` Manish Honap
2026-09-16 18:44 ` [PATCH v2 03/10] hw/vfio/pci: Detect a CXL Type-2 device and read its geometry mhonap
2026-09-17 16:04   ` Cédric Le Goater
2026-09-21 10:49     ` Manish Honap
2026-09-16 18:44 ` [PATCH v2 04/10] hw/vfio/pci: Enforce the passthrough topology for a CXL device mhonap
2026-09-17 13:20   ` Cédric Le Goater
2026-09-21 10:45     ` Manish Honap
2026-09-16 18:44 ` [PATCH v2 05/10] hw/vfio/pci: Back the CXL memory with a RAM-device region mhonap
2026-09-17 13:56   ` Cédric Le Goater
2026-09-21 10:55     ` Manish Honap
2026-09-16 18:44 ` [PATCH v2 06/10] hw/vfio/pci: Bind a CXL device to its fixed memory window mhonap
2026-09-17 16:00   ` Cédric Le Goater
2026-09-21 11:03     ` Manish Honap
2026-09-16 18:44 ` [PATCH v2 07/10] hw/vfio/pci: Map the CXL memory on the guest decoder commit mhonap
2026-09-18 16:08   ` Cédric Le Goater
2026-09-21 11:14     ` Manish Honap
2026-09-20  9:14   ` Junjie Cao
2026-09-21 11:17     ` Manish Honap
2026-09-16 18:44 ` [PATCH v2 08/10] docs/cxl: Document CXL Type-2 device passthrough mhonap
2026-09-16 18:44 ` [PATCH v2 09/10] hw/arm/smmu-common: Allow pxb-cxl as an SMMUv3 primary bus mhonap
2026-09-16 18:44 ` mhonap [this message]
2026-09-20  9:14   ` [PATCH v2 10/10] hw/pci-host: Emit a _DSM on pxb-cxl to preserve firmware PCI config Junjie Cao
2026-09-21 11:20     ` Manish Honap

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260916184412.3825713-11-mhonap@nvidia.com \
    --to=mhonap@nvidia.com \
    --cc=alejandro.lucero-palau@amd.com \
    --cc=alex@shazbot.org \
    --cc=anisinha@redhat.com \
    --cc=ankita@nvidia.com \
    --cc=clg@redhat.com \
    --cc=cohuck@redhat.com \
    --cc=dave.jiang@intel.com \
    --cc=eric.auger@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=jic23@kernel.org \
    --cc=kjaju@nvidia.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=pierrick.bouvier@oss.qualcomm.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=skolothumtho@nvidia.com \
    --cc=smadhavan@nvidia.com \
    --cc=vsethi@nvidia.com \
    --cc=zhiw@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox