1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Simple sanity tests for instruction emulation infrastructure.
5 * Copyright IBM Corp. 2016
8 #define pr_fmt(fmt) "emulate_step_test: " fmt
10 #include <linux/ptrace.h>
11 #include <asm/cpu_has_feature.h>
12 #include <asm/sstep.h>
13 #include <asm/ppc-opcode.h>
14 #include <asm/code-patching.h>
17 #define MAX_SUBTESTS 16
19 #define IGNORE_GPR(n) (0x1UL << (n))
20 #define IGNORE_XER (0x1UL << 32)
21 #define IGNORE_CCR (0x1UL << 33)
22 #define NEGATIVE_TEST (0x1UL << 63)
24 #define TEST_PLD(r, base, i, pr) \
25 ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
26 PPC_INST_PLD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
28 #define TEST_PLWZ(r, base, i, pr) \
29 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
30 PPC_RAW_LWZ(r, base, i))
32 #define TEST_PSTD(r, base, i, pr) \
33 ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
34 PPC_INST_PSTD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
36 #define TEST_PLFS(r, base, i, pr) \
37 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
38 PPC_INST_LFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
40 #define TEST_PSTFS(r, base, i, pr) \
41 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
42 PPC_INST_STFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
44 #define TEST_PLFD(r, base, i, pr) \
45 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
46 PPC_INST_LFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
48 #define TEST_PSTFD(r, base, i, pr) \
49 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
50 PPC_INST_STFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
52 #define TEST_PADDI(t, a, i, pr) \
53 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
54 PPC_RAW_ADDI(t, a, i))
56 static void __init init_pt_regs(struct pt_regs *regs)
58 static unsigned long msr;
59 static bool msr_cached;
61 memset(regs, 0, sizeof(struct pt_regs));
63 if (likely(msr_cached)) {
68 asm volatile("mfmsr %0" : "=r"(regs->msr));
78 static void __init show_result(char *mnemonic, char *result)
80 pr_info("%-14s : %s\n", mnemonic, result);
83 static void __init show_result_with_descr(char *mnemonic, char *descr,
86 pr_info("%-14s : %-50s %s\n", mnemonic, descr, result);
89 static void __init test_ld(void)
92 unsigned long a = 0x23;
96 regs.gpr[3] = (unsigned long) &a;
99 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LD(5, 3, 0)));
101 if (stepped == 1 && regs.gpr[5] == a)
102 show_result("ld", "PASS");
104 show_result("ld", "FAIL");
107 static void __init test_pld(void)
110 unsigned long a = 0x23;
113 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
114 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
119 regs.gpr[3] = (unsigned long)&a;
121 /* pld r5, 0(r3), 0 */
122 stepped = emulate_step(®s, TEST_PLD(5, 3, 0, 0));
124 if (stepped == 1 && regs.gpr[5] == a)
125 show_result("pld", "PASS");
127 show_result("pld", "FAIL");
130 static void __init test_lwz(void)
133 unsigned int a = 0x4545;
137 regs.gpr[3] = (unsigned long) &a;
140 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LWZ(5, 3, 0)));
142 if (stepped == 1 && regs.gpr[5] == a)
143 show_result("lwz", "PASS");
145 show_result("lwz", "FAIL");
148 static void __init test_plwz(void)
151 unsigned int a = 0x4545;
154 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
155 show_result("plwz", "SKIP (!CPU_FTR_ARCH_31)");
160 regs.gpr[3] = (unsigned long)&a;
162 /* plwz r5, 0(r3), 0 */
164 stepped = emulate_step(®s, TEST_PLWZ(5, 3, 0, 0));
166 if (stepped == 1 && regs.gpr[5] == a)
167 show_result("plwz", "PASS");
169 show_result("plwz", "FAIL");
172 static void __init test_lwzx(void)
175 unsigned int a[3] = {0x0, 0x0, 0x1234};
179 regs.gpr[3] = (unsigned long) a;
181 regs.gpr[5] = 0x8765;
183 /* lwzx r5, r3, r4 */
184 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LWZX(5, 3, 4)));
185 if (stepped == 1 && regs.gpr[5] == a[2])
186 show_result("lwzx", "PASS");
188 show_result("lwzx", "FAIL");
191 static void __init test_std(void)
194 unsigned long a = 0x1234;
198 regs.gpr[3] = (unsigned long) &a;
199 regs.gpr[5] = 0x5678;
202 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STD(5, 3, 0)));
203 if (stepped == 1 && regs.gpr[5] == a)
204 show_result("std", "PASS");
206 show_result("std", "FAIL");
209 static void __init test_pstd(void)
212 unsigned long a = 0x1234;
215 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
216 show_result("pstd", "SKIP (!CPU_FTR_ARCH_31)");
221 regs.gpr[3] = (unsigned long)&a;
222 regs.gpr[5] = 0x5678;
224 /* pstd r5, 0(r3), 0 */
225 stepped = emulate_step(®s, TEST_PSTD(5, 3, 0, 0));
226 if (stepped == 1 || regs.gpr[5] == a)
227 show_result("pstd", "PASS");
229 show_result("pstd", "FAIL");
232 static void __init test_ldarx_stdcx(void)
235 unsigned long a = 0x1234;
237 unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
240 asm volatile("mfcr %0" : "=r"(regs.ccr));
245 regs.gpr[3] = (unsigned long) &a;
247 regs.gpr[5] = 0x5678;
249 /* ldarx r5, r3, r4, 0 */
250 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LDARX(5, 3, 4, 0)));
253 * Don't touch 'a' here. Touching 'a' can do Load/store
254 * of 'a' which result in failure of subsequent stdcx.
255 * Instead, use hardcoded value for comparison.
257 if (stepped <= 0 || regs.gpr[5] != 0x1234) {
258 show_result("ldarx / stdcx.", "FAIL (ldarx)");
265 regs.gpr[5] = 0x9ABC;
267 /* stdcx. r5, r3, r4 */
268 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STDCX(5, 3, 4)));
271 * Two possible scenarios that indicates successful emulation
273 * 1. Reservation is active and store is performed. In this
274 * case cr0.eq bit will be set to 1.
275 * 2. Reservation is not active and store is not performed.
276 * In this case cr0.eq bit will be set to 0.
278 if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
279 || (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
280 show_result("ldarx / stdcx.", "PASS");
282 show_result("ldarx / stdcx.", "FAIL (stdcx.)");
285 #ifdef CONFIG_PPC_FPU
286 static void __init test_lfsx_stfsx(void)
304 regs.gpr[3] = (unsigned long) &c.a;
307 /* lfsx frt10, r3, r4 */
308 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LFSX(10, 3, 4)));
311 show_result("lfsx", "PASS");
313 show_result("lfsx", "FAIL");
320 /* stfsx frs10, r3, r4 */
321 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STFSX(10, 3, 4)));
323 if (stepped == 1 && c.b == cached_b)
324 show_result("stfsx", "PASS");
326 show_result("stfsx", "FAIL");
329 static void __init test_plfs_pstfs(void)
339 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
340 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
352 regs.gpr[3] = (unsigned long)&c.a;
354 /* plfs frt10, 0(r3), 0 */
355 stepped = emulate_step(®s, TEST_PLFS(10, 3, 0, 0));
358 show_result("plfs", "PASS");
360 show_result("plfs", "FAIL");
367 /* pstfs frs10, 0(r3), 0 */
368 stepped = emulate_step(®s, TEST_PSTFS(10, 3, 0, 0));
370 if (stepped == 1 && c.b == cached_b)
371 show_result("pstfs", "PASS");
373 show_result("pstfs", "FAIL");
376 static void __init test_lfdx_stfdx(void)
394 regs.gpr[3] = (unsigned long) &c.a;
397 /* lfdx frt10, r3, r4 */
398 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LFDX(10, 3, 4)));
401 show_result("lfdx", "PASS");
403 show_result("lfdx", "FAIL");
410 /* stfdx frs10, r3, r4 */
411 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STFDX(10, 3, 4)));
413 if (stepped == 1 && c.b == cached_b)
414 show_result("stfdx", "PASS");
416 show_result("stfdx", "FAIL");
419 static void __init test_plfd_pstfd(void)
429 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
430 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
442 regs.gpr[3] = (unsigned long)&c.a;
444 /* plfd frt10, 0(r3), 0 */
445 stepped = emulate_step(®s, TEST_PLFD(10, 3, 0, 0));
448 show_result("plfd", "PASS");
450 show_result("plfd", "FAIL");
457 /* pstfd frs10, 0(r3), 0 */
458 stepped = emulate_step(®s, TEST_PSTFD(10, 3, 0, 0));
460 if (stepped == 1 && c.b == cached_b)
461 show_result("pstfd", "PASS");
463 show_result("pstfd", "FAIL");
466 static void __init test_lfsx_stfsx(void)
468 show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
469 show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
472 static void __init test_plfs_pstfs(void)
474 show_result("plfs", "SKIP (CONFIG_PPC_FPU is not set)");
475 show_result("pstfs", "SKIP (CONFIG_PPC_FPU is not set)");
478 static void __init test_lfdx_stfdx(void)
480 show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
481 show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
484 static void __init test_plfd_pstfd(void)
486 show_result("plfd", "SKIP (CONFIG_PPC_FPU is not set)");
487 show_result("pstfd", "SKIP (CONFIG_PPC_FPU is not set)");
489 #endif /* CONFIG_PPC_FPU */
491 #ifdef CONFIG_ALTIVEC
492 static void __init test_lvx_stvx(void)
507 cached_b[0] = c.b[0] = 923745;
508 cached_b[1] = c.b[1] = 2139478;
509 cached_b[2] = c.b[2] = 9012;
510 cached_b[3] = c.b[3] = 982134;
512 regs.gpr[3] = (unsigned long) &c.a;
515 /* lvx vrt10, r3, r4 */
516 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LVX(10, 3, 4)));
519 show_result("lvx", "PASS");
521 show_result("lvx", "FAIL");
531 /* stvx vrs10, r3, r4 */
532 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STVX(10, 3, 4)));
534 if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
535 cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
536 show_result("stvx", "PASS");
538 show_result("stvx", "FAIL");
541 static void __init test_lvx_stvx(void)
543 show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
544 show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
546 #endif /* CONFIG_ALTIVEC */
549 static void __init test_lxvd2x_stxvd2x(void)
564 cached_b[0] = c.b[0] = 18233;
565 cached_b[1] = c.b[1] = 34863571;
566 cached_b[2] = c.b[2] = 834;
567 cached_b[3] = c.b[3] = 6138911;
569 regs.gpr[3] = (unsigned long) &c.a;
572 /* lxvd2x vsr39, r3, r4 */
573 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVD2X(39, R3, R4)));
575 if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
576 show_result("lxvd2x", "PASS");
578 if (!cpu_has_feature(CPU_FTR_VSX))
579 show_result("lxvd2x", "PASS (!CPU_FTR_VSX)");
581 show_result("lxvd2x", "FAIL");
592 /* stxvd2x vsr39, r3, r4 */
593 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVD2X(39, R3, R4)));
595 if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
596 cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
597 cpu_has_feature(CPU_FTR_VSX)) {
598 show_result("stxvd2x", "PASS");
600 if (!cpu_has_feature(CPU_FTR_VSX))
601 show_result("stxvd2x", "PASS (!CPU_FTR_VSX)");
603 show_result("stxvd2x", "FAIL");
607 static void __init test_lxvd2x_stxvd2x(void)
609 show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
610 show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
612 #endif /* CONFIG_VSX */
615 static void __init test_lxvp_stxvp(void)
625 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
626 show_result("lxvp", "SKIP (!CPU_FTR_ARCH_31)");
627 show_result("stxvp", "SKIP (!CPU_FTR_ARCH_31)");
635 cached_b[0] = c[0].b[0] = 18233;
636 cached_b[1] = c[0].b[1] = 34863571;
637 cached_b[2] = c[0].b[2] = 834;
638 cached_b[3] = c[0].b[3] = 6138911;
639 cached_b[4] = c[1].b[0] = 1234;
640 cached_b[5] = c[1].b[1] = 5678;
641 cached_b[6] = c[1].b[2] = 91011;
642 cached_b[7] = c[1].b[3] = 121314;
644 regs.gpr[4] = (unsigned long)&c[0].a;
649 * let TX=1 Tp=1 RA=4 DQ=0
651 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVP(34, 4, 0)));
653 if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
654 show_result("lxvp", "PASS");
656 if (!cpu_has_feature(CPU_FTR_VSX))
657 show_result("lxvp", "PASS (!CPU_FTR_VSX)");
659 show_result("lxvp", "FAIL");
664 c[0].b[0] = 21379463;
676 * let SX=1 Sp=1 RA=4 DQ=0
678 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVP(34, 4, 0)));
680 if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
681 cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
682 cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
683 cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
684 cpu_has_feature(CPU_FTR_VSX)) {
685 show_result("stxvp", "PASS");
687 if (!cpu_has_feature(CPU_FTR_VSX))
688 show_result("stxvp", "PASS (!CPU_FTR_VSX)");
690 show_result("stxvp", "FAIL");
694 static void __init test_lxvp_stxvp(void)
696 show_result("lxvp", "SKIP (CONFIG_VSX is not set)");
697 show_result("stxvp", "SKIP (CONFIG_VSX is not set)");
699 #endif /* CONFIG_VSX */
702 static void __init test_lxvpx_stxvpx(void)
712 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
713 show_result("lxvpx", "SKIP (!CPU_FTR_ARCH_31)");
714 show_result("stxvpx", "SKIP (!CPU_FTR_ARCH_31)");
722 cached_b[0] = c[0].b[0] = 18233;
723 cached_b[1] = c[0].b[1] = 34863571;
724 cached_b[2] = c[0].b[2] = 834;
725 cached_b[3] = c[0].b[3] = 6138911;
726 cached_b[4] = c[1].b[0] = 1234;
727 cached_b[5] = c[1].b[1] = 5678;
728 cached_b[6] = c[1].b[2] = 91011;
729 cached_b[7] = c[1].b[3] = 121314;
731 regs.gpr[3] = (unsigned long)&c[0].a;
737 * let TX=1 Tp=1 RA=3 RB=4
739 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVPX(34, 3, 4)));
741 if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
742 show_result("lxvpx", "PASS");
744 if (!cpu_has_feature(CPU_FTR_VSX))
745 show_result("lxvpx", "PASS (!CPU_FTR_VSX)");
747 show_result("lxvpx", "FAIL");
752 c[0].b[0] = 21379463;
764 * let SX=1 Sp=1 RA=3 RB=4
766 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVPX(34, 3, 4)));
768 if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
769 cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
770 cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
771 cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
772 cpu_has_feature(CPU_FTR_VSX)) {
773 show_result("stxvpx", "PASS");
775 if (!cpu_has_feature(CPU_FTR_VSX))
776 show_result("stxvpx", "PASS (!CPU_FTR_VSX)");
778 show_result("stxvpx", "FAIL");
782 static void __init test_lxvpx_stxvpx(void)
784 show_result("lxvpx", "SKIP (CONFIG_VSX is not set)");
785 show_result("stxvpx", "SKIP (CONFIG_VSX is not set)");
787 #endif /* CONFIG_VSX */
790 static void __init test_plxvp_pstxvp(void)
801 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
802 show_result("plxvp", "SKIP (!CPU_FTR_ARCH_31)");
803 show_result("pstxvp", "SKIP (!CPU_FTR_ARCH_31)");
809 cached_b[0] = c[0].b[0] = 18233;
810 cached_b[1] = c[0].b[1] = 34863571;
811 cached_b[2] = c[0].b[2] = 834;
812 cached_b[3] = c[0].b[3] = 6138911;
813 cached_b[4] = c[1].b[0] = 1234;
814 cached_b[5] = c[1].b[1] = 5678;
815 cached_b[6] = c[1].b[2] = 91011;
816 cached_b[7] = c[1].b[3] = 121314;
819 regs.gpr[3] = (unsigned long)&c[0].a;
824 * let RA=3 R=0 D=d0||d1=0 R=0 Tp=1 TX=1
826 instr = ppc_inst_prefix(PPC_RAW_PLXVP_P(34, 0, 3, 0), PPC_RAW_PLXVP_S(34, 0, 3, 0));
828 stepped = emulate_step(®s, instr);
829 if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
830 show_result("plxvp", "PASS");
832 if (!cpu_has_feature(CPU_FTR_VSX))
833 show_result("plxvp", "PASS (!CPU_FTR_VSX)");
835 show_result("plxvp", "FAIL");
840 c[0].b[0] = 21379463;
852 * let RA=3 D=d0||d1=0 R=0 Sp=1 SX=1
854 instr = ppc_inst_prefix(PPC_RAW_PSTXVP_P(34, 0, 3, 0), PPC_RAW_PSTXVP_S(34, 0, 3, 0));
856 stepped = emulate_step(®s, instr);
858 if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
859 cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
860 cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
861 cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
862 cpu_has_feature(CPU_FTR_VSX)) {
863 show_result("pstxvp", "PASS");
865 if (!cpu_has_feature(CPU_FTR_VSX))
866 show_result("pstxvp", "PASS (!CPU_FTR_VSX)");
868 show_result("pstxvp", "FAIL");
872 static void __init test_plxvp_pstxvp(void)
874 show_result("plxvp", "SKIP (CONFIG_VSX is not set)");
875 show_result("pstxvp", "SKIP (CONFIG_VSX is not set)");
877 #endif /* CONFIG_VSX */
879 static void __init run_tests_load_store(void)
894 test_lxvd2x_stxvd2x();
900 struct compute_test {
902 unsigned long cpu_feature;
908 } subtests[MAX_SUBTESTS + 1];
911 /* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
912 #define SI_MIN BIT(33)
913 #define SI_MAX (BIT(33) - 1)
914 #define SI_UMAX (BIT(34) - 1)
916 static struct compute_test compute_tests[] = {
921 .descr = "R0 = LONG_MAX",
922 .instr = ppc_inst(PPC_RAW_NOP()),
931 .cpu_feature = CPU_FTR_ARCH_300,
934 .descr = "BFA = 1, CR = GT",
935 .instr = ppc_inst(PPC_RAW_SETB(20, 1)),
941 .descr = "BFA = 4, CR = LT",
942 .instr = ppc_inst(PPC_RAW_SETB(20, 4)),
948 .descr = "BFA = 5, CR = EQ",
949 .instr = ppc_inst(PPC_RAW_SETB(20, 5)),
960 .descr = "RA = LONG_MIN, RB = LONG_MIN",
961 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
968 .descr = "RA = LONG_MIN, RB = LONG_MAX",
969 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
976 .descr = "RA = LONG_MAX, RB = LONG_MAX",
977 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
984 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
985 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
987 .gpr[21] = ULONG_MAX,
988 .gpr[22] = ULONG_MAX,
992 .descr = "RA = ULONG_MAX, RB = 0x1",
993 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
995 .gpr[21] = ULONG_MAX,
1000 .descr = "RA = INT_MIN, RB = INT_MIN",
1001 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1008 .descr = "RA = INT_MIN, RB = INT_MAX",
1009 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1016 .descr = "RA = INT_MAX, RB = INT_MAX",
1017 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1024 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1025 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1027 .gpr[21] = UINT_MAX,
1028 .gpr[22] = UINT_MAX,
1032 .descr = "RA = UINT_MAX, RB = 0x1",
1033 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1035 .gpr[21] = UINT_MAX,
1045 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1046 .flags = IGNORE_CCR,
1047 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1049 .gpr[21] = LONG_MIN,
1050 .gpr[22] = LONG_MIN,
1054 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1055 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1057 .gpr[21] = LONG_MIN,
1058 .gpr[22] = LONG_MAX,
1062 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1063 .flags = IGNORE_CCR,
1064 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1066 .gpr[21] = LONG_MAX,
1067 .gpr[22] = LONG_MAX,
1071 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1072 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1074 .gpr[21] = ULONG_MAX,
1075 .gpr[22] = ULONG_MAX,
1079 .descr = "RA = ULONG_MAX, RB = 0x1",
1080 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1082 .gpr[21] = ULONG_MAX,
1087 .descr = "RA = INT_MIN, RB = INT_MIN",
1088 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1095 .descr = "RA = INT_MIN, RB = INT_MAX",
1096 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1103 .descr = "RA = INT_MAX, RB = INT_MAX",
1104 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1111 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1112 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1114 .gpr[21] = UINT_MAX,
1115 .gpr[22] = UINT_MAX,
1119 .descr = "RA = UINT_MAX, RB = 0x1",
1120 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1122 .gpr[21] = UINT_MAX,
1132 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1133 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1135 .gpr[21] = LONG_MIN,
1136 .gpr[22] = LONG_MIN,
1140 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1141 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1143 .gpr[21] = LONG_MIN,
1144 .gpr[22] = LONG_MAX,
1148 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1149 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1151 .gpr[21] = LONG_MAX,
1152 .gpr[22] = LONG_MAX,
1156 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1157 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1159 .gpr[21] = ULONG_MAX,
1160 .gpr[22] = ULONG_MAX,
1164 .descr = "RA = ULONG_MAX, RB = 0x1",
1165 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1167 .gpr[21] = ULONG_MAX,
1172 .descr = "RA = INT_MIN, RB = INT_MIN",
1173 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1180 .descr = "RA = INT_MIN, RB = INT_MAX",
1181 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1188 .descr = "RA = INT_MAX, RB = INT_MAX",
1189 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1196 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1197 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1199 .gpr[21] = UINT_MAX,
1200 .gpr[22] = UINT_MAX,
1204 .descr = "RA = UINT_MAX, RB = 0x1",
1205 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1207 .gpr[21] = UINT_MAX,
1212 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1213 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1215 .gpr[21] = LONG_MIN | (uint)INT_MIN,
1216 .gpr[22] = LONG_MIN | (uint)INT_MIN,
1222 .mnemonic = "addc.",
1225 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1226 .flags = IGNORE_CCR,
1227 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1229 .gpr[21] = LONG_MIN,
1230 .gpr[22] = LONG_MIN,
1234 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1235 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1237 .gpr[21] = LONG_MIN,
1238 .gpr[22] = LONG_MAX,
1242 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1243 .flags = IGNORE_CCR,
1244 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1246 .gpr[21] = LONG_MAX,
1247 .gpr[22] = LONG_MAX,
1251 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1252 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1254 .gpr[21] = ULONG_MAX,
1255 .gpr[22] = ULONG_MAX,
1259 .descr = "RA = ULONG_MAX, RB = 0x1",
1260 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1262 .gpr[21] = ULONG_MAX,
1267 .descr = "RA = INT_MIN, RB = INT_MIN",
1268 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1275 .descr = "RA = INT_MIN, RB = INT_MAX",
1276 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1283 .descr = "RA = INT_MAX, RB = INT_MAX",
1284 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1291 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1292 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1294 .gpr[21] = UINT_MAX,
1295 .gpr[22] = UINT_MAX,
1299 .descr = "RA = UINT_MAX, RB = 0x1",
1300 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1302 .gpr[21] = UINT_MAX,
1307 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1308 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1310 .gpr[21] = LONG_MIN | (uint)INT_MIN,
1311 .gpr[22] = LONG_MIN | (uint)INT_MIN,
1317 .mnemonic = "divde",
1320 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1321 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1323 .gpr[21] = LONG_MIN,
1324 .gpr[22] = LONG_MIN,
1328 .descr = "RA = 1L, RB = 0",
1329 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1330 .flags = IGNORE_GPR(20),
1337 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1338 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1340 .gpr[21] = LONG_MIN,
1341 .gpr[22] = LONG_MAX,
1347 .mnemonic = "divde.",
1350 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1351 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1353 .gpr[21] = LONG_MIN,
1354 .gpr[22] = LONG_MIN,
1358 .descr = "RA = 1L, RB = 0",
1359 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1360 .flags = IGNORE_GPR(20),
1367 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1368 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1370 .gpr[21] = LONG_MIN,
1371 .gpr[22] = LONG_MAX,
1377 .mnemonic = "divdeu",
1380 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1381 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1382 .flags = IGNORE_GPR(20),
1384 .gpr[21] = LONG_MIN,
1385 .gpr[22] = LONG_MIN,
1389 .descr = "RA = 1L, RB = 0",
1390 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1391 .flags = IGNORE_GPR(20),
1398 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1399 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1401 .gpr[21] = LONG_MIN,
1402 .gpr[22] = LONG_MAX,
1406 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1407 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1409 .gpr[21] = LONG_MAX - 1,
1410 .gpr[22] = LONG_MAX,
1414 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1415 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1416 .flags = IGNORE_GPR(20),
1418 .gpr[21] = LONG_MIN + 1,
1419 .gpr[22] = LONG_MIN,
1425 .mnemonic = "divdeu.",
1428 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1429 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1430 .flags = IGNORE_GPR(20),
1432 .gpr[21] = LONG_MIN,
1433 .gpr[22] = LONG_MIN,
1437 .descr = "RA = 1L, RB = 0",
1438 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1439 .flags = IGNORE_GPR(20),
1446 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1447 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1449 .gpr[21] = LONG_MIN,
1450 .gpr[22] = LONG_MAX,
1454 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1455 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1457 .gpr[21] = LONG_MAX - 1,
1458 .gpr[22] = LONG_MAX,
1462 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1463 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1464 .flags = IGNORE_GPR(20),
1466 .gpr[21] = LONG_MIN + 1,
1467 .gpr[22] = LONG_MIN,
1473 .mnemonic = "paddi",
1474 .cpu_feature = CPU_FTR_ARCH_31,
1477 .descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
1478 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1481 .gpr[22] = LONG_MIN,
1485 .descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
1486 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1489 .gpr[22] = LONG_MIN,
1493 .descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
1494 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1497 .gpr[22] = LONG_MAX,
1501 .descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
1502 .instr = TEST_PADDI(21, 22, SI_UMAX, 0),
1505 .gpr[22] = ULONG_MAX,
1509 .descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
1510 .instr = TEST_PADDI(21, 22, 0x1, 0),
1513 .gpr[22] = ULONG_MAX,
1517 .descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
1518 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1525 .descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
1526 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1533 .descr = "RA = INT_MAX, SI = SI_MAX, R = 0",
1534 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1541 .descr = "RA = UINT_MAX, SI = 0x1, R = 0",
1542 .instr = TEST_PADDI(21, 22, 0x1, 0),
1545 .gpr[22] = UINT_MAX,
1549 .descr = "RA = UINT_MAX, SI = SI_MAX, R = 0",
1550 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1553 .gpr[22] = UINT_MAX,
1557 .descr = "RA is r0, SI = SI_MIN, R = 0",
1558 .instr = TEST_PADDI(21, 0, SI_MIN, 0),
1564 .descr = "RA = 0, SI = SI_MIN, R = 0",
1565 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1572 .descr = "RA is r0, SI = 0, R = 1",
1573 .instr = TEST_PADDI(21, 0, 0, 1),
1579 .descr = "RA is r0, SI = SI_MIN, R = 1",
1580 .instr = TEST_PADDI(21, 0, SI_MIN, 1),
1585 /* Invalid instruction form with R = 1 and RA != 0 */
1587 .descr = "RA = R22(0), SI = 0, R = 1",
1588 .instr = TEST_PADDI(21, 22, 0, 1),
1589 .flags = NEGATIVE_TEST,
1599 static int __init emulate_compute_instr(struct pt_regs *regs,
1604 struct instruction_op op;
1606 if (!regs || !ppc_inst_val(instr))
1609 /* This is not a return frame regs */
1610 regs->nip = patch_site_addr(&patch__exec_instr);
1612 analysed = analyse_instr(&op, regs, instr);
1613 if (analysed != 1 || GETTYPE(op.type) != COMPUTE) {
1616 pr_info("emulation failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1619 if (analysed == 1 && negative)
1620 pr_info("negative test failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1622 emulate_update_regs(regs, &op);
1626 static int __init execute_compute_instr(struct pt_regs *regs,
1629 extern int exec_instr(struct pt_regs *regs);
1631 if (!regs || !ppc_inst_val(instr))
1634 /* Patch the NOP with the actual instruction */
1635 patch_instruction_site(&patch__exec_instr, instr);
1636 if (exec_instr(regs)) {
1637 pr_info("execution failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1644 #define gpr_mismatch(gprn, exp, got) \
1645 pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n", \
1648 #define reg_mismatch(name, exp, got) \
1649 pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n", \
1652 static void __init run_tests_compute(void)
1654 unsigned long flags;
1655 struct compute_test *test;
1656 struct pt_regs *regs, exp, got;
1657 unsigned int i, j, k;
1659 bool ignore_gpr, ignore_xer, ignore_ccr, passed, rc, negative;
1661 for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
1662 test = &compute_tests[i];
1664 if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) {
1665 show_result(test->mnemonic, "SKIP (!CPU_FTR)");
1669 for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
1670 instr = test->subtests[j].instr;
1671 flags = test->subtests[j].flags;
1672 regs = &test->subtests[j].regs;
1673 negative = flags & NEGATIVE_TEST;
1674 ignore_xer = flags & IGNORE_XER;
1675 ignore_ccr = flags & IGNORE_CCR;
1678 memcpy(&exp, regs, sizeof(struct pt_regs));
1679 memcpy(&got, regs, sizeof(struct pt_regs));
1682 * Set a compatible MSR value explicitly to ensure
1683 * that XER and CR bits are updated appropriately
1685 exp.msr = MSR_KERNEL;
1686 got.msr = MSR_KERNEL;
1688 rc = emulate_compute_instr(&got, instr, negative) != 0;
1690 /* skip executing instruction */
1693 } else if (rc || execute_compute_instr(&exp, instr)) {
1698 /* Verify GPR values */
1699 for (k = 0; k < 32; k++) {
1700 ignore_gpr = flags & IGNORE_GPR(k);
1701 if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
1703 gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
1707 /* Verify LR value */
1708 if (exp.link != got.link) {
1710 reg_mismatch("LR", exp.link, got.link);
1713 /* Verify XER value */
1714 if (!ignore_xer && exp.xer != got.xer) {
1716 reg_mismatch("XER", exp.xer, got.xer);
1719 /* Verify CR value */
1720 if (!ignore_ccr && exp.ccr != got.ccr) {
1722 reg_mismatch("CR", exp.ccr, got.ccr);
1726 show_result_with_descr(test->mnemonic,
1727 test->subtests[j].descr,
1728 passed ? "PASS" : "FAIL");
1733 static int __init test_emulate_step(void)
1735 printk(KERN_INFO "Running instruction emulation self-tests ...\n");
1736 run_tests_load_store();
1737 run_tests_compute();
1741 late_initcall(test_emulate_step);