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);