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/core.c b/drivers/misc/lkdtm/core.c
index 5732fd59a227..ededa32d6744 100644
--- a/drivers/misc/lkdtm/core.c
+++ b/drivers/misc/lkdtm/core.c
@@ -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
};diff --git a/drivers/misc/lkdtm/powerpc.c b/drivers/misc/lkdtm/powerpc.c
index ef07e5201edf..6eaac79ea26b 100644
--- a/drivers/misc/lkdtm/powerpc.c
+++ b/drivers/misc/lkdtm/powerpc.c
@@ -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 = {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