* [PATCH 0/6] ppc/spapr: Add RTAS error injection support for VFIO EEH
@ 2026-05-12 7:11 Narayana Murty N
2026-05-12 7:11 ` [PATCH 1/6] ppc/spapr: Add VFIO EEH error injection backend Narayana Murty N
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: Narayana Murty N @ 2026-05-12 7:11 UTC (permalink / raw)
To: qemu-ppc, qemu-devel
Cc: npiggin, harshpb, mahesh, ganeshgr, sbhat, vaibhav,
anushree.mathur
This patch series implements comprehensive RTAS-based error injection
support for VFIO EEH (Enhanced Error Handling) on PowerPC sPAPR platforms.
The implementation enables guest-initiated PCI error injection for improved
testing and diagnostics of EEH recovery mechanisms.
Background
----------
EEH is a critical feature on PowerPC platforms that provides error detection,
isolation, and recovery for PCI devices. Testing EEH recovery paths requires
the ability to inject various types of errors into the system. While physical
hardware supports error injection through firmware interfaces, QEMU's VFIO
implementation previously lacked this capability.
This series bridges that gap by implementing the IBM RTAS error injection
interface, allowing guests to inject PCI errors through the same firmware
calls used on physical hardware. This enables comprehensive testing of device
drivers' EEH recovery code paths in virtualized environments.
Implementation Overview
-----------------------
The patch series introduces three new RTAS calls:
- ibm,open-errinjct: Opens an error injection session
- ibm,errinjct: Injects a specific error type
- ibm,close-errinjct: Closes the error injection session
The implementation supports multiple error types including:
- IOA bus errors (32-bit and 64-bit addressing)
- Memory/IO/Config space load/store errors
- DMA read/write errors
- Cache and TLB corruption scenarios
- Special recovery events
Tesed on pseries and powernv hosts on kvm guest with errinjct tool.
Patch Organization
------------------
Patch 1: Adds the VFIO backend for error injection
Patch 2: Implements the ibm,errinjct RTAS call handler
Patch 3: Adds session management (open/close) RTAS calls
Patch 4: Advertises capabilities via device tree properties
Patch 5: Refactors file naming for clarity
Patch 6: Updates MAINTAINERS file
Narayana Murty N (6):
ppc/spapr: Add VFIO EEH error injection backend
ppc/spapr: Add ibm,errinjct RTAS call handler
ppc/spapr: Add support for 'ibm,open-errinjct' and 'ibm,
close-errinjct'
ppc/spapr: Advertise RTAS error injection call support via FDT
property
hw/ppc: Rename spapr_pci_vfio.c to spapr_pci_vfio_eeh.c
MAINTAINERS: Add entry for sPAPR PCI VFIO EEH support
MAINTAINERS | 6 +
hw/ppc/Kconfig | 2 +-
hw/ppc/meson.build | 2 +-
hw/ppc/spapr.c | 106 ++++++++
hw/ppc/spapr_pci.c | 232 ++++++++++++++++++
...{spapr_pci_vfio.c => spapr_pci_vfio_eeh.c} | 65 ++++-
include/hw/pci-host/spapr.h | 8 +
include/hw/ppc/spapr.h | 57 ++++-
8 files changed, 464 insertions(+), 14 deletions(-)
rename hw/ppc/{spapr_pci_vfio.c => spapr_pci_vfio_eeh.c} (85%)
--
2.54.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/6] ppc/spapr: Add VFIO EEH error injection backend
2026-05-12 7:11 [PATCH 0/6] ppc/spapr: Add RTAS error injection support for VFIO EEH Narayana Murty N
@ 2026-05-12 7:11 ` Narayana Murty N
2026-05-12 7:11 ` [PATCH 2/6] ppc/spapr: Add ibm,errinjct RTAS call handler Narayana Murty N
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Narayana Murty N @ 2026-05-12 7:11 UTC (permalink / raw)
To: qemu-ppc, qemu-devel
Cc: npiggin, harshpb, mahesh, ganeshgr, sbhat, vaibhav,
anushree.mathur
Introduce 'spapr_phb_vfio_errinjct()' to inject PCI PHB error events via
the VFIO passthrough backend. This function translates RTAS error injection
parameters into VFIO EEH injection commands suitable for hardware emulation.
The patch adds:
- A minimal 'enum rtas_err_type' for error types used in VFIO path
- EEH function code macros ('EEH_ERR_FUNC_...')
- Backend stub and integration into 'spapr_pci_vfio.c'
- Necessary header declarations for interfacing
This forms the foundational layer for PCI error injection testing using VFIO
passthrough devices on pseries guests.
Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
---
hw/ppc/spapr_pci_vfio.c | 53 +++++++++++++++++++++++++++++++++++++
include/hw/pci-host/spapr.h | 7 +++++
include/hw/ppc/spapr.h | 44 ++++++++++++++++++++++++++++++
3 files changed, 104 insertions(+)
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index a748a0bf4c..ed0b22a84a 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -317,6 +317,55 @@ int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb)
return RTAS_OUT_SUCCESS;
}
+int spapr_phb_vfio_errinjct(SpaprPhbState *sphb,
+ uint32_t func, uint64_t addr,
+ uint64_t mask, uint32_t type)
+{
+ VFIOLegacyContainer *container = vfio_eeh_as_container(&sphb->iommu_as);
+ struct vfio_eeh_pe_op op = {
+ .op = VFIO_EEH_PE_INJECT_ERR,
+ .argsz = sizeof(op),
+ };
+
+ /* Set error type, address, and mask */
+ op.err.type = type;
+ op.err.addr = addr;
+ op.err.mask = mask;
+
+ /* Validate and set function code */
+ switch (func) {
+ case EEH_ERR_FUNC_LD_MEM_ADDR:
+ case EEH_ERR_FUNC_LD_MEM_DATA:
+ case EEH_ERR_FUNC_LD_IO_ADDR:
+ case EEH_ERR_FUNC_LD_IO_DATA:
+ case EEH_ERR_FUNC_LD_CFG_ADDR:
+ case EEH_ERR_FUNC_LD_CFG_DATA:
+ case EEH_ERR_FUNC_ST_MEM_ADDR:
+ case EEH_ERR_FUNC_ST_MEM_DATA:
+ case EEH_ERR_FUNC_ST_IO_ADDR:
+ case EEH_ERR_FUNC_ST_IO_DATA:
+ case EEH_ERR_FUNC_ST_CFG_ADDR:
+ case EEH_ERR_FUNC_ST_CFG_DATA:
+ case EEH_ERR_FUNC_DMA_RD_ADDR:
+ case EEH_ERR_FUNC_DMA_RD_DATA:
+ case EEH_ERR_FUNC_DMA_RD_MASTER:
+ case EEH_ERR_FUNC_DMA_RD_TARGET:
+ case EEH_ERR_FUNC_DMA_WR_ADDR:
+ case EEH_ERR_FUNC_DMA_WR_DATA:
+ case EEH_ERR_FUNC_DMA_WR_MASTER:
+ op.err.func = func;
+ break;
+ default:
+ return RTAS_OUT_PARAM_ERROR;
+ }
+
+ /* Perform the ioctl to inject the error */
+ if (ioctl(container->fd, VFIO_EEH_PE_OP, &op) < 0) {
+ return RTAS_OUT_HW_ERROR;
+ }
+
+ return RTAS_OUT_SUCCESS;
+}
#else
bool spapr_phb_eeh_available(SpaprPhbState *sphb)
@@ -349,4 +398,8 @@ int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb)
return RTAS_OUT_NOT_SUPPORTED;
}
+int spapr_phb_vfio_errinjct(SpaprPhbState *sphb, int option)
+{
+ return RTAS_OUT_NOT_SUPPORTED;
+}
#endif /* CONFIG_VFIO_PCI */
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 0db87f1281..417d1f6c31 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -125,6 +125,8 @@ int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, int *state);
int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option);
int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb);
void spapr_phb_vfio_reset(DeviceState *qdev);
+int spapr_phb_vfio_errinjct(SpaprPhbState *sphb, uint32_t func,
+ uint64_t addr, uint64_t mask, uint32_t type);
#else
static inline bool spapr_phb_eeh_available(SpaprPhbState *sphb)
{
@@ -151,6 +153,11 @@ static inline int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb)
static inline void spapr_phb_vfio_reset(DeviceState *qdev)
{
}
+static inline int spapr_phb_vfio_errinjct(SpaprPhbState *sphb, uint32_t func,
+ uint64_t addr, uint64_t mask, uint32_t type)
+{
+ return RTAS_OUT_HW_ERROR;
+}
#endif
void spapr_phb_dma_reset(SpaprPhbState *sphb);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 9acda15d4f..fadb7cf7d9 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -682,6 +682,50 @@ void push_sregs_to_kvm_pr(SpaprMachineState *spapr);
#define RTAS_EEH_PE_UNAVAIL_INFO 1000
#define RTAS_EEH_PE_RECOVER_INFO 0
+/* EEH error types and functions */
+#define EEH_ERR_FUNC_MIN 0
+#define EEH_ERR_FUNC_LD_MEM_ADDR 0 /* Memory load */
+#define EEH_ERR_FUNC_LD_MEM_DATA 1
+#define EEH_ERR_FUNC_LD_IO_ADDR 2 /* IO load */
+#define EEH_ERR_FUNC_LD_IO_DATA 3
+#define EEH_ERR_FUNC_LD_CFG_ADDR 4 /* Config load */
+#define EEH_ERR_FUNC_LD_CFG_DATA 5
+#define EEH_ERR_FUNC_ST_MEM_ADDR 6 /* Memory store */
+#define EEH_ERR_FUNC_ST_MEM_DATA 7
+#define EEH_ERR_FUNC_ST_IO_ADDR 8 /* IO store */
+#define EEH_ERR_FUNC_ST_IO_DATA 9
+#define EEH_ERR_FUNC_ST_CFG_ADDR 10 /* Config store */
+#define EEH_ERR_FUNC_ST_CFG_DATA 11
+#define EEH_ERR_FUNC_DMA_RD_ADDR 12 /* DMA read */
+#define EEH_ERR_FUNC_DMA_RD_DATA 13
+#define EEH_ERR_FUNC_DMA_RD_MASTER 14
+#define EEH_ERR_FUNC_DMA_RD_TARGET 15
+#define EEH_ERR_FUNC_DMA_WR_ADDR 16 /* DMA write */
+#define EEH_ERR_FUNC_DMA_WR_DATA 17
+#define EEH_ERR_FUNC_DMA_WR_MASTER 18
+#define EEH_ERR_FUNC_DMA_WR_TARGET 19
+#define EEH_ERR_FUNC_MAX EEH_ERR_FUNC_DMA_WR_TARGET
+
+/* RTAS PCI Error Injection Token Types */
+enum rtas_err_type {
+ RTAS_ERR_TYPE_FATAL = 0x1,
+ RTAS_ERR_TYPE_RECOVERED_RANDOM_EVENT = 0x2,
+ RTAS_ERR_TYPE_RECOVERED_SPECIAL_EVENT = 0x3,
+ RTAS_ERR_TYPE_CORRUPTED_PAGE = 0x4,
+ RTAS_ERR_TYPE_CORRUPTED_SLB = 0x5,
+ RTAS_ERR_TYPE_TRANSLATOR_FAILURE = 0x6,
+ RTAS_ERR_TYPE_IOA_BUS_ERROR = 0x7,
+ RTAS_ERR_TYPE_PLATFORM_SPECIFIC = 0x8,
+ RTAS_ERR_TYPE_CORRUPTED_DCACHE_START = 0x9,
+ RTAS_ERR_TYPE_CORRUPTED_DCACHE_END = 0xA,
+ RTAS_ERR_TYPE_CORRUPTED_ICACHE_START = 0xB,
+ RTAS_ERR_TYPE_CORRUPTED_ICACHE_END = 0xC,
+ RTAS_ERR_TYPE_CORRUPTED_TLB_START = 0xD,
+ RTAS_ERR_TYPE_CORRUPTED_TLB_END = 0xE,
+ RTAS_ERR_TYPE_IOA_BUS_ERROR_64 = 0xF,
+ RTAS_ERR_TYPE_UPSTREAM_IO_ERROR = 0x10
+};
+
/* ibm,set-slot-reset */
#define RTAS_SLOT_RESET_DEACTIVATE 0
#define RTAS_SLOT_RESET_HOT 1
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/6] ppc/spapr: Add ibm,errinjct RTAS call handler
2026-05-12 7:11 [PATCH 0/6] ppc/spapr: Add RTAS error injection support for VFIO EEH Narayana Murty N
2026-05-12 7:11 ` [PATCH 1/6] ppc/spapr: Add VFIO EEH error injection backend Narayana Murty N
@ 2026-05-12 7:11 ` Narayana Murty N
2026-05-12 7:11 ` [PATCH 3/6] ppc/spapr: Add support for 'ibm, open-errinjct' and 'ibm, close-errinjct' Narayana Murty N
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Narayana Murty N @ 2026-05-12 7:11 UTC (permalink / raw)
To: qemu-ppc, qemu-devel
Cc: npiggin, harshpb, mahesh, ganeshgr, sbhat, vaibhav,
anushree.mathur
Implements the 'ibm,errinjct' RTAS call for PHB-level PCI error injection
via firmware. This handler decodes the RTAS parameter buffer, validates
arguments, and delegates the injection to the backend.
The patch includes:
- 'rtas_ibm_errinjct()' handler implementation
- Registration of 'RTAS_IBM_ERRINJCT' token
- RTAS error codes for result reporting
- Helper macros used exclusively in RTAS code path
Enables guest-initiated error injection for improved test coverage and
diagnostics in EEH emulation flows.
Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
---
hw/ppc/spapr_pci.c | 153 +++++++++++++++++++++++++++++++++++++++++
include/hw/ppc/spapr.h | 6 +-
2 files changed, 158 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index c1d4b7806e..82de04186e 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -704,6 +704,156 @@ param_error_exit:
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}
+static int parse_and_verify_recovered_special_event(target_ulong param_buf,
+ uint64_t *addr) {
+ uint32_t mode = rtas_ld(param_buf, 0);
+ if (mode != EEH_ERR_EVENT_MODE_MIN && mode != EEH_ERR_EVENT_MODE_MAX) {
+ return RTAS_OUT_PARAM_ERROR;
+ }
+ *addr = ((uint64_t)mode) << 32;
+ qemu_log("RTAS: recovered-special-event: mode=%u\n", mode);
+ return RTAS_OUT_SUCCESS;
+}
+
+static int parse_and_verify_corrupted_page(target_ulong param_buf,
+ uint64_t *addr) {
+ *addr = ((uint64_t)rtas_ld(param_buf, 0) << 32) | rtas_ld(param_buf, 1);
+ qemu_log("RTAS: corrupted-page: addr=0x%lx\n", *addr);
+ return (*addr) ? RTAS_OUT_SUCCESS : RTAS_OUT_PARAM_ERROR;
+}
+
+static int parse_and_verify_ioa_bus_error(target_ulong param_buf,
+ bool is_64bit,
+ uint64_t *addr, uint64_t *mask,
+ uint64_t *buid, uint32_t *func)
+{
+ if (is_64bit) {
+ *addr = ((uint64_t)rtas_ld(param_buf, 0) << 32) | rtas_ld(param_buf, 1);
+ *mask = ((uint64_t)rtas_ld(param_buf, 2) << 32) | rtas_ld(param_buf, 3);
+ *buid = ((uint64_t)rtas_ld(param_buf, 5) << 32) | rtas_ld(param_buf, 6);
+ *func = rtas_ld(param_buf, 7);
+ } else {
+ *addr = rtas_ld(param_buf, 0);
+ *mask = rtas_ld(param_buf, 1);
+ *buid = ((uint64_t)rtas_ld(param_buf, 3) << 32) | rtas_ld(param_buf, 4);
+ *func = rtas_ld(param_buf, 5);
+ }
+
+ return RTAS_OUT_SUCCESS;
+}
+
+static int parse_and_verify_corrupted_dcache(target_ulong param_buf,
+ uint64_t *addr)
+{
+ uint32_t action = rtas_ld(param_buf, 0);
+ uint32_t nature = rtas_ld(param_buf, 1);
+ *addr = ((uint64_t)action << 32) | nature;
+
+ return (action <= 2 && nature <= 2) ? RTAS_OUT_SUCCESS
+ : RTAS_OUT_PARAM_ERROR;
+}
+
+static int parse_and_verify_corrupted_icache(target_ulong param_buf,
+ uint64_t *addr)
+{
+ uint32_t action = rtas_ld(param_buf, 0);
+ uint32_t nature = rtas_ld(param_buf, 1);
+ *addr = ((uint64_t)action << 32) | nature;
+
+ return (action <= 3 && nature <= 2) ? RTAS_OUT_SUCCESS
+ : RTAS_OUT_PARAM_ERROR;
+}
+
+static int parse_and_verify_corrupted_tlb(target_ulong param_buf,
+ uint64_t *addr)
+{
+ uint32_t nature = rtas_ld(param_buf, 0);
+ *addr = ((uint64_t)nature << 32);
+
+ return (nature <= 2) ? RTAS_OUT_SUCCESS : RTAS_OUT_PARAM_ERROR;
+}
+
+static void rtas_ibm_errinjct(PowerPCCPU *cpu, SpaprMachineState *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ SpaprPhbState *sphb;
+ target_ulong param_buf;
+ uint64_t addr = 0, mask = 0, buid = 0;
+ uint32_t func = 0;
+ uint32_t type, o_token;
+ int ret = -1;
+
+ if ((nargs != 3) || (nret != 1)) {
+ goto param_error_exit;
+ }
+
+ type = rtas_ld(args, 0);
+ o_token = rtas_ld(args, 1);
+ param_buf = rtas_ld(args, 2);
+
+ if (o_token != spapr->errinjct_token) {
+ goto param_error_exit;
+ }
+
+ sphb = QLIST_FIRST(&spapr->phbs);
+ if (!sphb) {
+ goto param_error_exit;
+ }
+
+ switch (type) {
+ case RTAS_ERR_TYPE_IOA_BUS_ERROR:
+ ret = parse_and_verify_ioa_bus_error(param_buf, false, &addr,
+ &mask, &buid, &func);
+ break;
+ case RTAS_ERR_TYPE_IOA_BUS_ERROR_64:
+ ret = parse_and_verify_ioa_bus_error(param_buf, true, &addr,
+ &mask, &buid, &func);
+ break;
+ case RTAS_ERR_TYPE_CORRUPTED_PAGE:
+ ret = parse_and_verify_corrupted_page(param_buf, &addr);
+ break;
+ case RTAS_ERR_TYPE_RECOVERED_SPECIAL_EVENT:
+ ret = parse_and_verify_recovered_special_event(param_buf, &addr);
+ break;
+ case RTAS_ERR_TYPE_CORRUPTED_DCACHE_START:
+ case RTAS_ERR_TYPE_CORRUPTED_DCACHE_END:
+ ret = parse_and_verify_corrupted_dcache(param_buf, &addr);
+ mask = 0;
+ break;
+ case RTAS_ERR_TYPE_CORRUPTED_ICACHE_START:
+ case RTAS_ERR_TYPE_CORRUPTED_ICACHE_END:
+ ret = parse_and_verify_corrupted_icache(param_buf, &addr);
+ mask = 0;
+ break;
+ case RTAS_ERR_TYPE_CORRUPTED_TLB_START:
+ case RTAS_ERR_TYPE_CORRUPTED_TLB_END:
+ ret = parse_and_verify_corrupted_tlb(param_buf, &addr);
+ mask = 0;
+ break;
+ default:
+ ret = RTAS_OUT_PARAM_ERROR;
+ break;
+ }
+
+ if (ret != RTAS_OUT_SUCCESS) {
+ goto param_error_exit;
+ }
+
+ ret = spapr_phb_vfio_errinjct(sphb, func, addr, mask, type);
+ if (ret < 0) {
+ rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
+ return;
+ }
+
+ rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+ return;
+
+param_error_exit:
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+}
+
static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
{
/*
@@ -2380,6 +2530,9 @@ void spapr_pci_rtas_init(void)
spapr_rtas_register(RTAS_IBM_SLOT_ERROR_DETAIL,
"ibm,slot-error-detail",
rtas_ibm_slot_error_detail);
+ spapr_rtas_register(RTAS_IBM_ERRINJCT,
+ "ibm,errinjct",
+ rtas_ibm_errinjct);
}
static void spapr_pci_register_types(void)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index fadb7cf7d9..512dd038ec 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -706,6 +706,9 @@ void push_sregs_to_kvm_pr(SpaprMachineState *spapr);
#define EEH_ERR_FUNC_DMA_WR_TARGET 19
#define EEH_ERR_FUNC_MAX EEH_ERR_FUNC_DMA_WR_TARGET
+#define EEH_ERR_EVENT_MODE_MIN 1
+#define EEH_ERR_EVENT_MODE_MAX 2
+
/* RTAS PCI Error Injection Token Types */
enum rtas_err_type {
RTAS_ERR_TYPE_FATAL = 0x1,
@@ -808,8 +811,9 @@ enum rtas_err_type {
#define RTAS_IBM_NMI_REGISTER (RTAS_TOKEN_BASE + 0x2B)
#define RTAS_IBM_NMI_INTERLOCK (RTAS_TOKEN_BASE + 0x2C)
#define RTAS_CONFIGURE_KERNEL_DUMP (RTAS_TOKEN_BASE + 0x2D)
+#define RTAS_IBM_ERRINJCT (RTAS_TOKEN_BASE + 0x2E)
-#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2E)
+#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2F)
/* RTAS ibm,get-system-parameter token values */
#define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/6] ppc/spapr: Add support for 'ibm, open-errinjct' and 'ibm, close-errinjct'
2026-05-12 7:11 [PATCH 0/6] ppc/spapr: Add RTAS error injection support for VFIO EEH Narayana Murty N
2026-05-12 7:11 ` [PATCH 1/6] ppc/spapr: Add VFIO EEH error injection backend Narayana Murty N
2026-05-12 7:11 ` [PATCH 2/6] ppc/spapr: Add ibm,errinjct RTAS call handler Narayana Murty N
@ 2026-05-12 7:11 ` Narayana Murty N
2026-05-12 7:11 ` [PATCH 4/6] ppc/spapr: Advertise RTAS error injection call support via FDT property Narayana Murty N
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Narayana Murty N @ 2026-05-12 7:11 UTC (permalink / raw)
To: qemu-ppc, qemu-devel
Cc: npiggin, harshpb, mahesh, ganeshgr, sbhat, vaibhav,
anushree.mathur
Add support for the 'ibm,open-errinjct' and 'ibm,close-errinjct' RTAS
calls. These handlers manage exclusive access to error injection
facilities through a simple session-based mechanism.
Updates include:
- Implementation of rtas_ibm_open_errinjct() and rtas_ibm_close_errinjct()
- Tracking field 'spapr->errinjct_token' in SpaprMachineState
- New token definitions for the above RTAS calls
- Return codes for already open or invalid close conditions
This ensures that only one guest process can actively perform error
injection at a time, improving reliability and preventing conflicts.
Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
---
hw/ppc/spapr_pci.c | 65 ++++++++++++++++++++++++++++++++++++++++++
include/hw/ppc/spapr.h | 9 +++++-
2 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 82de04186e..b00f71d92a 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -854,6 +854,65 @@ param_error_exit:
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}
+static void rtas_ibm_open_errinjct(PowerPCCPU *cpu,
+ SpaprMachineState *spapr,
+ uint32_t token,
+ uint32_t nargs,
+ target_ulong args,
+ uint32_t nret,
+ target_ulong rets)
+{
+ /* Validate argument count */
+ if ((nargs != 0) || (nret != 2)) {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
+ if (spapr->errinjct_token) {
+ /* Already open: return token=0 and code=ALREADY_OPEN */
+ rtas_st(rets, 0, 0);
+ rtas_st(rets, 1, RTAS_OUT_ALREADY_OPEN);
+ return;
+ }
+
+ spapr->errinjct_token = 1;
+
+ /*
+ * Unlike most RTAS calls, ibm,open-errinjct returns
+ * the session token in the first output parameter
+ * and the status in the second.
+ */
+ rtas_st(rets, 0, spapr->errinjct_token);
+ rtas_st(rets, 1, RTAS_OUT_SUCCESS);
+}
+
+static void rtas_ibm_close_errinjct(PowerPCCPU *cpu,
+ SpaprMachineState *spapr,
+ uint32_t token,
+ uint32_t nargs,
+ target_ulong args,
+ uint32_t nret,
+ target_ulong rets)
+{
+ uint32_t o_token;
+
+ if ((nargs != 1) || (nret != 1)) {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
+ o_token = rtas_ld(args, 0);
+
+ if (o_token != spapr->errinjct_token) {
+ rtas_st(rets, 0, RTAS_OUT_NOT_OPEN);
+ return;
+ }
+
+ spapr->errinjct_token = 0;
+
+ rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
{
/*
@@ -2533,6 +2592,12 @@ void spapr_pci_rtas_init(void)
spapr_rtas_register(RTAS_IBM_ERRINJCT,
"ibm,errinjct",
rtas_ibm_errinjct);
+ spapr_rtas_register(RTAS_IBM_OPEN_ERRINJCT,
+ "ibm,open-errinjct",
+ rtas_ibm_open_errinjct);
+ spapr_rtas_register(RTAS_IBM_CLOSE_ERRINJCT,
+ "ibm,close-errinjct",
+ rtas_ibm_close_errinjct);
}
static void spapr_pci_register_types(void)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 512dd038ec..6c87f94e1d 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -274,6 +274,8 @@ struct SpaprMachineState {
bool fadump_registered;
bool fadump_dump_active;
FadumpMemStruct registered_fdm;
+
+ uint32_t errinjct_token;
};
#define H_SUCCESS 0
@@ -746,6 +748,9 @@ enum rtas_err_type {
#define RTAS_OUT_PARAM_ERROR -3
#define RTAS_OUT_NOT_SUPPORTED -3
#define RTAS_OUT_NO_SUCH_INDICATOR -3
+#define RTAS_OUT_ALREADY_OPEN -4
+#define RTAS_OUT_NOT_OPEN -5
+#define RTAS_OUT_CLOSE_ERROR -6
#define RTAS_OUT_DUMP_ALREADY_REGISTERED -9
#define RTAS_OUT_DUMP_ACTIVE -10
#define RTAS_OUT_NOT_AUTHORIZED -9002
@@ -812,8 +817,10 @@ enum rtas_err_type {
#define RTAS_IBM_NMI_INTERLOCK (RTAS_TOKEN_BASE + 0x2C)
#define RTAS_CONFIGURE_KERNEL_DUMP (RTAS_TOKEN_BASE + 0x2D)
#define RTAS_IBM_ERRINJCT (RTAS_TOKEN_BASE + 0x2E)
+#define RTAS_IBM_OPEN_ERRINJCT (RTAS_TOKEN_BASE + 0x2F)
+#define RTAS_IBM_CLOSE_ERRINJCT (RTAS_TOKEN_BASE + 0x30)
-#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2F)
+#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x31)
/* RTAS ibm,get-system-parameter token values */
#define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/6] ppc/spapr: Advertise RTAS error injection call support via FDT property
2026-05-12 7:11 [PATCH 0/6] ppc/spapr: Add RTAS error injection support for VFIO EEH Narayana Murty N
` (2 preceding siblings ...)
2026-05-12 7:11 ` [PATCH 3/6] ppc/spapr: Add support for 'ibm, open-errinjct' and 'ibm, close-errinjct' Narayana Murty N
@ 2026-05-12 7:11 ` Narayana Murty N
2026-05-12 7:11 ` [PATCH 5/6] hw/ppc: Rename spapr_pci_vfio.c to spapr_pci_vfio_eeh.c Narayana Murty N
2026-05-12 7:11 ` [PATCH 6/6] MAINTAINERS: Add entry for sPAPR PCI VFIO EEH support Narayana Murty N
5 siblings, 0 replies; 10+ messages in thread
From: Narayana Murty N @ 2026-05-12 7:11 UTC (permalink / raw)
To: qemu-ppc, qemu-devel
Cc: npiggin, harshpb, mahesh, ganeshgr, sbhat, vaibhav,
anushree.mathur
Advertise RTAS error injection call support to guests through a new
"ibm,errinjct-tokens" property under the RTAS node in the device tree.
This patch introduces:
- spapr_get_errinject_tokens(), which retrieves or constructs a blob
of supported error injection tokens from the host or fallback data.
- Integration of "ibm,errinjct-tokens" into the RTAS FDT node.
- Addition of "ibm,open-errinjct" and "ibm,close-errinjct" properties
to advertise open/close handlers for error injection sessions.
The ibm,errinjct-tokens property allows guests to programmatically
discover supported RTAS error injection facilities, enabling safe and
dynamic usage. The helper routine allocates memory for the token blob,
which the caller must free once it has been added to the FDT.
If the device-tree file (/proc/device-tree/rtas/ibm,errinjct-tokens)
is not available, a static fallback blob is generated internally.
Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
---
hw/ppc/spapr.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 106 insertions(+)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d40af312fa..bf6c838e0a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -115,6 +115,8 @@
#define PHANDLE_INTC 0x00001111
+#define ERR_BLOB_MAX 512
+
/* These two functions implement the VCPU id numbering: one to compute them
* all and one to identify thread 0 of a VCORE. Any change to the first one
* is likely to have an impact on the second one, so let's keep them close.
@@ -968,10 +970,104 @@ static void spapr_dt_rtas_fadump(SpaprMachineState *spapr, void *fdt, int rtas)
}
}
+/*
+ * spapr_get_errinject_tokens:
+ * ---------------------------
+ * Retrieve or construct a binary blob representing supported RTAS error
+ * injection tokens. If the host device-tree path
+ * "/proc/device-tree/rtas/ibm,errinjct-tokens" exists, it is read directly.
+ * Otherwise, a static fallback list of tokens is generated.
+ *
+ * The caller receives a dynamically allocated buffer in @out_buf and
+ * its size in @out_size, both of which must be freed by the caller
+ * once used.
+ *
+ * Returns:
+ * 0 (EXIT_SUCCESS) - on success
+ * -EIO, -ENOMEM - on failure
+ */
+static int spapr_get_errinject_tokens(char **out_buf, size_t *out_size)
+{
+ char *path = NULL, *buf = NULL;
+ gsize len = 0;
+ uint8_t errinjct_blob[ERR_BLOB_MAX];
+
+ static const struct {
+ const char *name;
+ enum rtas_err_type token;
+ } errinjct_tokens[] = {
+ { "recovered-special-event", RTAS_ERR_TYPE_RECOVERED_SPECIAL_EVENT },
+ { "corrupted-page", RTAS_ERR_TYPE_CORRUPTED_PAGE },
+ { "ioa-bus-error", RTAS_ERR_TYPE_IOA_BUS_ERROR },
+ { "corrupted-dcache-start", RTAS_ERR_TYPE_CORRUPTED_DCACHE_START },
+ { "corrupted-dcache-end", RTAS_ERR_TYPE_CORRUPTED_DCACHE_END },
+ { "corrupted-icache-start", RTAS_ERR_TYPE_CORRUPTED_ICACHE_START },
+ { "corrupted-icache-end", RTAS_ERR_TYPE_CORRUPTED_ICACHE_END },
+ { "corrupted-tlb-start", RTAS_ERR_TYPE_CORRUPTED_TLB_START },
+ { "corrupted-tlb-end", RTAS_ERR_TYPE_CORRUPTED_TLB_END },
+ { "ioa-bus-error-64", RTAS_ERR_TYPE_IOA_BUS_ERROR_64 },
+ };
+
+ path = g_strdup("/proc/device-tree/rtas/ibm,errinjct-tokens");
+
+ if (g_file_test(path, G_FILE_TEST_EXISTS)) {
+ qemu_log("RTAS: Found %s\n", path);
+
+ if (!g_file_get_contents(path, &buf, &len, NULL)) {
+ error_report("RTAS: Failed to read %s", path);
+ g_free(path);
+ return -EIO;
+ }
+
+ qemu_log("RTAS: Read %zu bytes from device-tree\n", len);
+ *out_buf = buf;
+ *out_size = len;
+ g_free(path);
+ return EXIT_SUCCESS;
+ }
+
+ qemu_log("RTAS: %s not found, building fallback blob\n", path);
+ g_free(path);
+ len = 0;
+
+ for (int i = 0; i < G_N_ELEMENTS(errinjct_tokens); i++) {
+ const char *name = errinjct_tokens[i].name;
+ size_t str_len = strlen(name) + 1;
+
+ if (len + str_len + sizeof(uint32_t) > sizeof(errinjct_blob)) {
+ error_report("RTAS: Too many tokens for static buffer");
+ return -ENOMEM;
+ }
+
+ memcpy(&errinjct_blob[len], name, str_len);
+ len += str_len;
+
+ uint32_t be_token = cpu_to_be32(errinjct_tokens[i].token);
+ memcpy(&errinjct_blob[len], &be_token, sizeof(be_token));
+ len += sizeof(be_token);
+ }
+
+ buf = g_malloc(len);
+ if (!buf) {
+ error_report("RTAS: Failed to allocate %zu bytes for blob", len);
+ return -ENOMEM;
+ }
+
+ memcpy(buf, errinjct_blob, len);
+ *out_buf = buf;
+ *out_size = len;
+
+ qemu_log("RTAS: Fallback blob built (%zu bytes)\n", len);
+ return EXIT_SUCCESS;
+}
+
+
static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
{
MachineState *ms = MACHINE(spapr);
int rtas;
+ size_t size_tokens = 0;
+ g_autofree char *errinject_tokens;
GString *hypertas = g_string_sized_new(256);
GString *qemu_hypertas = g_string_sized_new(256);
uint64_t max_device_addr = 0;
@@ -1080,6 +1176,16 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
*/
_FDT(fdt_setprop(fdt, rtas, "ibm,extended-os-term", NULL, 0));
+ if (!spapr_get_errinject_tokens(&errinject_tokens, &size_tokens)) {
+ _FDT(fdt_setprop(fdt, rtas, "ibm,errinjct-tokens",
+ errinject_tokens, size_tokens));
+
+ _FDT(fdt_setprop_string(fdt, rtas, "ibm,open-errinjct",
+ "ibm,open-errinjct"));
+ _FDT(fdt_setprop_string(fdt, rtas, "ibm,close-errinjct",
+ "ibm,close-errinjct"));
+ }
+
_FDT(fdt_setprop(fdt, rtas, "ibm,lrdr-capacity",
lrdr_capacity, sizeof(lrdr_capacity)));
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/6] hw/ppc: Rename spapr_pci_vfio.c to spapr_pci_vfio_eeh.c
2026-05-12 7:11 [PATCH 0/6] ppc/spapr: Add RTAS error injection support for VFIO EEH Narayana Murty N
` (3 preceding siblings ...)
2026-05-12 7:11 ` [PATCH 4/6] ppc/spapr: Advertise RTAS error injection call support via FDT property Narayana Murty N
@ 2026-05-12 7:11 ` Narayana Murty N
2026-05-12 7:54 ` Cédric Le Goater
2026-05-12 7:11 ` [PATCH 6/6] MAINTAINERS: Add entry for sPAPR PCI VFIO EEH support Narayana Murty N
5 siblings, 1 reply; 10+ messages in thread
From: Narayana Murty N @ 2026-05-12 7:11 UTC (permalink / raw)
To: qemu-ppc, qemu-devel
Cc: npiggin, harshpb, mahesh, ganeshgr, sbhat, vaibhav,
anushree.mathur
The file spapr_pci_vfio.c contains exclusively EEH (Enhanced Error
Handling) related functions for VFIO devices on sPAPR platforms.
To better reflect its specific purpose and improve code organization,
this commit:
1. Renames spapr_pci_vfio.c to spapr_pci_vfio_eeh.c
2. Moves spapr_phb_vfio_eeh_reenable() from spapr_pci_vfio_eeh.c to
spapr_pci.c, as it's a general PHB operation not specific to
VFIO EEH error injection/recovery
After this change, spapr_pci_vfio_eeh.c contains only the core VFIO
EEH error handling functions, making the file's purpose more focused
and clear.
This is a refactoring change with no functional impact.
Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
---
hw/ppc/Kconfig | 2 +-
hw/ppc/meson.build | 2 +-
hw/ppc/spapr_pci.c | 14 ++++++++++++++
hw/ppc/{spapr_pci_vfio.c => spapr_pci_vfio_eeh.c} | 12 +-----------
include/hw/pci-host/spapr.h | 1 +
5 files changed, 18 insertions(+), 13 deletions(-)
rename hw/ppc/{spapr_pci_vfio.c => spapr_pci_vfio_eeh.c} (96%)
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 347dcce690..886ce71ef8 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -6,7 +6,7 @@ config PSERIES
imply PCI_DEVICES
imply TEST_DEVICES
imply VIRTIO_VGA
- imply VFIO_PCI if LINUX # needed by spapr_pci_vfio.c
+ imply VFIO_PCI if LINUX # needed by spapr_pci_vfio_eeh.c
select NVDIMM
select DIMM
select PCI
diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 37aa535db2..7cf0226b5e 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -35,7 +35,7 @@ ppc_ss.add(when: ['CONFIG_PSERIES', 'CONFIG_TCG'], if_true: files(
ppc_ss.add(when: 'CONFIG_SPAPR_RNG', if_true: files('spapr_rng.c'))
if host_os == 'linux'
ppc_ss.add(when: 'CONFIG_PSERIES', if_true: files(
- 'spapr_pci_vfio.c',
+ 'spapr_pci_vfio_eeh.c',
))
endif
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index b00f71d92a..fcb7b850c0 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -2215,6 +2215,20 @@ void spapr_phb_dma_reset(SpaprPhbState *sphb)
tcet->def_win = true;
}
+void spapr_phb_vfio_reset(DeviceState *qdev)
+{
+ /*
+ * The PE might be in frozen state. To reenable the EEH
+ * functionality on it will clean the frozen state, which
+ * ensures that the contained PCI devices will work properly
+ * after reboot.
+ */
+ spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
+}
+
+
+
+
static void spapr_phb_reset(DeviceState *qdev)
{
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio_eeh.c
similarity index 96%
rename from hw/ppc/spapr_pci_vfio.c
rename to hw/ppc/spapr_pci_vfio_eeh.c
index ed0b22a84a..c00cf1d24b 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio_eeh.c
@@ -131,21 +131,11 @@ bool spapr_phb_eeh_available(SpaprPhbState *sphb)
return vfio_eeh_as_ok(&sphb->iommu_as);
}
-static void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb)
+void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb)
{
vfio_eeh_as_op(&sphb->iommu_as, VFIO_EEH_PE_ENABLE);
}
-void spapr_phb_vfio_reset(DeviceState *qdev)
-{
- /*
- * The PE might be in frozen state. To reenable the EEH
- * functionality on it will clean the frozen state, which
- * ensures that the contained PCI devices will work properly
- * after reboot.
- */
- spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
-}
static void spapr_eeh_pci_find_device(PCIBus *bus, PCIDevice *pdev,
void *opaque)
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 417d1f6c31..5ca122a5f1 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -125,6 +125,7 @@ int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, int *state);
int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option);
int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb);
void spapr_phb_vfio_reset(DeviceState *qdev);
+void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb);
int spapr_phb_vfio_errinjct(SpaprPhbState *sphb, uint32_t func,
uint64_t addr, uint64_t mask, uint32_t type);
#else
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/6] MAINTAINERS: Add entry for sPAPR PCI VFIO EEH support
2026-05-12 7:11 [PATCH 0/6] ppc/spapr: Add RTAS error injection support for VFIO EEH Narayana Murty N
` (4 preceding siblings ...)
2026-05-12 7:11 ` [PATCH 5/6] hw/ppc: Rename spapr_pci_vfio.c to spapr_pci_vfio_eeh.c Narayana Murty N
@ 2026-05-12 7:11 ` Narayana Murty N
5 siblings, 0 replies; 10+ messages in thread
From: Narayana Murty N @ 2026-05-12 7:11 UTC (permalink / raw)
To: qemu-ppc, qemu-devel
Cc: npiggin, harshpb, mahesh, ganeshgr, sbhat, vaibhav,
anushree.mathur
Add a dedicated MAINTAINERS entry for hw/ppc/spapr_pci_vfio_eeh.c,
which implements Extended Error Handling (EEH) support for VFIO-based
PCI devices on PowerPC sPAPR platforms.
EEH provides error detection, isolation, and recovery mechanisms for
PCI devices, allowing the system to handle and recover from hardware
errors without requiring a full system reboot.
Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
---
MAINTAINERS | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 9d3d645953..03a638cab1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1656,6 +1656,12 @@ F: tests/functional/ppc64/test_pseries.py
F: tests/functional/ppc64/test_hv.py
F: tests/functional/ppc64/test_tuxrun.py
+sPAPR PCI VFIO Extended Error handling (EEH)
+M: Narayana Murty <nnmlinux@linux.ibm.com>
+L: qemu-ppc@nongnu.org
+S: Maintained
+F: hw/ppc/spapr_pci_vfio_eeh.c
+
PowerNV (Non-Virtualized)
M: Nicholas Piggin <npiggin@gmail.com>
R: Aditya Gupta <adityag@linux.ibm.com>
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 5/6] hw/ppc: Rename spapr_pci_vfio.c to spapr_pci_vfio_eeh.c
2026-05-12 7:11 ` [PATCH 5/6] hw/ppc: Rename spapr_pci_vfio.c to spapr_pci_vfio_eeh.c Narayana Murty N
@ 2026-05-12 7:54 ` Cédric Le Goater
2026-05-13 8:24 ` Narayana Murty N
2026-05-13 16:16 ` Pierrick Bouvier
0 siblings, 2 replies; 10+ messages in thread
From: Cédric Le Goater @ 2026-05-12 7:54 UTC (permalink / raw)
To: Narayana Murty N, qemu-ppc, qemu-devel
Cc: npiggin, harshpb, mahesh, ganeshgr, sbhat, vaibhav,
anushree.mathur, Pierrick Bouvier, Philippe Mathieu-Daudé
+ Pierrick, Philippe
On 5/12/26 09:11, Narayana Murty N wrote:
> The file spapr_pci_vfio.c contains exclusively EEH (Enhanced Error
> Handling) related functions for VFIO devices on sPAPR platforms.
> To better reflect its specific purpose and improve code organization,
> this commit:
>
> 1. Renames spapr_pci_vfio.c to spapr_pci_vfio_eeh.c
> 2. Moves spapr_phb_vfio_eeh_reenable() from spapr_pci_vfio_eeh.c to
> spapr_pci.c, as it's a general PHB operation not specific to
> VFIO EEH error injection/recovery
>
> After this change, spapr_pci_vfio_eeh.c contains only the core VFIO
> EEH error handling functions, making the file's purpose more focused
> and clear.
>
> This is a refactoring change with no functional impact.
>
> Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
> ---
> hw/ppc/Kconfig | 2 +-
> hw/ppc/meson.build | 2 +-
> hw/ppc/spapr_pci.c | 14 ++++++++++++++
> hw/ppc/{spapr_pci_vfio.c => spapr_pci_vfio_eeh.c} | 12 +-----------
There is a CONFIG_VFIO_PCI in this file that could be replaced
with stub definitions.
Thanks,
C.
> include/hw/pci-host/spapr.h | 1 +
> 5 files changed, 18 insertions(+), 13 deletions(-)
> rename hw/ppc/{spapr_pci_vfio.c => spapr_pci_vfio_eeh.c} (96%)
>
> diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
> index 347dcce690..886ce71ef8 100644
> --- a/hw/ppc/Kconfig
> +++ b/hw/ppc/Kconfig
> @@ -6,7 +6,7 @@ config PSERIES
> imply PCI_DEVICES
> imply TEST_DEVICES
> imply VIRTIO_VGA
> - imply VFIO_PCI if LINUX # needed by spapr_pci_vfio.c
> + imply VFIO_PCI if LINUX # needed by spapr_pci_vfio_eeh.c
> select NVDIMM
> select DIMM
> select PCI
> diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
> index 37aa535db2..7cf0226b5e 100644
> --- a/hw/ppc/meson.build
> +++ b/hw/ppc/meson.build
> @@ -35,7 +35,7 @@ ppc_ss.add(when: ['CONFIG_PSERIES', 'CONFIG_TCG'], if_true: files(
> ppc_ss.add(when: 'CONFIG_SPAPR_RNG', if_true: files('spapr_rng.c'))
> if host_os == 'linux'
> ppc_ss.add(when: 'CONFIG_PSERIES', if_true: files(
> - 'spapr_pci_vfio.c',
> + 'spapr_pci_vfio_eeh.c',
> ))
> endif
>
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index b00f71d92a..fcb7b850c0 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -2215,6 +2215,20 @@ void spapr_phb_dma_reset(SpaprPhbState *sphb)
> tcet->def_win = true;
> }
>
> +void spapr_phb_vfio_reset(DeviceState *qdev)
> +{
> + /*
> + * The PE might be in frozen state. To reenable the EEH
> + * functionality on it will clean the frozen state, which
> + * ensures that the contained PCI devices will work properly
> + * after reboot.
> + */
> + spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
> +}
> +
> +
> +
> +
> static void spapr_phb_reset(DeviceState *qdev)
> {
> SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
> diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio_eeh.c
> similarity index 96%
> rename from hw/ppc/spapr_pci_vfio.c
> rename to hw/ppc/spapr_pci_vfio_eeh.c
> index ed0b22a84a..c00cf1d24b 100644
> --- a/hw/ppc/spapr_pci_vfio.c
> +++ b/hw/ppc/spapr_pci_vfio_eeh.c
> @@ -131,21 +131,11 @@ bool spapr_phb_eeh_available(SpaprPhbState *sphb)
> return vfio_eeh_as_ok(&sphb->iommu_as);
> }
>
> -static void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb)
> +void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb)
> {
> vfio_eeh_as_op(&sphb->iommu_as, VFIO_EEH_PE_ENABLE);
> }
>
> -void spapr_phb_vfio_reset(DeviceState *qdev)
> -{
> - /*
> - * The PE might be in frozen state. To reenable the EEH
> - * functionality on it will clean the frozen state, which
> - * ensures that the contained PCI devices will work properly
> - * after reboot.
> - */
> - spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
> -}
>
> static void spapr_eeh_pci_find_device(PCIBus *bus, PCIDevice *pdev,
> void *opaque)
> diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
> index 417d1f6c31..5ca122a5f1 100644
> --- a/include/hw/pci-host/spapr.h
> +++ b/include/hw/pci-host/spapr.h
> @@ -125,6 +125,7 @@ int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, int *state);
> int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option);
> int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb);
> void spapr_phb_vfio_reset(DeviceState *qdev);
> +void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb);
> int spapr_phb_vfio_errinjct(SpaprPhbState *sphb, uint32_t func,
> uint64_t addr, uint64_t mask, uint32_t type);
> #else
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 5/6] hw/ppc: Rename spapr_pci_vfio.c to spapr_pci_vfio_eeh.c
2026-05-12 7:54 ` Cédric Le Goater
@ 2026-05-13 8:24 ` Narayana Murty N
2026-05-13 16:16 ` Pierrick Bouvier
1 sibling, 0 replies; 10+ messages in thread
From: Narayana Murty N @ 2026-05-13 8:24 UTC (permalink / raw)
To: Cédric Le Goater, qemu-ppc, qemu-devel
Cc: npiggin, harshpb, mahesh, ganeshgr, sbhat, vaibhav,
anushree.mathur, Pierrick Bouvier, Philippe Mathieu-Daudé
On 12/05/26 1:24 PM, Cédric Le Goater wrote:
> + Pierrick, Philippe
>
> On 5/12/26 09:11, Narayana Murty N wrote:
>> The file spapr_pci_vfio.c contains exclusively EEH (Enhanced Error
>> Handling) related functions for VFIO devices on sPAPR platforms.
>> To better reflect its specific purpose and improve code organization,
>> this commit:
>>
>> 1. Renames spapr_pci_vfio.c to spapr_pci_vfio_eeh.c
>> 2. Moves spapr_phb_vfio_eeh_reenable() from spapr_pci_vfio_eeh.c to
>> spapr_pci.c, as it's a general PHB operation not specific to
>> VFIO EEH error injection/recovery
>>
>> After this change, spapr_pci_vfio_eeh.c contains only the core VFIO
>> EEH error handling functions, making the file's purpose more focused
>> and clear.
>>
>> This is a refactoring change with no functional impact.
>>
>> Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
>> ---
>> hw/ppc/Kconfig | 2 +-
>> hw/ppc/meson.build | 2 +-
>> hw/ppc/spapr_pci.c | 14 ++++++++++++++
>> hw/ppc/{spapr_pci_vfio.c => spapr_pci_vfio_eeh.c} | 12 +-----------
>
>
> There is a CONFIG_VFIO_PCI in this file that could be replaced
> with stub definitions.
>
Hi Cedric,
We are using CONFIG_VFIO_PCI in the new eeh specific file as is for eeh
specific routines and stubs.
Are you suggesting to retain spapr_pci_vfio.c with the remaining single
routine "spapr_phb_vfio_reset"
and its stub?
Regards,
Narayana Murty
> Thanks,
>
> C.
>
>
>> include/hw/pci-host/spapr.h | 1 +
>> 5 files changed, 18 insertions(+), 13 deletions(-)
>> rename hw/ppc/{spapr_pci_vfio.c => spapr_pci_vfio_eeh.c} (96%)
>>
>> diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
>> index 347dcce690..886ce71ef8 100644
>> --- a/hw/ppc/Kconfig
>> +++ b/hw/ppc/Kconfig
>> @@ -6,7 +6,7 @@ config PSERIES
>> imply PCI_DEVICES
>> imply TEST_DEVICES
>> imply VIRTIO_VGA
>> - imply VFIO_PCI if LINUX # needed by spapr_pci_vfio.c
>> + imply VFIO_PCI if LINUX # needed by spapr_pci_vfio_eeh.c
>> select NVDIMM
>> select DIMM
>> select PCI
>> diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
>> index 37aa535db2..7cf0226b5e 100644
>> --- a/hw/ppc/meson.build
>> +++ b/hw/ppc/meson.build
>> @@ -35,7 +35,7 @@ ppc_ss.add(when: ['CONFIG_PSERIES', 'CONFIG_TCG'],
>> if_true: files(
>> ppc_ss.add(when: 'CONFIG_SPAPR_RNG', if_true: files('spapr_rng.c'))
>> if host_os == 'linux'
>> ppc_ss.add(when: 'CONFIG_PSERIES', if_true: files(
>> - 'spapr_pci_vfio.c',
>> + 'spapr_pci_vfio_eeh.c',
>> ))
>> endif
>> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
>> index b00f71d92a..fcb7b850c0 100644
>> --- a/hw/ppc/spapr_pci.c
>> +++ b/hw/ppc/spapr_pci.c
>> @@ -2215,6 +2215,20 @@ void spapr_phb_dma_reset(SpaprPhbState *sphb)
>> tcet->def_win = true;
>> }
>> +void spapr_phb_vfio_reset(DeviceState *qdev)
>> +{
>> + /*
>> + * The PE might be in frozen state. To reenable the EEH
>> + * functionality on it will clean the frozen state, which
>> + * ensures that the contained PCI devices will work properly
>> + * after reboot.
>> + */
>> + spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
>> +}
>> +
>> +
>> +
>> +
>> static void spapr_phb_reset(DeviceState *qdev)
>> {
>> SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
>> diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio_eeh.c
>> similarity index 96%
>> rename from hw/ppc/spapr_pci_vfio.c
>> rename to hw/ppc/spapr_pci_vfio_eeh.c
>> index ed0b22a84a..c00cf1d24b 100644
>> --- a/hw/ppc/spapr_pci_vfio.c
>> +++ b/hw/ppc/spapr_pci_vfio_eeh.c
>> @@ -131,21 +131,11 @@ bool spapr_phb_eeh_available(SpaprPhbState *sphb)
>> return vfio_eeh_as_ok(&sphb->iommu_as);
>> }
>> -static void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb)
>> +void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb)
>> {
>> vfio_eeh_as_op(&sphb->iommu_as, VFIO_EEH_PE_ENABLE);
>> }
>> -void spapr_phb_vfio_reset(DeviceState *qdev)
>> -{
>> - /*
>> - * The PE might be in frozen state. To reenable the EEH
>> - * functionality on it will clean the frozen state, which
>> - * ensures that the contained PCI devices will work properly
>> - * after reboot.
>> - */
>> - spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
>> -}
>> static void spapr_eeh_pci_find_device(PCIBus *bus, PCIDevice *pdev,
>> void *opaque)
>> diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
>> index 417d1f6c31..5ca122a5f1 100644
>> --- a/include/hw/pci-host/spapr.h
>> +++ b/include/hw/pci-host/spapr.h
>> @@ -125,6 +125,7 @@ int spapr_phb_vfio_eeh_get_state(SpaprPhbState
>> *sphb, int *state);
>> int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option);
>> int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb);
>> void spapr_phb_vfio_reset(DeviceState *qdev);
>> +void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb);
>> int spapr_phb_vfio_errinjct(SpaprPhbState *sphb, uint32_t func,
>> uint64_t addr, uint64_t mask, uint32_t
>> type);
>> #else
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 5/6] hw/ppc: Rename spapr_pci_vfio.c to spapr_pci_vfio_eeh.c
2026-05-12 7:54 ` Cédric Le Goater
2026-05-13 8:24 ` Narayana Murty N
@ 2026-05-13 16:16 ` Pierrick Bouvier
1 sibling, 0 replies; 10+ messages in thread
From: Pierrick Bouvier @ 2026-05-13 16:16 UTC (permalink / raw)
To: Cédric Le Goater, Narayana Murty N, qemu-ppc, qemu-devel
Cc: npiggin, harshpb, mahesh, ganeshgr, sbhat, vaibhav,
anushree.mathur, Philippe Mathieu-Daudé
On 5/12/2026 12:54 AM, Cédric Le Goater wrote:
> + Pierrick, Philippe
>
> On 5/12/26 09:11, Narayana Murty N wrote:
>> The file spapr_pci_vfio.c contains exclusively EEH (Enhanced Error
>> Handling) related functions for VFIO devices on sPAPR platforms.
>> To better reflect its specific purpose and improve code organization,
>> this commit:
>>
>> 1. Renames spapr_pci_vfio.c to spapr_pci_vfio_eeh.c
>> 2. Moves spapr_phb_vfio_eeh_reenable() from spapr_pci_vfio_eeh.c to
>> spapr_pci.c, as it's a general PHB operation not specific to
>> VFIO EEH error injection/recovery
>>
>> After this change, spapr_pci_vfio_eeh.c contains only the core VFIO
>> EEH error handling functions, making the file's purpose more focused
>> and clear.
>>
>> This is a refactoring change with no functional impact.
>>
>> Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
>> ---
>> hw/ppc/Kconfig | 2 +-
>> hw/ppc/meson.build | 2 +-
>> hw/ppc/spapr_pci.c | 14 ++++++++++++++
>> hw/ppc/{spapr_pci_vfio.c => spapr_pci_vfio_eeh.c} | 12 +-----------
>
>
> There is a CONFIG_VFIO_PCI in this file that could be replaced
> with stub definitions.
>
Indeed, we didn't touch this yet because it hw/ppc, and it's not in the
list of target where we are focused.
Indeed, the #include CONFIG_DEVICES and #ifdef CONFIG_VFIO_PCI can be
removed, and stubs for spapr_phb_* functions be added in a new
spapr_pci_vfio-stubs.c file, and added to stub_ss.
Regards,
Pierrick
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-05-13 16:17 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-12 7:11 [PATCH 0/6] ppc/spapr: Add RTAS error injection support for VFIO EEH Narayana Murty N
2026-05-12 7:11 ` [PATCH 1/6] ppc/spapr: Add VFIO EEH error injection backend Narayana Murty N
2026-05-12 7:11 ` [PATCH 2/6] ppc/spapr: Add ibm,errinjct RTAS call handler Narayana Murty N
2026-05-12 7:11 ` [PATCH 3/6] ppc/spapr: Add support for 'ibm, open-errinjct' and 'ibm, close-errinjct' Narayana Murty N
2026-05-12 7:11 ` [PATCH 4/6] ppc/spapr: Advertise RTAS error injection call support via FDT property Narayana Murty N
2026-05-12 7:11 ` [PATCH 5/6] hw/ppc: Rename spapr_pci_vfio.c to spapr_pci_vfio_eeh.c Narayana Murty N
2026-05-12 7:54 ` Cédric Le Goater
2026-05-13 8:24 ` Narayana Murty N
2026-05-13 16:16 ` Pierrick Bouvier
2026-05-12 7:11 ` [PATCH 6/6] MAINTAINERS: Add entry for sPAPR PCI VFIO EEH support Narayana Murty N
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox