I've had a version of this code for many years (and occasionally mention it as test platform for kernel patches) and it keeps coming in handy, so time to share the CXL version.
What is this? - ACPI + UEFI specs define a means of notifying the OS of errors that firmware has handled (gathered up data etc, reset the relevant error tracking units etc) in a set of standard formats (UEFI spec appendix N). - ARM virt already supports standard HEST ACPI table description of Synchronous External Abort (SEA) for memory errors. This series builds on this to add a GHESv2 / Generic Error Device / GPIO interrupt path for asynchronous error reporting. - CXL and PCI AER both already have injection commands (via HMP / QMP) These are repurposed to perform FW first injection if the guest OS has not negotiated OS first handling (so before the CXL / PCIE _OSC is called or when it doesn't negotiate control of AER / CXL Memory Errors). - The OS normally negotiates for control of error registers via _OSC. Previously QEMU unconditionally granted control of these registers. This series includes a machine parameter to allow the 'FW' to not let the OS take control and tracks whether the OS has asked for control or not. Note this code relies on the standard handshake - it's not remotely correct if the OS does follow that flow - this can be hardened with some more AML magic. Alternatives: - In theory we could emulate a management controller running appropriate firmware and have that actually handle the errors. It's much easier to instead intercept them before the error reporting messages are sent and result logged in the root ports error registers. As far as the guest is concerned it doesn't matter if these registers are handled via the firmware or never got written in the first place (the guest isn't allowed to touch these registers anyway!) This is sort of same argument for why we build ACPI tables in general in QEMU rather than making that an EDK2 problem. Why? - The kernel CXL code supports both firmware first and native RAS. As only some vendors have adopted a FW first model and hardware availability is limited this code has proven challenging to test. Why an RFC? - Small matter that the ARM CXL support isn't upstream. - I'm assuming adding this support to QEMU will be controversial. - There are some loose ends, TODOs and Fixme's in the code. - Only one type of CXL event currently handled - should provide them all CXL Protocol and AER error reporting is more complete. - I should probably figure out how to do this for x86 as apparently people also want to use that architecture ;) Thanks to Shiju Jose for help testing this. Based on: Random stack of patches on my gitlab.com/jic23/qemu cxl-2024-02-05-draft branch. Specifically: https://gitlab.com/jic23/qemu/-/commit/0fa064b9c8eeef468d8a19e87f39f230b4fa4da9 All comments welcome - particularly anyone who can advise on what the HEST table should look like an x86 machine - too many options! Jonathan Cameron (11): hw/pci: Add pcie_find_dvsec() utility. hw/acpi: Allow GPEX _OSC to keep fw first control of AER and CXL errors. arm/virt: Add fw-first-ras property. acpi/ghes: Support GPIO error source. arm/virt: Wire up GPIO error source for ACPI / GHES acpi: pci/cxl: Stash the OSC control parameters. pci/aer: Support firmware first error injection via GHESv2 hw/pci/aer: Default to error handling on. cxl/ras: Set registers to sensible state for FW first ras cxl/type3: FW first protocol error injection. cxl/type3: Add firmware first error reporting for general media events. include/hw/acpi/cxl.h | 2 +- include/hw/acpi/ghes.h | 14 + include/hw/arm/virt.h | 1 + include/hw/boards.h | 1 + include/hw/cxl/cxl.h | 2 + include/hw/pci-host/gpex.h | 1 + include/hw/pci/pcie.h | 1 + hw/acpi/cxl-stub.c | 2 +- hw/acpi/cxl.c | 50 ++- hw/acpi/ghes-stub.c | 25 ++ hw/acpi/ghes.c | 634 +++++++++++++++++++++++++++++++++- hw/arm/virt-acpi-build.c | 71 +++- hw/arm/virt.c | 32 +- hw/cxl/cxl-component-utils.c | 4 +- hw/i386/acpi-build.c | 2 +- hw/mem/cxl_type3.c | 42 ++- hw/pci-bridge/cxl_root_port.c | 1 - hw/pci-host/gpex-acpi.c | 17 +- hw/pci-host/gpex.c | 1 + hw/pci/pcie.c | 30 ++ hw/pci/pcie_aer.c | 35 +- 21 files changed, 914 insertions(+), 54 deletions(-) -- 2.39.2