]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
lkdtm/powerpc: add PPC_RADIX_TLBIEL test for radix MCE validation
authorSayali Patil <sayalip@linux.ibm.com>
Mon, 18 May 2026 06:56:05 +0000 (12:26 +0530)
committerKees Cook <kees@kernel.org>
Thu, 21 May 2026 10:21:01 +0000 (03:21 -0700)
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>
drivers/misc/lkdtm/Makefile
drivers/misc/lkdtm/core.c
drivers/misc/lkdtm/powerpc.c
tools/testing/selftests/lkdtm/tests.txt

index 03ebe33185f9d0f32a3a47392db9b9b593a2c78c..4e58d16fc01e55b3facce6087f14d1d9f9627016 100644 (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
 
index 5732fd59a227d05723dfa5a2843ecbf43c803ace..ededa32d6744056af7ec5957d873356261f4c12b 100644 (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
 };
index ef07e5201edf8aa4668b1bdbc0787963db31cc25..6eaac79ea26b4db36218fa0ed2ca0a7d78b170d1 100644 (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 = {
index 3245032db34d32434e01fdaaf922d6c34d775130..d8180bbe31e8bda4be64383c82098363c8e71f03 100644 (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