Add a new LKDTM trigger (PPC_RADIX_TLBIEL) that executes a process-scoped radix TLBIEL instruction to exercise the radix MMU behaviour and associated machine check exception (MCE) handling paths.
This provides a way to validate MCE handling in radix mode. Currently, there is no dedicated LKDTM test that exercises this path or allows triggering radix-specific machine check behaviour for validation. The test is only enabled on ppc64 systems with radix MMU support and If radix is not active, the trigger is skipped and reported as XFAIL. Co-developed-by: Ritesh Harjani (IBM) <[email protected]> Signed-off-by: Ritesh Harjani (IBM) <[email protected]> Signed-off-by: Sayali Patil <[email protected]> --- drivers/misc/lkdtm/Makefile | 2 +- drivers/misc/lkdtm/powerpc.c | 39 +++++++++++++++++++++++++ tools/testing/selftests/lkdtm/tests.txt | 1 + 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile index 03ebe33185f9..4e58d16fc01e 100644 --- a/drivers/misc/lkdtm/Makefile +++ b/drivers/misc/lkdtm/Makefile @@ -11,7 +11,7 @@ lkdtm-$(CONFIG_LKDTM) += usercopy.o lkdtm-$(CONFIG_LKDTM) += kstack_erase.o lkdtm-$(CONFIG_LKDTM) += cfi.o lkdtm-$(CONFIG_LKDTM) += fortify.o -lkdtm-$(CONFIG_PPC_64S_HASH_MMU) += powerpc.o +lkdtm-$(CONFIG_PPC_BOOK3S_64) += powerpc.o KASAN_SANITIZE_stackleak.o := n diff --git a/drivers/misc/lkdtm/powerpc.c b/drivers/misc/lkdtm/powerpc.c index ef07e5201edf..3d56b56f5e0c 100644 --- a/drivers/misc/lkdtm/powerpc.c +++ b/drivers/misc/lkdtm/powerpc.c @@ -105,6 +105,31 @@ static void insert_dup_slb_entry_0(void) preempt_enable(); } +static void tlbiel_va(unsigned long va, + unsigned long pid, + unsigned long ap, + unsigned long ric) +{ + unsigned long rb, rs, prs, r; + + rb = va & ~(PPC_BITMASK(52, 63)); + rb |= ap << PPC_BITLSHIFT(58); + rs = pid << PPC_BITLSHIFT(31); + + prs = 1; /* process scoped */ + r = 1; /* radix format */ + + /* + * Trigger an MCE by issuing radix tlbiel with an invalid operand combination. + * Using PRS=1 (process-scoped) with kernel address does not correspond to + * any valid process-scoped translation. + * This results in an invalid tlbiel operation, causing hardware to + * raise a machine check. + */ + asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1) + : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); +} + static void lkdtm_PPC_SLB_MULTIHIT(void) { if (!radix_enabled()) { @@ -124,8 +149,22 @@ static void lkdtm_PPC_SLB_MULTIHIT(void) } } +static void lkdtm_PPC_RADIX_TLBIEL(void) +{ + unsigned long addr = PAGE_OFFSET; + + if (radix_enabled()) { + pr_info("Injecting Radix TLB invalidation MCE\n"); + tlbiel_va(addr, 0, 0, RIC_FLUSH_ALL); + pr_info("Recovered from radix tlbiel attempt\n"); + } else { + pr_err("XFAIL: This test is for ppc64 and with radix mode MMU only\n"); + } +} + static struct crashtype crashtypes[] = { CRASHTYPE(PPC_SLB_MULTIHIT), + CRASHTYPE(PPC_RADIX_TLBIEL), }; struct crashtype_category powerpc_crashtypes = { diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt index 3245032db34d..d8180bbe31e8 100644 --- a/tools/testing/selftests/lkdtm/tests.txt +++ b/tools/testing/selftests/lkdtm/tests.txt @@ -86,3 +86,4 @@ FORTIFY_STR_MEMBER detected buffer overflow FORTIFY_MEM_OBJECT detected buffer overflow FORTIFY_MEM_MEMBER detected field-spanning write PPC_SLB_MULTIHIT Recovered +#PPC_RADIX_TLBIEL Triggers unrecoverable MCE -- 2.52.0
