From: Manish Honap <[email protected]>
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.
This is not about the component register BAR moving. vfio-pci marks every
BAR dword ALL_VIRT, so a guest BAR write updates the virtual config only
and cannot move the host resource, and QEMU's trapped comp-regs region is
a subregion of the BAR MemoryRegion, so it follows any guest-visible
relocation while the kernel's physical decoder mapping stays fixed. The
CXL.mem window is delivered 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. 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 both the _OSC
and the _DSM. x86 passes false as it does not use the accelerated SMMU.
Signed-off-by: Manish Honap <[email protected]>
---
hw/acpi/Kconfig | 1 +
hw/acpi/cxl-stub.c | 2 +-
hw/acpi/cxl.c | 4 +++-
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, 50 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 f92f7fa3d5..7607ba500f 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,12 @@ 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());
+ aml_append(dev, build_pci_host_bridge_dsm_method(preserve_config));
}
diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c
index 8c7ed10479..1a20f8469b 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 8837b69687..a24bff8c88 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.