* [PATCH v2 1/8] acpi_dev_interface: add ghes support state at AcpiDeviceIfClass
2026-11-08 8:45 [PATCH v2 0/8] Add ghes support for x86 via SCI notification Mauro Carvalho Chehab
@ 2026-11-08 8:45 ` Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 2/8] tests/acpi: virt: reserve expected tables for PC GHES SCI support Mauro Carvalho Chehab
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Mauro Carvalho Chehab @ 2026-11-08 8:45 UTC (permalink / raw)
To: Michael S Tsirkin
Cc: Jonathan Cameron, Shiju Jose, qemu-devel, Igor Mammedov,
Mauro Carvalho Chehab, linux-edac, qemu-arm, Ani Sinha
Currently, ghes.c assumes that GHES support can be checked by
looking at GED. This is valid only for aarch64. As we're now
adding support for other architectures, this needs to be done
on a different way.
For instance, on x86, it needs to detect if GHES is supported
inside ICH9 and PIIX4 PM.
Add an ancillary method at acpi_dev_interface to share
information if ghes is supported on an arch-independent way.
It should be noticed that, with this change, there's no need to
include anymore hw/acpi/generic_event_device.h, as this were the
aarch64-specific GED interface sits and the code is now generic.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
hw/acpi/acpi_interface.c | 7 +++++++
hw/acpi/generic_event_device.c | 6 ++++++
hw/acpi/ghes.c | 30 +++++++++++++++++-----------
include/hw/acpi/acpi_dev_interface.h | 6 ++++++
4 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/hw/acpi/acpi_interface.c b/hw/acpi/acpi_interface.c
index a44679017ead..bf11acfbb54b 100644
--- a/hw/acpi/acpi_interface.c
+++ b/hw/acpi/acpi_interface.c
@@ -3,6 +3,13 @@
#include "hw/acpi/acpi_aml_interface.h"
#include "qemu/module.h"
+AcpiGhesState *acpi_device_get_ghes_state(AcpiDeviceIf *adev)
+{
+ AcpiDeviceIfClass *klass = ACPI_DEVICE_IF_GET_CLASS(adev);
+
+ return klass->get_ghes_state ? klass->get_ghes_state(adev) : NULL;
+}
+
static void register_types(void)
{
static const TypeInfo acpi_dev_if_info = {
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 65a5d1612fa4..c0913d458ff5 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -324,6 +324,11 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
acpi_cpu_ospm_status(&s->cpuhp_state, list);
}
+static AcpiGhesState *acpi_ged_get_ghes_state(AcpiDeviceIf *adev)
+{
+ return &ACPI_GED(adev)->ghes_state;
+}
+
static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
{
AcpiGedState *s = ACPI_GED(adev);
@@ -610,6 +615,7 @@ static void acpi_ged_class_init(ObjectClass *class, const void *data)
adevc->ospm_status = acpi_ged_ospm_status;
adevc->send_event = acpi_ged_send_event;
+ adevc->get_ghes_state = acpi_ged_get_ghes_state;
object_class_property_add_uint16_ptr(class, ACPI_PCIHP_IO_BASE_PROP,
offsetof(AcpiGedState,
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
index b2d5e3499320..3989fd4d7e91 100644
--- a/hw/acpi/ghes.c
+++ b/hw/acpi/ghes.c
@@ -24,7 +24,7 @@
#include "hw/acpi/ghes.h"
#include "hw/acpi/aml-build.h"
#include "qemu/error-report.h"
-#include "hw/acpi/generic_event_device.h"
+#include "hw/acpi/acpi_dev_interface.h"
#include "hw/nvram/fw_cfg.h"
#include "qemu/uuid.h"
#include "exec/cpu-common.h"
@@ -587,21 +587,27 @@ bool acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
source_id, errp);
}
-AcpiGhesState *acpi_ghes_get_state(void)
+static int acpi_ghes_find_state(Object *obj, void *opaque)
{
- AcpiGedState *acpi_ged_state;
+ Object *adev = object_dynamic_cast(obj, TYPE_ACPI_DEVICE_IF);
AcpiGhesState *ags;
- acpi_ged_state = ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED,
- NULL));
-
- if (!acpi_ged_state) {
- return NULL;
+ if (!adev) {
+ return 0;
}
- ags = &acpi_ged_state->ghes_state;
-
- if (!ags->hw_error_le && !ags->hest_addr_le) {
- return NULL;
+ ags = acpi_device_get_ghes_state(ACPI_DEVICE_IF(adev));
+ if (!ags || (!ags->hw_error_le && !ags->hest_addr_le)) {
+ return 0;
}
+ *(AcpiGhesState **)opaque = ags;
+ return 1;
+}
+
+AcpiGhesState *acpi_ghes_get_state(void)
+{
+ AcpiGhesState *ags = NULL;
+
+ object_child_foreach_recursive(object_get_root(), acpi_ghes_find_state,
+ &ags);
return ags;
}
diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h
index 65debb90a8d4..644e0006ff6a 100644
--- a/include/hw/acpi/acpi_dev_interface.h
+++ b/include/hw/acpi/acpi_dev_interface.h
@@ -26,6 +26,7 @@ DECLARE_CLASS_CHECKERS(AcpiDeviceIfClass, ACPI_DEVICE_IF,
TYPE_ACPI_DEVICE_IF)
typedef struct AcpiDeviceIf AcpiDeviceIf;
+typedef struct AcpiGhesState AcpiGhesState;
/**
* AcpiDeviceIfClass:
@@ -33,6 +34,7 @@ typedef struct AcpiDeviceIf AcpiDeviceIf;
* ospm_status: returns status of ACPI device objects, reported
* via _OST method if device supports it.
* send_event: inject a specified event into guest
+ * get_ghes_state: returns the controller's GHES state, if supported
* madt_cpu: fills @entry with Interrupt Controller Structure
* for CPU indexed by @uid in @apic_ids array,
* returned structure types are:
@@ -50,5 +52,9 @@ struct AcpiDeviceIfClass {
/* <public> */
void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
void (*send_event)(AcpiDeviceIf *adev, AcpiEventStatusBits ev);
+
+ AcpiGhesState *(*get_ghes_state)(AcpiDeviceIf *adev);
};
+
+AcpiGhesState *acpi_device_get_ghes_state(AcpiDeviceIf *adev);
#endif
--
2.56.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 2/8] tests/acpi: virt: reserve expected tables for PC GHES SCI support
2026-11-08 8:45 [PATCH v2 0/8] Add ghes support for x86 via SCI notification Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 1/8] acpi_dev_interface: add ghes support state at AcpiDeviceIfClass Mauro Carvalho Chehab
@ 2026-11-08 8:45 ` Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 3/8] hw/i186: add support for HEST table with SCI Mauro Carvalho Chehab
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Mauro Carvalho Chehab @ 2026-11-08 8:45 UTC (permalink / raw)
To: Michael S Tsirkin
Cc: Jonathan Cameron, Shiju Jose, qemu-devel, Igor Mammedov,
Mauro Carvalho Chehab, linux-edac, qemu-arm, Ani Sinha
Prepare to modify x86 firmware files, disabling DSDT and HEST table
check until we update it to new firmware file changes.
Notice that we're adding a SPDX header at the new files just to
shut up checkpatch. This will be dropped when we add the BIOS
binaries there.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
tests/data/acpi/x86/pc/DSDT.ras | 1 +
tests/data/acpi/x86/pc/HEST.ras | 1 +
tests/data/acpi/x86/q35/DSDT.ras | 1 +
tests/data/acpi/x86/q35/HEST.ras | 1 +
tests/qtest/bios-tables-test-allowed-diff.h | 4 ++++
5 files changed, 8 insertions(+)
create mode 100644 tests/data/acpi/x86/pc/DSDT.ras
create mode 100644 tests/data/acpi/x86/pc/HEST.ras
create mode 100644 tests/data/acpi/x86/q35/DSDT.ras
create mode 100644 tests/data/acpi/x86/q35/HEST.ras
diff --git a/tests/data/acpi/x86/pc/DSDT.ras b/tests/data/acpi/x86/pc/DSDT.ras
new file mode 100644
index 000000000000..73fa78ef14ea
--- /dev/null
+++ b/tests/data/acpi/x86/pc/DSDT.ras
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/tests/data/acpi/x86/pc/HEST.ras b/tests/data/acpi/x86/pc/HEST.ras
new file mode 100644
index 000000000000..73fa78ef14ea
--- /dev/null
+++ b/tests/data/acpi/x86/pc/HEST.ras
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/tests/data/acpi/x86/q35/DSDT.ras b/tests/data/acpi/x86/q35/DSDT.ras
new file mode 100644
index 000000000000..73fa78ef14ea
--- /dev/null
+++ b/tests/data/acpi/x86/q35/DSDT.ras
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/tests/data/acpi/x86/q35/HEST.ras b/tests/data/acpi/x86/q35/HEST.ras
new file mode 100644
index 000000000000..73fa78ef14ea
--- /dev/null
+++ b/tests/data/acpi/x86/q35/HEST.ras
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8bf4..b3761468accc 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,5 @@
/* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/x86/pc/DSDT.ras",
+"tests/data/acpi/x86/pc/HEST.ras",
+"tests/data/acpi/x86/q35/DSDT.ras",
+"tests/data/acpi/x86/q35/HEST.ras",
--
2.56.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 3/8] hw/i186: add support for HEST table with SCI
2026-11-08 8:45 [PATCH v2 0/8] Add ghes support for x86 via SCI notification Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 1/8] acpi_dev_interface: add ghes support state at AcpiDeviceIfClass Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 2/8] tests/acpi: virt: reserve expected tables for PC GHES SCI support Mauro Carvalho Chehab
@ 2026-11-08 8:45 ` Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 4/8] hw/i386: add GHES support at ICH9 and PIIX4 PM Mauro Carvalho Chehab
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Mauro Carvalho Chehab @ 2026-11-08 8:45 UTC (permalink / raw)
To: Michael S Tsirkin, Paolo Bonzini
Cc: Jonathan Cameron, Shiju Jose, qemu-devel, Igor Mammedov,
Mauro Carvalho Chehab, linux-edac, qemu-arm, Ani Sinha,
Richard Henderson
The _OSC device configuration object evaluates some platform
software specific support. Among them, there are bits there
to indicate if APEI support is enabled. Those are sitting
at the UUID 0811B06E-4A27-44F9-8D60-3CBBC22E7B48.
Bit 4 is APEI support. it has to be enabled to let x86 use
APEI/HEST/GHES.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
hw/i386/Kconfig | 1 +
hw/i386/acpi-build.c | 102 +++++++++++++++++++++++++++++++++++++++++++
hw/i386/pc.c | 41 +++++++++++++++++
include/hw/i386/pc.h | 5 +++
4 files changed, 149 insertions(+)
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index e27d8816e5bb..b1fbfaf33f9b 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -47,6 +47,7 @@ config PC
select MC146818RTC
# For ACPI builder:
select SERIAL_ISA
+ select ACPI_APEI
select ACPI_PCI
select ACPI_VMGENID
select ACPI_VMCLOCK
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 985515434974..6f960c66e2a4 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -71,6 +71,7 @@
#include "hw/acpi/utils.h"
#include "hw/acpi/pci.h"
#include "hw/acpi/cxl.h"
+#include "hw/acpi/ghes.h"
#include "qom/qom-qobject.h"
#include "hw/i386/amd_iommu.h"
@@ -852,6 +853,56 @@ static void build_acpi0017(Aml *table)
aml_append(table, scope);
}
+/* ACPI 5.0, 6.2.10.2: Platform-Wide OSPM Capabilities. */
+#define ACPI_PLAT_OSPM_CAP "0811B06E-4A27-44F9-8D60-3CBBC22E7B48"
+
+/* ACPI 5.0: Table 6-151: Platform-Wide _OSC caps DWORD 2 */
+#define ACPI_OSC_CAP_APEI (1U << 4)
+
+static Aml *build_apei_osc(uint32_t mask, uint32_t bits)
+{
+ Aml *method = aml_method("_OSC", 4, AML_SERIALIZED);
+ uint8_t failure[8] = { 2 }; /* _OSC failure */
+ uint32_t disabled = mask & ~bits;
+ Aml *support = aml_name("CDW2");
+ Aml *status = aml_name("CDW1");
+ Aml *if_ctx;
+
+ if_ctx = aml_if(aml_lless(aml_sizeof(aml_arg(3)), aml_int(8)));
+ aml_append(if_ctx, aml_return(aml_buffer(sizeof(failure), failure)));
+ aml_append(method, if_ctx);
+ aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
+ aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
+
+ /* Arg0: UUID */
+ if_ctx = aml_if(aml_lnot(aml_equal(aml_arg(0),
+ aml_touuid(ACPI_PLAT_OSPM_CAP))));
+ aml_append(if_ctx, aml_or(status, aml_int(4), status));
+ aml_append(if_ctx, aml_return(aml_arg(3)));
+ aml_append(method, if_ctx);
+
+ /* Arg1: Revision ID: 1 */
+ if_ctx = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
+ aml_append(if_ctx, aml_or(status, aml_int(8), status));
+ aml_append(if_ctx, aml_return(aml_arg(3)));
+ aml_append(method, if_ctx);
+
+ /* Arg2: count of entries in Arg3: 2 dwords */
+ if_ctx = aml_if(aml_lnot(aml_equal(aml_arg(2), aml_int(2))));
+ aml_append(if_ctx, aml_or(status, aml_int(2), status));
+ aml_append(if_ctx, aml_return(aml_arg(3)));
+ aml_append(method, if_ctx);
+
+ /* Arg3: Second DWORD: caps - update according with mask */
+ aml_append(method, aml_and(support, aml_int(~disabled), aml_local(0)));
+ if_ctx = aml_if(aml_lnot(aml_equal(support, aml_local(0))));
+ aml_append(if_ctx, aml_or(status, aml_int(mask), status));
+ aml_append(method, if_ctx);
+ aml_append(method, aml_store(aml_local(0), support));
+ aml_append(method, aml_return(aml_arg(3)));
+ return method;
+}
+
static void
build_dsdt(GArray *table_data, BIOSLinker *linker,
AcpiPmInfo *pm, AcpiMiscInfo *misc,
@@ -1284,6 +1335,21 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
aml_append(dsdt, scope);
}
+ if (pcms->ras) {
+ sb_scope = aml_scope("_SB");
+ aml_append(sb_scope, build_apei_osc(ACPI_OSC_CAP_APEI,
+ ACPI_OSC_CAP_APEI));
+ aml_append(sb_scope, aml_error_device());
+ aml_append(dsdt, sb_scope);
+
+ scope = aml_scope("_GPE");
+ method = aml_method("_E07", 0, AML_NOTSERIALIZED);
+ aml_append(method, aml_notify(aml_name("\\_SB." ACPI_APEI_ERROR_DEVICE),
+ aml_int(0x80)));
+ aml_append(scope, method);
+ aml_append(dsdt, scope);
+ }
+
/* copy AML table into ACPI tables blob and patch header there */
g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
acpi_table_end(linker, &table);
@@ -2043,6 +2109,10 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
return true;
}
+static const AcpiNotificationSourceId hest_ghes_notify[] = {
+ {ACPI_HEST_SRC_ID_QMP, ACPI_GHES_NOTIFY_SCI},
+};
+
static
void acpi_build(AcpiBuildTables *tables, MachineState *machine)
{
@@ -2199,6 +2269,16 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
cxl_build_cedt(table_offsets, tables_blob, tables->linker,
x86ms->oem_id, x86ms->oem_table_id, &pcms->cxl_devices_state);
}
+ if (pcms->ras) {
+ AcpiGhesState *ags =
+ acpi_device_get_ghes_state(ACPI_DEVICE_IF(x86ms->acpi_dev));
+
+ acpi_add_table(table_offsets, tables_blob);
+ acpi_build_hest(ags, tables_blob, tables->hardware_errors,
+ tables->linker, hest_ghes_notify,
+ ARRAY_SIZE(hest_ghes_notify),
+ x86ms->oem_id, x86ms->oem_table_id);
+ }
acpi_add_table(table_offsets, tables_blob);
build_waet(tables_blob, tables->linker, x86ms->oem_id, x86ms->oem_table_id);
@@ -2315,6 +2395,21 @@ void acpi_setup(void)
static FwCfgTPMConfig tpm_config;
#endif
+ if (pcms->ras) {
+ AcpiGhesState *ags = NULL;
+
+ if (x86ms->acpi_dev) {
+ ags = acpi_device_get_ghes_state(ACPI_DEVICE_IF(x86ms->acpi_dev));
+ }
+ if (!x86ms->fw_cfg || !pcms->acpi_build_enabled ||
+ !x86_machine_is_acpi_enabled(x86ms) || !ags) {
+ error_report("ras=on requires ACPI table generation and a PC "
+ "ACPI controller");
+ exit(EXIT_FAILURE);
+ }
+ ags->use_hest_addr = true;
+ }
+
if (!x86ms->fw_cfg) {
ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
return;
@@ -2361,6 +2456,13 @@ void acpi_setup(void)
}
#endif
+ if (pcms->ras) {
+ AcpiGhesState *ags =
+ acpi_device_get_ghes_state(ACPI_DEVICE_IF(x86ms->acpi_dev));
+
+ acpi_ghes_add_fw_cfg(ags, x86ms->fw_cfg, tables.hardware_errors);
+ }
+
vmgenid_dev = find_vmgenid_dev();
if (vmgenid_dev) {
vmgenid_add_fw_cfg(VMGENID(vmgenid_dev), x86ms->fw_cfg,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 4737eb471c14..28af7f507dab 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -51,6 +51,7 @@
#include "qemu/error-report.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/pc-hotplug.h"
+#include "hw/acpi/ghes.h"
#include "acpi-build.h"
#include "hw/mem/nvdimm.h"
#include "hw/cxl/cxl_host.h"
@@ -1608,6 +1609,34 @@ static void pc_machine_set_max_fw_size(Object *obj, Visitor *v,
pcms->max_fw_size = value;
}
+static bool pc_machine_get_ras(Object *obj, Error **errp)
+{
+ PCMachineState *pcms = PC_MACHINE(obj);
+
+ return pcms->ras;
+}
+
+static void pc_machine_set_ras(Object *obj, bool value, Error **errp)
+{
+ PCMachineState *pcms = PC_MACHINE(obj);
+
+ pcms->ras = value;
+}
+
+static void pc_sci_error(Notifier *n, void *opaque)
+{
+ PCMachineState *pcms = container_of(n, PCMachineState, ghes_sci_notifier);
+ X86MachineState *x86ms = X86_MACHINE(pcms);
+ uint16_t *source_id = opaque;
+
+ /* Currently, only QMP injection is supported */
+ if (!pcms->ras || !x86ms->acpi_dev ||
+ *source_id != ACPI_HEST_SRC_ID_QMP) {
+ return;
+ }
+
+ acpi_send_event(DEVICE(x86ms->acpi_dev), ACPI_GENERIC_ERROR);
+}
static void pc_machine_initfn(Object *obj)
{
@@ -1642,12 +1671,18 @@ static void pc_machine_initfn(Object *obj)
if (pcmc->pci_enabled) {
cxl_machine_init(obj, &pcms->cxl_devices_state);
}
+
+ pcms->ghes_sci_notifier.notify = pc_sci_error;
+ notifier_list_add(&acpi_generic_error_notifiers,
+ &pcms->ghes_sci_notifier);
}
static void pc_machine_finalize(Object *obj)
{
PCMachineState *pcms = PC_MACHINE(obj);
+ notifier_remove(&pcms->ghes_sci_notifier);
+
if (pcms->pcspk && !qdev_is_realized(DEVICE(pcms->pcspk))) {
object_unref(OBJECT(pcms->pcspk));
}
@@ -1773,6 +1808,12 @@ static void pc_machine_class_init(ObjectClass *oc, const void *data)
object_class_property_set_description(oc, PC_MACHINE_SMBIOS_EP,
"SMBIOS Entry Point type [32, 64]");
+ object_class_property_add_bool(oc, "ras", pc_machine_get_ras,
+ pc_machine_set_ras);
+ object_class_property_set_description(oc, "ras",
+ "Set on/off to enable/disable reporting host memory errors "
+ "to a KVM guest using ACPI and guest external abort exceptions");
+
object_class_property_add_bool(oc, "fd-bootchk",
pc_machine_get_fd_bootchk,
pc_machine_set_fd_bootchk);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 844ae835784f..533612194f32 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -30,6 +30,9 @@ typedef struct PCMachineState {
/* State for other subsystems/APIs: */
Notifier machine_done;
+ /* Triggered when a new SCI GHES error raises */
+ Notifier ghes_sci_notifier;
+
/* Pointers to devices and objects: */
PCIBus *pcibus;
I2CBus *smbus;
@@ -57,6 +60,8 @@ typedef struct PCMachineState {
bool i8042_enabled;
bool default_bus_bypass_iommu;
bool fd_bootchk;
+ bool ras;
+
uint64_t max_fw_size;
/* ACPI Memory hotplug IO base address */
--
2.56.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 4/8] hw/i386: add GHES support at ICH9 and PIIX4 PM
2026-11-08 8:45 [PATCH v2 0/8] Add ghes support for x86 via SCI notification Mauro Carvalho Chehab
` (2 preceding siblings ...)
2026-11-08 8:45 ` [PATCH v2 3/8] hw/i186: add support for HEST table with SCI Mauro Carvalho Chehab
@ 2026-11-08 8:45 ` Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 5/8] tests/acpi: virt: add x86 DSDT and HEST tables Mauro Carvalho Chehab
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Mauro Carvalho Chehab @ 2026-11-08 8:45 UTC (permalink / raw)
To: Michael S Tsirkin
Cc: Jonathan Cameron, Shiju Jose, qemu-devel, Igor Mammedov,
Mauro Carvalho Chehab, linux-edac, qemu-arm,
Philippe Mathieu-Daudé, Ani Sinha, Aurelien Jarno
Enabling GHES support on x86 means that both PIIX4 and ICH9
PM controllers need to expose ghes state.
Implement that, as suggested by Igor.
Suggested-by: Igor Mammedov <imammedo@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20250530164134.6c666b2e@imammedo.users.ipa.redhat.com/
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
hw/acpi/ich9.c | 19 +++++++++++++++++++
hw/acpi/piix4.c | 25 +++++++++++++++++++++++++
hw/isa/lpc_ich9.c | 6 ++++++
include/hw/acpi/ich9.h | 2 ++
include/hw/acpi/piix4.h | 2 ++
5 files changed, 54 insertions(+)
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 91a22a8e9480..39303e681406 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -223,6 +223,24 @@ static const VMStateDescription vmstate_pcihp_state = {
}
};
+static bool ich9_hest_needed(void *opaque)
+{
+ ICH9LPCPMRegs *pm = opaque;
+
+ return pm->ghes_state.hest_addr_le != 0;
+}
+
+static const VMStateDescription vmstate_ich9_hest = {
+ .name = "ich9_pm/hest",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = ich9_hest_needed,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT64(ghes_state.hest_addr_le, ICH9LPCPMRegs),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
const VMStateDescription vmstate_ich9_pm = {
.name = "ich9_pm",
.version_id = 1,
@@ -245,6 +263,7 @@ const VMStateDescription vmstate_ich9_pm = {
&vmstate_tco_io_state,
&vmstate_cpuhp_state,
&vmstate_pcihp_state,
+ &vmstate_ich9_hest,
NULL
}
};
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index a7d5356340be..854a1008deff 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -224,6 +224,24 @@ static bool vmstate_test_migrate_acpi_index(void *opaque, int version_id)
!s->not_migrate_acpi_index;
}
+static bool piix4_hest_needed(void *opaque)
+{
+ PIIX4PMState *s = opaque;
+
+ return s->ghes_state.hest_addr_le != 0;
+}
+
+static const VMStateDescription vmstate_piix4_hest = {
+ .name = "piix4_pm/hest",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = piix4_hest_needed,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT64(ghes_state.hest_addr_le, PIIX4PMState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
/* qemu-kvm 1.2 uses version 3 but advertised as 2
* To support incoming qemu-kvm 1.2 migration, change version_id
* and minimum_version_id to 2 below (which breaks migration from
@@ -259,6 +277,7 @@ static const VMStateDescription vmstate_acpi = {
.subsections = (const VMStateDescription * const []) {
&vmstate_memhp_state,
&vmstate_cpuhp_state,
+ &vmstate_piix4_hest,
NULL
}
};
@@ -561,6 +580,11 @@ static void piix4_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
acpi_cpu_ospm_status(&s->cpuhp_state, list);
}
+static AcpiGhesState *piix4_get_ghes_state(AcpiDeviceIf *adev)
+{
+ return &PIIX4_PM(adev)->ghes_state;
+}
+
static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
{
PIIX4PMState *s = PIIX4_PM(adev);
@@ -617,6 +641,7 @@ static void piix4_pm_class_init(ObjectClass *klass, const void *data)
hc->is_hotpluggable_bus = piix4_is_hotpluggable_bus;
adevc->ospm_status = piix4_ospm_status;
adevc->send_event = piix4_send_gpe;
+ adevc->get_ghes_state = piix4_get_ghes_state;
object_class_property_add_uint16_ptr(klass, ACPI_PCIHP_IO_BASE_PROP,
offsetof(PIIX4PMState,
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index b55b5136a385..f321c2d6e95f 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -833,6 +833,11 @@ static const Property ich9_lpc_properties[] = {
pm.periodic_timer_enabled, true),
};
+static AcpiGhesState *ich9_get_ghes_state(AcpiDeviceIf *adev)
+{
+ return &ICH9_LPC_DEVICE(adev)->pm.ghes_state;
+}
+
static void ich9_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
{
ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
@@ -900,6 +905,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, const void *data)
hc->is_hotpluggable_bus = ich9_pm_is_hotpluggable_bus;
adevc->ospm_status = ich9_pm_ospm_status;
adevc->send_event = ich9_send_gpe;
+ adevc->get_ghes_state = ich9_get_ghes_state;
amldevc->build_dev_aml = build_ich9_isa_aml;
object_class_property_add_uint8_ptr(klass, ACPI_PM_PROP_SCI_INT,
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 6956b2b9c9a2..67db16d93523 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -27,6 +27,7 @@
#include "hw/acpi/memory_hotplug.h"
#include "hw/acpi/acpi_dev_interface.h"
#include "hw/acpi/ich9_tco.h"
+#include "hw/acpi/ghes.h"
#include "hw/acpi/cpu.h"
#define ACPI_PCIHP_ADDR_ICH9 0x0cc0
@@ -38,6 +39,7 @@ typedef struct ICH9LPCPMRegs {
* PM1a_CNT_BLK = 2 in FADT so it is defined as uint16_t.
*/
ACPIREGS acpi_regs;
+ AcpiGhesState ghes_state;
MemoryRegion io;
MemoryRegion io_gpe;
diff --git a/include/hw/acpi/piix4.h b/include/hw/acpi/piix4.h
index 863382a814ad..8732574e9c03 100644
--- a/include/hw/acpi/piix4.h
+++ b/include/hw/acpi/piix4.h
@@ -29,6 +29,7 @@
#include "hw/i2c/pm_smbus.h"
#include "hw/isa/apm.h"
#include "hw/acpi/cpu.h"
+#include "hw/acpi/ghes.h"
#define TYPE_PIIX4_PM "PIIX4_PM"
OBJECT_DECLARE_SIMPLE_TYPE(PIIX4PMState, PIIX4_PM)
@@ -43,6 +44,7 @@ struct PIIX4PMState {
MemoryRegion io_gpe;
ACPIREGS ar;
+ AcpiGhesState ghes_state;
APMState apm;
--
2.56.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 5/8] tests/acpi: virt: add x86 DSDT and HEST tables
2026-11-08 8:45 [PATCH v2 0/8] Add ghes support for x86 via SCI notification Mauro Carvalho Chehab
` (3 preceding siblings ...)
2026-11-08 8:45 ` [PATCH v2 4/8] hw/i386: add GHES support at ICH9 and PIIX4 PM Mauro Carvalho Chehab
@ 2026-11-08 8:45 ` Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 6/8] docs: acpi_hest_ghes: document notification mechanisms Mauro Carvalho Chehab
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Mauro Carvalho Chehab @ 2026-11-08 8:45 UTC (permalink / raw)
To: Michael S Tsirkin
Cc: Jonathan Cameron, Shiju Jose, qemu-devel, Igor Mammedov,
Mauro Carvalho Chehab, linux-edac, qemu-arm, Ani Sinha
The following DSDT changes affect both:
-"tests/data/acpi/x86/pc/DSDT.ras",
-"tests/data/acpi/x86/q35/DSDT.ras",
--- /tmp/DSDT_old.dsl
+++ /tmp/DSDT.dsl
@@
+ Method (_OSC, 4, Serialized) // _OSC: Operating System Capabilities
+ {
+ If ((SizeOf (Arg3) < 0x08))
+ {
+ Return (Buffer (0x08) { 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 })
+ }
+
+ CreateDWordField (Arg3, Zero, CDW1)
+ CreateDWordField (Arg3, 0x04, CDW2)
+ If ((Arg0 != ToUUID ("0811b06e-4a27-44f9-8d60-3cbbc22e7b48")))
+ {
+ CDW1 |= 0x04
+ Return (Arg3)
+ }
+ If ((Arg1 != One))
+ {
+ CDW1 |= 0x08
+ Return (Arg3)
+ }
+ If ((Arg2 != 0x02))
+ {
+ CDW1 |= 0x02
+ Return (Arg3)
+ }
+
+ Local0 = (CDW2 & 0xFFFFFFFF)
+ If ((CDW2 != Local0))
+ {
+ CDW1 |= 0x10
+ }
+ CDW2 = Local0
+ Return (Arg3)
+ }
+
+ Device (GEDD)
+ {
+ Name (_HID, "PNP0C33" /* Error Device */)
+ Name (_UID, Zero)
+ }
+ }
+
+ Scope (_GPE)
+ {
+ Method (_E07, 0, NotSerialized)
+ {
+ Notify (\_SB.GEDD, 0x80) // Status Change
+ }
+ }
The x86 HEST table now contains a GHESv2 source:
--- /tmp/HEST_old.dsl
+++ /tmp/HEST.dsl
@@
+[024h 0036 4] Error Source Count : 00000001
+
+[028h 0040 2] Subtable Type : 000A [Generic Hardware Error Source V2]
+[02Ah 0042 2] Source Id : 0001
+[02Ch 0044 2] Related Source Id : FFFF
+[02Eh 0046 1] Reserved : 00
+[02Fh 0047 1] Enabled : 01
+[030h 0048 4] Records To Preallocate : 00000001
+[034h 0052 4] Max Sections Per Record : 00000001
+[038h 0056 4] Max Raw Data Length : 00000400
+
+[03Ch 0060 12] Error Status Address : [Generic Address Structure]
+[03Ch 0060 1] Space ID : 00 [SystemMemory]
+[03Dh 0061 1] Bit Width : 40
+[03Fh 0063 1] Encoded Access Width : 04 [QWord Access:64]
+
+[048h 0072 28] Notify : [Hardware Error Notification Structure]
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
tests/data/acpi/x86/pc/DSDT.ras | Bin 48 -> 8818 bytes
tests/data/acpi/x86/pc/HEST.ras | Bin 48 -> 132 bytes
tests/data/acpi/x86/q35/DSDT.ras | Bin 48 -> 8647 bytes
tests/data/acpi/x86/q35/HEST.ras | Bin 48 -> 132 bytes
tests/qtest/bios-tables-test-allowed-diff.h | 4 ----
5 files changed, 4 deletions(-)
diff --git a/tests/data/acpi/x86/pc/DSDT.ras b/tests/data/acpi/x86/pc/DSDT.ras
index 73fa78ef14ea5ec208df4358dd64d3b7f4b25880..ee99b20fd6e9d95ad2690e20573cd8bd5ca0d90f 100644
GIT binary patch
literal 8818
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
F{{Ue1iFp73
literal 48
zcmdPbQV0%kiO}`QOis-!PSy2HNzE(COv_9yvQlsl@X<BWGtkX1(#=UMNi9;)(&qvI
DZyye+
diff --git a/tests/data/acpi/x86/pc/HEST.ras b/tests/data/acpi/x86/pc/HEST.ras
index 73fa78ef14ea5ec208df4358dd64d3b7f4b25880..6dfeb1d3704523f5ee7c81f442c4f51bbd10282d 100644
GIT binary patch
literal 132
zcmeZp4Gw8xU|?XhbMklg2v%^42yj+VP*7lGU|;~TK{N<+F)%Xx|Ife(<1?@@FfceU
guzdLapPhk$fq_{DMB)HYwLhS0|NVymkXaxA05bg-0RR91
literal 48
zcmdPbQV0%kiO}`QOis-!PSy2HNzE(COv_9yvQlsl@X<BWGtkX1(#=UMNi9;)(&qvI
DZyye+
diff --git a/tests/data/acpi/x86/q35/DSDT.ras b/tests/data/acpi/x86/q35/DSDT.ras
index 73fa78ef14ea5ec208df4358dd64d3b7f4b25880..f7626f56ceda77aeb0ca04e8913d76bf57177a45 100644
GIT binary patch
literal 8647
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
E4{5|Mc>n+a
literal 48
zcmdPbQV0%kiO}`QOis-!PSy2HNzE(COv_9yvQlsl@X<BWGtkX1(#=UMNi9;)(&qvI
DZyye+
diff --git a/tests/data/acpi/x86/q35/HEST.ras b/tests/data/acpi/x86/q35/HEST.ras
index 73fa78ef14ea5ec208df4358dd64d3b7f4b25880..6dfeb1d3704523f5ee7c81f442c4f51bbd10282d 100644
GIT binary patch
literal 132
zcmeZp4Gw8xU|?XhbMklg2v%^42yj+VP*7lGU|;~TK{N<+F)%Xx|Ife(<1?@@FfceU
guzdLapPhk$fq_{DMB)HYwLhS0|NVymkXaxA05bg-0RR91
literal 48
zcmdPbQV0%kiO}`QOis-!PSy2HNzE(COv_9yvQlsl@X<BWGtkX1(#=UMNi9;)(&qvI
DZyye+
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index b3761468accc..dfb8523c8bf4 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,5 +1 @@
/* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/x86/pc/DSDT.ras",
-"tests/data/acpi/x86/pc/HEST.ras",
-"tests/data/acpi/x86/q35/DSDT.ras",
-"tests/data/acpi/x86/q35/HEST.ras",
--
2.56.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 6/8] docs: acpi_hest_ghes: document notification mechanisms
2026-11-08 8:45 [PATCH v2 0/8] Add ghes support for x86 via SCI notification Mauro Carvalho Chehab
` (4 preceding siblings ...)
2026-11-08 8:45 ` [PATCH v2 5/8] tests/acpi: virt: add x86 DSDT and HEST tables Mauro Carvalho Chehab
@ 2026-11-08 8:45 ` Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 7/8] tests: add GHES tests on arm64 virt machine Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 8/8] tests: add GHES tests on x86 piix4 and q35 machines Mauro Carvalho Chehab
7 siblings, 0 replies; 9+ messages in thread
From: Mauro Carvalho Chehab @ 2026-11-08 8:45 UTC (permalink / raw)
To: Michael S Tsirkin, Pierrick Bouvier
Cc: Jonathan Cameron, Shiju Jose, qemu-devel, Igor Mammedov,
Mauro Carvalho Chehab, linux-edac, qemu-arm
Currently, the HEST spec mixes generic support with arch dependent
notification mechanisms.
Move the arm-specific notifications to a separate chapter and add
a new one describing x86 mechanisms.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
docs/specs/acpi_hest_ghes.rst | 44 ++++++++++++++++++++++++++++-------
1 file changed, 35 insertions(+), 9 deletions(-)
diff --git a/docs/specs/acpi_hest_ghes.rst b/docs/specs/acpi_hest_ghes.rst
index aaf7b1ad11a5..1a32550ef3a1 100644
--- a/docs/specs/acpi_hest_ghes.rst
+++ b/docs/specs/acpi_hest_ghes.rst
@@ -7,6 +7,7 @@ APEI tables generating and CPER record
This work is licensed under the terms of the GNU GPL, version 2 or later.
See the COPYING file in the top-level directory.
+
Design Details
--------------
@@ -105,14 +106,39 @@ Design Details
firmware will write back the start address of either "etc/hardware_errors"
or HEST table at the corresponding fw_cfg file.
-(9) When QEMU gets a SIGBUS from the kernel, QEMU writes CPER into corresponding
- "Error Status Data Block", guest memory, and then injects platform specific
- interrupt (in case of arm/virt machine it's Synchronous External Abort) as a
- notification which is necessary for notifying the guest.
+.. note::
-(10) This notification (in virtual hardware) will be handled by the guest
- kernel, on receiving notification, guest APEI driver could read the CPER error
- and take appropriate action.
+ GHES support requires ACPI and ``-machine ras=on``.
-(11) kvm_arch_on_sigbus_vcpu() reports RAS errors via a SEA notifications,
- when a SIGBUS event is triggered.
+Notifications on ARM64
+----------------------
+
+The ARM64 ``virt`` machine supports two GHESv2 notification sources:
+
+* source 0: Synchronous External Abort (SEA);
+* source 1: GPIO notification delivered through a Generic Event Device (GED).
+
+Source 0 reports hardware-memory RAS events on the ``virt`` machine:
+
+* When QEMU receives a ``SIGBUS`` from the kernel, it writes the CPER into the
+ corresponding ``Error Status Data Block`` in guest memory and reports the
+ event through a Synchronous External Abort (SEA). The guest kernel handle
+ the SEA,
+
+* The guest APEI driver can read and process the CPER record.
+
+* ``kvm_arch_on_sigbus_vcpu()`` reports these RAS events through SEA.
+
+When source 1 is available, QEMU supports GHES error injection through the QMP
+interface.
+
+
+Notifications on x86
+--------------------
+
+The ``pc`` and ``q35`` machines support one GHESv2 source:
+
+* source 1: System Control Interrupt (SCI).
+
+When source 1 is available, QEMU supports GHES error injection through
+the QMP interface.
--
2.56.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 7/8] tests: add GHES tests on arm64 virt machine
2026-11-08 8:45 [PATCH v2 0/8] Add ghes support for x86 via SCI notification Mauro Carvalho Chehab
` (5 preceding siblings ...)
2026-11-08 8:45 ` [PATCH v2 6/8] docs: acpi_hest_ghes: document notification mechanisms Mauro Carvalho Chehab
@ 2026-11-08 8:45 ` Mauro Carvalho Chehab
2026-11-08 8:45 ` [PATCH v2 8/8] tests: add GHES tests on x86 piix4 and q35 machines Mauro Carvalho Chehab
7 siblings, 0 replies; 9+ messages in thread
From: Mauro Carvalho Chehab @ 2026-11-08 8:45 UTC (permalink / raw)
To: Michael S Tsirkin
Cc: Jonathan Cameron, Shiju Jose, qemu-devel, Igor Mammedov,
Mauro Carvalho Chehab, linux-edac, qemu-arm, Ani Sinha
QEMU has support for HEST table since version 9.2. Yet, it currently
lacks a test to check if the HEST table is working.
Add tests for arm64 error inject mechanism, implemented at
QEMU version 10.2.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
tests/qtest/bios-tables-test.c | 80 ++++++++++++++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index f6dfa4131b89..884af30d77ff 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -68,6 +68,7 @@
#define MACHINE_PC "pc"
#define MACHINE_Q35 "q35"
+#define VIRT_ACPI_GED_BASE 0x09080000
#define ACPI_REBUILD_EXPECTED_AML "TEST_ACPI_REBUILD_AML"
@@ -913,6 +914,84 @@ static uint8_t base_required_struct_types[] = {
0, 1, 3, 4, 16, 17, 19, 32, 127
};
+static void test_acpi_ghes_v2_injection(test_data *data)
+{
+ const uint8_t cper[20] = { [0] = 2, [16] = 2 }; /* corrected GESB */
+ g_autofree char *payload = g_base64_encode(cper, sizeof(cper));
+ uint64_t status_addr, ack_addr;
+ uint8_t actual[sizeof(cper)];
+ QTestState *qts = data->qts;
+ const uint8_t *ghes = NULL;
+ AcpiSdtTable *hest = NULL;
+ AcpiSdtTable *table;
+
+ for (unsigned i = 0; i < data->tables->len; i++) {
+ table = &g_array_index(data->tables, AcpiSdtTable, i);
+
+ if (compare_signature(table, "HEST")) {
+ hest = table;
+ break;
+ }
+ }
+ g_assert_nonnull(hest);
+
+ for (unsigned i = 0; i < ldl_le_p(hest->aml + 36); i++) {
+ const uint8_t *entry = hest->aml + 40 + i * 92;
+
+ g_assert_cmpuint(lduw_le_p(entry), ==, 10); /* GHESv2 */
+ if (lduw_le_p(entry + 2) == 1) { /* QMP source */
+ ghes = entry;
+ break;
+ }
+ }
+ g_assert_nonnull(ghes);
+ g_assert_cmpuint(ghes[32], ==, 7); /* GPIO notification */
+ status_addr = qtest_readq(qts, ldq_le_p(ghes + 24));
+ ack_addr = ldq_le_p(ghes + 68);
+ g_assert_cmphex(status_addr, !=, 0);
+ g_assert_cmphex(ack_addr, !=, 0);
+ g_assert_cmpuint(qtest_readq(qts, ack_addr), ==, 1);
+
+ for (unsigned i = 0; i < 3; i++) {
+ qtest_qmp_assert_success(qts,
+ "{'execute': 'inject-ghes-v2-error', 'arguments': {'cper': %s}}",
+ payload);
+ g_assert_cmpuint(qtest_readq(qts, ack_addr), ==, 0);
+ qtest_memread(qts, status_addr, actual, sizeof(actual));
+ g_assert_cmpmem(actual, sizeof(actual), cper, sizeof(cper));
+
+ /* GED converts the GPIO notification into an Error event. */
+ g_assert_cmphex(qtest_readl(qts, VIRT_ACPI_GED_BASE), ==, 0x20);
+ g_assert_cmphex(qtest_readl(qts, VIRT_ACPI_GED_BASE), ==, 0);
+
+ /* A second injection must wait for OSPM's acknowledgement. */
+ qobject_unref(qtest_qmp_assert_failure_ref(qts,
+ "{'execute': 'inject-ghes-v2-error', 'arguments': {'cper': %s}}",
+ payload));
+ qtest_writeq(qts, ack_addr, 1);
+ }
+}
+
+static void test_acpi_aarch64_virt_ras(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .arch = "aarch64",
+ .tcg_only = true,
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd",
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 128ULL * MiB,
+ };
+
+ test_vm_prepare("-cpu cortex-a57 -machine ras=on", &data);
+ process_acpi_tables_noexit(&data);
+ test_acpi_ghes_v2_injection(&data);
+ qtest_quit(data.qts);
+ free_test_data(&data);
+}
+
static void test_acpi_piix4_tcg(void)
{
test_data data = {};
@@ -2930,6 +3009,7 @@ int main(int argc, char *argv[])
} else if (strcmp(arch, "aarch64") == 0) {
if (has_tcg && qtest_has_device("virtio-blk-pci")) {
qtest_add_func("acpi/virt", test_acpi_aarch64_virt_tcg);
+ qtest_add_func("acpi/virt/ras", test_acpi_aarch64_virt_ras);
qtest_add_func("acpi/virt/acpihmatvirt",
test_acpi_aarch64_virt_tcg_acpi_hmat);
qtest_add_func("acpi/virt/topology",
--
2.56.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 8/8] tests: add GHES tests on x86 piix4 and q35 machines
2026-11-08 8:45 [PATCH v2 0/8] Add ghes support for x86 via SCI notification Mauro Carvalho Chehab
` (6 preceding siblings ...)
2026-11-08 8:45 ` [PATCH v2 7/8] tests: add GHES tests on arm64 virt machine Mauro Carvalho Chehab
@ 2026-11-08 8:45 ` Mauro Carvalho Chehab
7 siblings, 0 replies; 9+ messages in thread
From: Mauro Carvalho Chehab @ 2026-11-08 8:45 UTC (permalink / raw)
To: Michael S Tsirkin
Cc: Jonathan Cameron, Shiju Jose, qemu-devel, Igor Mammedov,
Mauro Carvalho Chehab, linux-edac, qemu-arm, Ani Sinha
Add support to test GHES on x86 using the SCI mechanism.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
tests/qtest/bios-tables-test.c | 67 ++++++++++++++++++++++++++++++----
1 file changed, 59 insertions(+), 8 deletions(-)
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 884af30d77ff..4e9eac290472 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -914,7 +914,8 @@ static uint8_t base_required_struct_types[] = {
0, 1, 3, 4, 16, 17, 19, 32, 127
};
-static void test_acpi_ghes_v2_injection(test_data *data)
+static void test_acpi_ghes_v2_injection(test_data *data, bool sci,
+ int notif_type)
{
const uint8_t cper[20] = { [0] = 2, [16] = 2 }; /* corrected GESB */
g_autofree char *payload = g_base64_encode(cper, sizeof(cper));
@@ -923,14 +924,18 @@ static void test_acpi_ghes_v2_injection(test_data *data)
QTestState *qts = data->qts;
const uint8_t *ghes = NULL;
AcpiSdtTable *hest = NULL;
+ AcpiSdtTable *fadt = NULL;
AcpiSdtTable *table;
+ uint8_t gpe_len;
+ uint32_t gpe0;
for (unsigned i = 0; i < data->tables->len; i++) {
table = &g_array_index(data->tables, AcpiSdtTable, i);
if (compare_signature(table, "HEST")) {
hest = table;
- break;
+ } else if (compare_signature(table, "FACP")) {
+ fadt = table;
}
}
g_assert_nonnull(hest);
@@ -945,29 +950,51 @@ static void test_acpi_ghes_v2_injection(test_data *data)
}
}
g_assert_nonnull(ghes);
- g_assert_cmpuint(ghes[32], ==, 7); /* GPIO notification */
+ g_assert_cmpuint(ghes[32], ==, notif_type);
status_addr = qtest_readq(qts, ldq_le_p(ghes + 24));
ack_addr = ldq_le_p(ghes + 68);
g_assert_cmphex(status_addr, !=, 0);
g_assert_cmphex(ack_addr, !=, 0);
g_assert_cmpuint(qtest_readq(qts, ack_addr), ==, 1);
+ if (sci) {
+ g_assert_nonnull(fadt);
+ gpe0 = ldl_le_p(fadt->aml + 80);
+ gpe_len = fadt->aml[92];
+ qtest_irq_intercept_in(qts, "ioapic");
+ qtest_outb(qts, gpe0, 0xff);
+ qtest_outb(qts, gpe0 + gpe_len / 2, 0x80);
+ }
+
for (unsigned i = 0; i < 3; i++) {
+ if (sci) {
+ g_assert_false(qtest_get_irq(qts, 9));
+ }
qtest_qmp_assert_success(qts,
"{'execute': 'inject-ghes-v2-error', 'arguments': {'cper': %s}}",
payload);
g_assert_cmpuint(qtest_readq(qts, ack_addr), ==, 0);
qtest_memread(qts, status_addr, actual, sizeof(actual));
g_assert_cmpmem(actual, sizeof(actual), cper, sizeof(cper));
-
- /* GED converts the GPIO notification into an Error event. */
- g_assert_cmphex(qtest_readl(qts, VIRT_ACPI_GED_BASE), ==, 0x20);
- g_assert_cmphex(qtest_readl(qts, VIRT_ACPI_GED_BASE), ==, 0);
+ if (sci) {
+ g_assert_cmphex(qtest_inb(qts, gpe0) & 0x80, ==, 0x80);
+ g_assert_true(qtest_get_irq(qts, 9));
+ } else {
+ /* GED converts the GPIO notification into an Error event. */
+ g_assert_cmphex(qtest_readl(qts, VIRT_ACPI_GED_BASE), ==, 0x20);
+ g_assert_cmphex(qtest_readl(qts, VIRT_ACPI_GED_BASE), ==, 0);
+ }
/* A second injection must wait for OSPM's acknowledgement. */
qobject_unref(qtest_qmp_assert_failure_ref(qts,
"{'execute': 'inject-ghes-v2-error', 'arguments': {'cper': %s}}",
payload));
+
+ if (sci) {
+ /* Emulate OSPM clearing the edge GPE. */
+ qtest_outb(qts, gpe0, 0x80);
+ g_assert_false(qtest_get_irq(qts, 9));
+ }
qtest_writeq(qts, ack_addr, 1);
}
}
@@ -987,7 +1014,28 @@ static void test_acpi_aarch64_virt_ras(void)
test_vm_prepare("-cpu cortex-a57 -machine ras=on", &data);
process_acpi_tables_noexit(&data);
- test_acpi_ghes_v2_injection(&data);
+ test_acpi_ghes_v2_injection(&data, false, 7);
+ qtest_quit(data.qts);
+ free_test_data(&data);
+}
+
+static void test_acpi_x86_ras(const void *opaque)
+{
+ test_data data = {
+ .machine = opaque,
+ .arch = "x86",
+ .variant = ".ras",
+ };
+
+ test_vm_prepare("-machine ras=on", &data);
+ process_acpi_tables_noexit(&data);
+ test_acpi_ghes_v2_injection(&data, true, 3);
+ free_test_data(&data);
+
+ /* Check if fw restored error buffer, then write back HEST on reset. */
+ qtest_system_reset(data.qts);
+ process_acpi_tables_noexit(&data);
+ test_acpi_ghes_v2_injection(&data, true, 3);
qtest_quit(data.qts);
free_test_data(&data);
}
@@ -2883,6 +2931,8 @@ int main(int argc, char *argv[])
}
if (qtest_has_machine(MACHINE_PC)) {
qtest_add_func("acpi/piix4", test_acpi_piix4_tcg);
+ qtest_add_data_func("acpi/piix4/ras", MACHINE_PC,
+ test_acpi_x86_ras);
qtest_add_func("acpi/piix4/oem-fields", test_acpi_piix4_oem_fields);
qtest_add_func("acpi/piix4/bridge", test_acpi_piix4_tcg_bridge);
qtest_add_func("acpi/piix4/pci-hotplug/no_root_hotplug",
@@ -2921,6 +2971,7 @@ int main(int argc, char *argv[])
}
if (qtest_has_machine(MACHINE_Q35)) {
qtest_add_func("acpi/q35", test_acpi_q35_tcg);
+ qtest_add_data_func("acpi/q35/ras", MACHINE_Q35, test_acpi_x86_ras);
qtest_add_func("acpi/q35/oem-fields", test_acpi_q35_oem_fields);
if (tpm_model_is_available("-machine q35", "tpm-tis")) {
qtest_add_func("acpi/q35/tpm2-tis", test_acpi_q35_tcg_tpm2_tis);
--
2.56.0
^ permalink raw reply related [flat|nested] 9+ messages in thread