lkdtm/powerpc: add PPC_RADIX_TLBIEL test for radix MCE validation

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) <ritesh.list@gmail.com>
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Signed-off-by: Sayali Patil <sayalip@linux.ibm.com>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Reviewed-by: Michael Ellerman <mpe@kernel.org>
Link: https://patch.msgid.link/85c9b59217bcecb3c7af52e9d5b175266771d7de.1778975974.git.sayalip@linux.ibm.com
Signed-off-by: Kees Cook <kees@kernel.org>
This commit is contained in:
Sayali Patil 2026-05-18 12:26:05 +05:30 committed by Kees Cook
parent 3f21a4426e
commit 122b52f0ba
4 changed files with 47 additions and 2 deletions

View File

@ -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

View File

@ -96,7 +96,7 @@ static const struct crashtype_category *crashtype_categories[] = {
&stackleak_crashtypes,
&cfi_crashtypes,
&fortify_crashtypes,
#ifdef CONFIG_PPC_64S_HASH_MMU
#ifdef CONFIG_PPC_BOOK3S_64
&powerpc_crashtypes,
#endif
};

View File

@ -5,6 +5,7 @@
#include <linux/vmalloc.h>
#include <asm/mmu.h>
#ifdef CONFIG_PPC_64S_HASH_MMU
/* Inserts new slb entries */
static void insert_slb_entry(unsigned long p, int ssize, int page_size)
{
@ -104,9 +105,35 @@ static void insert_dup_slb_entry_0(void)
preempt_enable();
}
#endif /* CONFIG_PPC_64S_HASH_MMU */
static __always_inline 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.
* The combination of RIC = 2 with IS = 0 (Invalidation selector specified
* in the RB register) is invalid.
* This invalid combination causes 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)
{
#ifdef CONFIG_PPC_64S_HASH_MMU
if (!radix_enabled()) {
pr_info("Injecting SLB multihit errors\n");
/*
@ -122,10 +149,27 @@ static void lkdtm_PPC_SLB_MULTIHIT(void)
} else {
pr_err("XFAIL: This test is for ppc64 and with hash mode MMU only\n");
}
#else
pr_err("XFAIL: This test requires CONFIG_PPC_64S_HASH_MMU\n");
#endif
}
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 = {

View File

@ -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