aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
authorMark Brown <broonie@kernel.org>2026-05-30 00:25:59 +0100
committerMark Brown <broonie@kernel.org>2026-05-30 00:25:59 +0100
commit7a2dbd1f5b916884a4d67fa8bcab7b1f369974b7 (patch)
tree101557d079e4da42a6b7f610032d17d3ad02caa4 /drivers
parent71380c34142c2e98723d7d291f88323c64c934de (diff)
parentc2606fb910d7cade63ee7e9c28e6a4225d0383f6 (diff)
downloadlinux-next-history-7a2dbd1f5b916884a4d67fa8bcab7b1f369974b7.tar.gz
Merge branch 'for-next/kspp' of https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/lkdtm/Makefile2
-rw-r--r--drivers/misc/lkdtm/bugs.c27
-rw-r--r--drivers/misc/lkdtm/core.c2
-rw-r--r--drivers/misc/lkdtm/powerpc.c49
4 files changed, 78 insertions, 2 deletions
diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile
index 03ebe33185f9d..4e58d16fc01e5 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/bugs.c b/drivers/misc/lkdtm/bugs.c
index e0098f314570d..3eca2ef64afff 100644
--- a/drivers/misc/lkdtm/bugs.c
+++ b/drivers/misc/lkdtm/bugs.c
@@ -7,6 +7,7 @@
*/
#include "lkdtm.h"
#include <linux/cpu.h>
+#include <linux/efi.h>
#include <linux/list.h>
#include <linux/hrtimer.h>
#include <linux/sched.h>
@@ -817,6 +818,29 @@ static noinline void lkdtm_CORRUPT_PAC(void)
#endif
}
+static void __maybe_unused lkdtm_EFI_RUNTIME_CRASH(void)
+{
+ static unsigned long size __ro_after_init = sizeof(efi_char16_t);
+ efi_status_t status;
+
+ if (!efi.get_next_variable ||
+ !efi_enabled(EFI_RUNTIME_SERVICES) ||
+ !efi_rt_services_supported(EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) {
+ pr_err("FAIL: EFI GetNextVariableName() is not available\n");
+ return;
+ }
+
+ /*
+ * Provoke a fault by asking the firmware to write to a read-only
+ * variable.
+ */
+ status = efi.get_next_variable(&size, L"", &(efi_guid_t){});
+
+ if (status != EFI_ABORTED || efi_enabled(EFI_RUNTIME_SERVICES))
+ pr_err("FAIL: EFI GetNextVariable() did not abort (%#lx)\n",
+ status);
+}
+
static struct crashtype crashtypes[] = {
CRASHTYPE(PANIC),
CRASHTYPE(PANIC_STOP_IRQOFF),
@@ -850,6 +874,9 @@ static struct crashtype crashtypes[] = {
CRASHTYPE(UNSET_SMEP),
CRASHTYPE(DOUBLE_FAULT),
CRASHTYPE(CORRUPT_PAC),
+#ifdef CONFIG_EFI
+ CRASHTYPE(EFI_RUNTIME_CRASH),
+#endif
};
struct crashtype_category bugs_crashtypes = {
diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
index 5732fd59a227d..ededa32d67440 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 be385449911a8..6eaac79ea26b4 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)
{
@@ -17,11 +18,14 @@ static void insert_slb_entry(unsigned long p, int ssize, int page_size)
: "r" (mk_vsid_data(p, ssize, flags)),
"r" (mk_esid_data(p, ssize, SLB_NUM_BOLTED))
: "memory");
+ isync();
asm volatile("slbmte %0,%1" :
: "r" (mk_vsid_data(p, ssize, flags)),
"r" (mk_esid_data(p, ssize, SLB_NUM_BOLTED + 1))
: "memory");
+ isync();
+
preempt_enable();
}
@@ -84,6 +88,7 @@ static void insert_dup_slb_entry_0(void)
: "r" (vsid),
"r" (esid | SLB_NUM_BOLTED)
: "memory");
+ isync();
asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
@@ -93,15 +98,42 @@ static void insert_dup_slb_entry_0(void)
: "r" (vsid),
"r" (esid | (SLB_NUM_BOLTED + 1))
: "memory");
+ isync();
pr_info("%s accessing test address 0x%lx: 0x%lx\n",
__func__, test_address, *test_ptr);
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");
/*
@@ -117,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 = {