2 * Simple sanity test for emulate_step load/store instructions.
4 * Copyright IBM Corp. 2016
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
12 #define pr_fmt(fmt) "emulate_step_test: " fmt
14 #include <linux/ptrace.h>
15 #include <asm/sstep.h>
16 #include <asm/ppc-opcode.h>
18 #define IMM_L(i) ((uintptr_t)(i) & 0xffff)
21 * Defined with TEST_ prefix so it does not conflict with other
24 #define TEST_LD(r, base, i) (PPC_INST_LD | ___PPC_RT(r) | \
25 ___PPC_RA(base) | IMM_L(i))
26 #define TEST_LWZ(r, base, i) (PPC_INST_LWZ | ___PPC_RT(r) | \
27 ___PPC_RA(base) | IMM_L(i))
28 #define TEST_LWZX(t, a, b) (PPC_INST_LWZX | ___PPC_RT(t) | \
29 ___PPC_RA(a) | ___PPC_RB(b))
30 #define TEST_STD(r, base, i) (PPC_INST_STD | ___PPC_RS(r) | \
31 ___PPC_RA(base) | ((i) & 0xfffc))
32 #define TEST_LDARX(t, a, b, eh) (PPC_INST_LDARX | ___PPC_RT(t) | \
33 ___PPC_RA(a) | ___PPC_RB(b) | \
35 #define TEST_STDCX(s, a, b) (PPC_INST_STDCX | ___PPC_RS(s) | \
36 ___PPC_RA(a) | ___PPC_RB(b))
37 #define TEST_LFSX(t, a, b) (PPC_INST_LFSX | ___PPC_RT(t) | \
38 ___PPC_RA(a) | ___PPC_RB(b))
39 #define TEST_STFSX(s, a, b) (PPC_INST_STFSX | ___PPC_RS(s) | \
40 ___PPC_RA(a) | ___PPC_RB(b))
41 #define TEST_LFDX(t, a, b) (PPC_INST_LFDX | ___PPC_RT(t) | \
42 ___PPC_RA(a) | ___PPC_RB(b))
43 #define TEST_STFDX(s, a, b) (PPC_INST_STFDX | ___PPC_RS(s) | \
44 ___PPC_RA(a) | ___PPC_RB(b))
45 #define TEST_LVX(t, a, b) (PPC_INST_LVX | ___PPC_RT(t) | \
46 ___PPC_RA(a) | ___PPC_RB(b))
47 #define TEST_STVX(s, a, b) (PPC_INST_STVX | ___PPC_RS(s) | \
48 ___PPC_RA(a) | ___PPC_RB(b))
49 #define TEST_LXVD2X(s, a, b) (PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b))
50 #define TEST_STXVD2X(s, a, b) (PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b))
53 static void __init
init_pt_regs(struct pt_regs
*regs
)
55 static unsigned long msr
;
56 static bool msr_cached
;
58 memset(regs
, 0, sizeof(struct pt_regs
));
60 if (likely(msr_cached
)) {
65 asm volatile("mfmsr %0" : "=r"(regs
->msr
));
75 static void __init
show_result(char *ins
, char *result
)
77 pr_info("%-14s : %s\n", ins
, result
);
80 static void __init
test_ld(void)
83 unsigned long a
= 0x23;
87 regs
.gpr
[3] = (unsigned long) &a
;
90 stepped
= emulate_step(®s
, TEST_LD(5, 3, 0));
92 if (stepped
== 1 && regs
.gpr
[5] == a
)
93 show_result("ld", "PASS");
95 show_result("ld", "FAIL");
98 static void __init
test_lwz(void)
101 unsigned int a
= 0x4545;
105 regs
.gpr
[3] = (unsigned long) &a
;
108 stepped
= emulate_step(®s
, TEST_LWZ(5, 3, 0));
110 if (stepped
== 1 && regs
.gpr
[5] == a
)
111 show_result("lwz", "PASS");
113 show_result("lwz", "FAIL");
116 static void __init
test_lwzx(void)
119 unsigned int a
[3] = {0x0, 0x0, 0x1234};
123 regs
.gpr
[3] = (unsigned long) a
;
125 regs
.gpr
[5] = 0x8765;
127 /* lwzx r5, r3, r4 */
128 stepped
= emulate_step(®s
, TEST_LWZX(5, 3, 4));
129 if (stepped
== 1 && regs
.gpr
[5] == a
[2])
130 show_result("lwzx", "PASS");
132 show_result("lwzx", "FAIL");
135 static void __init
test_std(void)
138 unsigned long a
= 0x1234;
142 regs
.gpr
[3] = (unsigned long) &a
;
143 regs
.gpr
[5] = 0x5678;
146 stepped
= emulate_step(®s
, TEST_STD(5, 3, 0));
147 if (stepped
== 1 || regs
.gpr
[5] == a
)
148 show_result("std", "PASS");
150 show_result("std", "FAIL");
153 static void __init
test_ldarx_stdcx(void)
156 unsigned long a
= 0x1234;
158 unsigned long cr0_eq
= 0x1 << 29; /* eq bit of CR0 */
161 asm volatile("mfcr %0" : "=r"(regs
.ccr
));
166 regs
.gpr
[3] = (unsigned long) &a
;
168 regs
.gpr
[5] = 0x5678;
170 /* ldarx r5, r3, r4, 0 */
171 stepped
= emulate_step(®s
, TEST_LDARX(5, 3, 4, 0));
174 * Don't touch 'a' here. Touching 'a' can do Load/store
175 * of 'a' which result in failure of subsequent stdcx.
176 * Instead, use hardcoded value for comparison.
178 if (stepped
<= 0 || regs
.gpr
[5] != 0x1234) {
179 show_result("ldarx / stdcx.", "FAIL (ldarx)");
186 regs
.gpr
[5] = 0x9ABC;
188 /* stdcx. r5, r3, r4 */
189 stepped
= emulate_step(®s
, TEST_STDCX(5, 3, 4));
192 * Two possible scenarios that indicates successful emulation
194 * 1. Reservation is active and store is performed. In this
195 * case cr0.eq bit will be set to 1.
196 * 2. Reservation is not active and store is not performed.
197 * In this case cr0.eq bit will be set to 0.
199 if (stepped
== 1 && ((regs
.gpr
[5] == a
&& (regs
.ccr
& cr0_eq
))
200 || (regs
.gpr
[5] != a
&& !(regs
.ccr
& cr0_eq
))))
201 show_result("ldarx / stdcx.", "PASS");
203 show_result("ldarx / stdcx.", "FAIL (stdcx.)");
206 #ifdef CONFIG_PPC_FPU
207 static void __init
test_lfsx_stfsx(void)
225 regs
.gpr
[3] = (unsigned long) &c
.a
;
228 /* lfsx frt10, r3, r4 */
229 stepped
= emulate_step(®s
, TEST_LFSX(10, 3, 4));
232 show_result("lfsx", "PASS");
234 show_result("lfsx", "FAIL");
241 /* stfsx frs10, r3, r4 */
242 stepped
= emulate_step(®s
, TEST_STFSX(10, 3, 4));
244 if (stepped
== 1 && c
.b
== cached_b
)
245 show_result("stfsx", "PASS");
247 show_result("stfsx", "FAIL");
250 static void __init
test_lfdx_stfdx(void)
268 regs
.gpr
[3] = (unsigned long) &c
.a
;
271 /* lfdx frt10, r3, r4 */
272 stepped
= emulate_step(®s
, TEST_LFDX(10, 3, 4));
275 show_result("lfdx", "PASS");
277 show_result("lfdx", "FAIL");
284 /* stfdx frs10, r3, r4 */
285 stepped
= emulate_step(®s
, TEST_STFDX(10, 3, 4));
287 if (stepped
== 1 && c
.b
== cached_b
)
288 show_result("stfdx", "PASS");
290 show_result("stfdx", "FAIL");
293 static void __init
test_lfsx_stfsx(void)
295 show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
296 show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
299 static void __init
test_lfdx_stfdx(void)
301 show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
302 show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
304 #endif /* CONFIG_PPC_FPU */
306 #ifdef CONFIG_ALTIVEC
307 static void __init
test_lvx_stvx(void)
322 cached_b
[0] = c
.b
[0] = 923745;
323 cached_b
[1] = c
.b
[1] = 2139478;
324 cached_b
[2] = c
.b
[2] = 9012;
325 cached_b
[3] = c
.b
[3] = 982134;
327 regs
.gpr
[3] = (unsigned long) &c
.a
;
330 /* lvx vrt10, r3, r4 */
331 stepped
= emulate_step(®s
, TEST_LVX(10, 3, 4));
334 show_result("lvx", "PASS");
336 show_result("lvx", "FAIL");
346 /* stvx vrs10, r3, r4 */
347 stepped
= emulate_step(®s
, TEST_STVX(10, 3, 4));
349 if (stepped
== 1 && cached_b
[0] == c
.b
[0] && cached_b
[1] == c
.b
[1] &&
350 cached_b
[2] == c
.b
[2] && cached_b
[3] == c
.b
[3])
351 show_result("stvx", "PASS");
353 show_result("stvx", "FAIL");
356 static void __init
test_lvx_stvx(void)
358 show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
359 show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
361 #endif /* CONFIG_ALTIVEC */
364 static void __init
test_lxvd2x_stxvd2x(void)
379 cached_b
[0] = c
.b
[0] = 18233;
380 cached_b
[1] = c
.b
[1] = 34863571;
381 cached_b
[2] = c
.b
[2] = 834;
382 cached_b
[3] = c
.b
[3] = 6138911;
384 regs
.gpr
[3] = (unsigned long) &c
.a
;
387 /* lxvd2x vsr39, r3, r4 */
388 stepped
= emulate_step(®s
, TEST_LXVD2X(39, 3, 4));
391 show_result("lxvd2x", "PASS");
393 show_result("lxvd2x", "FAIL");
403 /* stxvd2x vsr39, r3, r4 */
404 stepped
= emulate_step(®s
, TEST_STXVD2X(39, 3, 4));
406 if (stepped
== 1 && cached_b
[0] == c
.b
[0] && cached_b
[1] == c
.b
[1] &&
407 cached_b
[2] == c
.b
[2] && cached_b
[3] == c
.b
[3])
408 show_result("stxvd2x", "PASS");
410 show_result("stxvd2x", "FAIL");
413 static void __init
test_lxvd2x_stxvd2x(void)
415 show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
416 show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
418 #endif /* CONFIG_VSX */
420 static int __init
test_emulate_step(void)
430 test_lxvd2x_stxvd2x();
434 late_initcall(test_emulate_step
);