Re: [PATCH v2 2/5] powerpc/pseries: Add RTAS error injection buffer infrastructure
From: Sourabh Jain <hidden>
Date: 2026-06-10 03:27:56
Also in:
lkml
On 27/05/26 12:54, Narayana Murty N wrote:
quoted hunk ↗ jump to hunk
Adds global infrastructure required by the injection engine: - a 1KB aligned RTAS working buffer in rtas.c - a spinlock to serialize buffer access - UAPI definitions for error-injection tokens (added to eeh.h) Signed-off-by: Narayana Murty N <redacted> --- arch/powerpc/include/asm/rtas.h | 21 +++++++++++++++++++++ arch/powerpc/include/uapi/asm/eeh.h | 18 ++++++++++++++++++ arch/powerpc/kernel/rtas.c | 12 ++++++++++++ 3 files changed, 51 insertions(+)diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index d046bbd5017d..82512f822c7a 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h@@ -519,6 +519,27 @@ int rtas_get_error_log_max(void); extern spinlock_t rtas_data_buf_lock; extern char rtas_data_buf[RTAS_DATA_BUF_SIZE]; +/* + * RTAS Error Injection Buffer (PAPR-compliant) + * ============================================ + * + * 1KB aligned, zero-initialized buffer for ibm,errinjct RTAS work area. + * Protected by rtas_errinjct_buf_lock for concurrent access safety. + * + * PAPR Requirement: ibm,errinjct requires a caller-allocated buffer passed + * via physical address. Buffer must accommodate largest error type layouts: + * - IOA bus error (64-bit): 8x32-bit words (32 bytes) + * - All other types: <=4x32-bit words (16 bytes) + * + * Usage: + * prepare_errinjct_buffer() -> spin_lock() -> rtas_call() -> spin_unlock() + * + * Alignment: SZ_1K ensures PAPR firmware requirements and cache-line safety. + */ +#define RTAS_ERRINJCT_BUF_SIZE 1024 +extern spinlock_t rtas_errinjct_buf_lock; +extern char rtas_errinjct_buf[RTAS_ERRINJCT_BUF_SIZE];
The kernel has a similar buffer for userspace (named rtas_rmo_buf), which is allocated in the range (0, min(ppc64_rma_size, RTAS_INSTANTIATE_MAX)). Whereas, the base address of the statically allocated rtas_errinjct_buf array depends on the location at which the kernel is loaded, which could be higher than RTAS_INSTANTIATE_MAX. Also, things will break if the base address of rtas_errinjct_buf is greater than 4 GB. In that case, the kernel will send a truncated address, and RTAS may corrupt memory as a result. Why don't we allocate rtas_errinjct_buf in the same range where rtas_rmo_buf is allocated?
quoted hunk ↗ jump to hunk
+ /* RMO buffer reserved for user-space RTAS use */ extern unsigned long rtas_rmo_buf;diff --git a/arch/powerpc/include/uapi/asm/eeh.h b/arch/powerpc/include/uapi/asm/eeh.h index 3b5c47ff3fc4..86645cab2827 100644 --- a/arch/powerpc/include/uapi/asm/eeh.h +++ b/arch/powerpc/include/uapi/asm/eeh.h@@ -41,4 +41,22 @@ #define EEH_ERR_FUNC_DMA_WR_TARGET 19 #define EEH_ERR_FUNC_MAX 19 +/* RTAS PCI Error Injection Token Types */ +#define RTAS_ERR_TYPE_FATAL 0x1 +#define RTAS_ERR_TYPE_RECOVERED_RANDOM_EVENT 0x2 +#define RTAS_ERR_TYPE_RECOVERED_SPECIAL_EVENT 0x3 +#define RTAS_ERR_TYPE_CORRUPTED_PAGE 0x4 +#define RTAS_ERR_TYPE_CORRUPTED_SLB 0x5 +#define RTAS_ERR_TYPE_TRANSLATOR_FAILURE 0x6 +#define RTAS_ERR_TYPE_IOA_BUS_ERROR 0x7 +#define RTAS_ERR_TYPE_PLATFORM_SPECIFIC 0x8 +#define RTAS_ERR_TYPE_CORRUPTED_DCACHE_START 0x9 +#define RTAS_ERR_TYPE_CORRUPTED_DCACHE_END 0xA +#define RTAS_ERR_TYPE_CORRUPTED_ICACHE_START 0xB +#define RTAS_ERR_TYPE_CORRUPTED_ICACHE_END 0xC +#define RTAS_ERR_TYPE_CORRUPTED_TLB_START 0xD +#define RTAS_ERR_TYPE_CORRUPTED_TLB_END 0xE +#define RTAS_ERR_TYPE_IOA_BUS_ERROR_64 0xF +#define RTAS_ERR_TYPE_UPSTREAM_IO_ERROR 0x10 + #endif /* _ASM_POWERPC_EEH_H */diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index a2dd94eed9d0..c110965ea1d9 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c@@ -769,6 +769,18 @@ EXPORT_SYMBOL_GPL(rtas_data_buf); unsigned long rtas_rmo_buf; +/* + * RTAS Error Injection Buffer - Global Definitions + * Global 1KB buffer and spinlock for ibm,errinjct RTAS service. + * Exported for pseries EEH error injection usage. + */ + +DEFINE_SPINLOCK(rtas_errinjct_buf_lock); +EXPORT_SYMBOL_GPL(rtas_errinjct_buf_lock); + +char rtas_errinjct_buf[1024] __aligned(SZ_1K); +EXPORT_SYMBOL_GPL(rtas_errinjct_buf); + /* * If non-NULL, this gets called when the kernel terminates. * This is done like this so rtas_flash can be a module.