1 // SPDX-License-Identifier: GPL-2.0
4 #include <linux/slab.h>
5 #include <linux/vmalloc.h>
8 /* Inserts new slb entries */
9 static void insert_slb_entry(unsigned long p
, int ssize
, int page_size
)
13 flags
= SLB_VSID_KERNEL
| mmu_psize_defs
[page_size
].sllp
;
16 asm volatile("slbmte %0,%1" :
17 : "r" (mk_vsid_data(p
, ssize
, flags
)),
18 "r" (mk_esid_data(p
, ssize
, SLB_NUM_BOLTED
))
21 asm volatile("slbmte %0,%1" :
22 : "r" (mk_vsid_data(p
, ssize
, flags
)),
23 "r" (mk_esid_data(p
, ssize
, SLB_NUM_BOLTED
+ 1))
28 /* Inject slb multihit on vmalloc-ed address i.e 0xD00... */
29 static int inject_vmalloc_slb_multihit(void)
33 p
= vmalloc(PAGE_SIZE
);
37 insert_slb_entry((unsigned long)p
, MMU_SEGSIZE_1T
, mmu_vmalloc_psize
);
39 * This triggers exception, If handled correctly we must recover
47 /* Inject slb multihit on kmalloc-ed address i.e 0xC00... */
48 static int inject_kmalloc_slb_multihit(void)
52 p
= kmalloc(2048, GFP_KERNEL
);
56 insert_slb_entry((unsigned long)p
, MMU_SEGSIZE_1T
, mmu_linear_psize
);
58 * This triggers exception, If handled correctly we must recover
67 * Few initial SLB entries are bolted. Add a test to inject
68 * multihit in bolted entry 0.
70 static void insert_dup_slb_entry_0(void)
72 unsigned long test_address
= PAGE_OFFSET
, *test_ptr
;
73 unsigned long esid
, vsid
;
76 test_ptr
= (unsigned long *)test_address
;
79 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
80 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
82 /* for i !=0 we would need to mask out the old entry number */
83 asm volatile("slbmte %0,%1" :
85 "r" (esid
| SLB_NUM_BOLTED
)
88 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
89 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
91 /* for i !=0 we would need to mask out the old entry number */
92 asm volatile("slbmte %0,%1" :
94 "r" (esid
| (SLB_NUM_BOLTED
+ 1))
97 pr_info("%s accessing test address 0x%lx: 0x%lx\n",
98 __func__
, test_address
, *test_ptr
);
103 static void lkdtm_PPC_SLB_MULTIHIT(void)
105 if (!radix_enabled()) {
106 pr_info("Injecting SLB multihit errors\n");
108 * These need not be separate tests, And they do pretty
109 * much same thing. In any case we must recover from the
110 * errors introduced by these functions, machine would not
111 * survive these tests in case of failure to handle.
113 inject_vmalloc_slb_multihit();
114 inject_kmalloc_slb_multihit();
115 insert_dup_slb_entry_0();
116 pr_info("Recovered from SLB multihit errors\n");
118 pr_err("XFAIL: This test is for ppc64 and with hash mode MMU only\n");
122 static struct crashtype crashtypes
[] = {
123 CRASHTYPE(PPC_SLB_MULTIHIT
),
126 struct crashtype_category powerpc_crashtypes
= {
127 .crashtypes
= crashtypes
,
128 .len
= ARRAY_SIZE(crashtypes
),