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 #define TEST_SETB(t, bfa) ppc_inst(PPC_INST_SETB | ___PPC_RT(t) | ___PPC_RA((bfa & 0x7) << 2))
59 static void __init init_pt_regs(struct pt_regs *regs)
61 static unsigned long msr;
62 static bool msr_cached;
64 memset(regs, 0, sizeof(struct pt_regs));
66 if (likely(msr_cached)) {
71 asm volatile("mfmsr %0" : "=r"(regs->msr));
81 static void __init show_result(char *mnemonic, char *result)
83 pr_info("%-14s : %s\n", mnemonic, result);
86 static void __init show_result_with_descr(char *mnemonic, char *descr,
89 pr_info("%-14s : %-50s %s\n", mnemonic, descr, result);
92 static void __init test_ld(void)
95 unsigned long a = 0x23;
99 regs.gpr[3] = (unsigned long) &a;
102 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LD(5, 3, 0)));
104 if (stepped == 1 && regs.gpr[5] == a)
105 show_result("ld", "PASS");
107 show_result("ld", "FAIL");
110 static void __init test_pld(void)
113 unsigned long a = 0x23;
116 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
117 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
122 regs.gpr[3] = (unsigned long)&a;
124 /* pld r5, 0(r3), 0 */
125 stepped = emulate_step(®s, TEST_PLD(5, 3, 0, 0));
127 if (stepped == 1 && regs.gpr[5] == a)
128 show_result("pld", "PASS");
130 show_result("pld", "FAIL");
133 static void __init test_lwz(void)
136 unsigned int a = 0x4545;
140 regs.gpr[3] = (unsigned long) &a;
143 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LWZ(5, 3, 0)));
145 if (stepped == 1 && regs.gpr[5] == a)
146 show_result("lwz", "PASS");
148 show_result("lwz", "FAIL");
151 static void __init test_plwz(void)
154 unsigned int a = 0x4545;
157 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
158 show_result("plwz", "SKIP (!CPU_FTR_ARCH_31)");
163 regs.gpr[3] = (unsigned long)&a;
165 /* plwz r5, 0(r3), 0 */
167 stepped = emulate_step(®s, TEST_PLWZ(5, 3, 0, 0));
169 if (stepped == 1 && regs.gpr[5] == a)
170 show_result("plwz", "PASS");
172 show_result("plwz", "FAIL");
175 static void __init test_lwzx(void)
178 unsigned int a[3] = {0x0, 0x0, 0x1234};
182 regs.gpr[3] = (unsigned long) a;
184 regs.gpr[5] = 0x8765;
186 /* lwzx r5, r3, r4 */
187 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LWZX(5, 3, 4)));
188 if (stepped == 1 && regs.gpr[5] == a[2])
189 show_result("lwzx", "PASS");
191 show_result("lwzx", "FAIL");
194 static void __init test_std(void)
197 unsigned long a = 0x1234;
201 regs.gpr[3] = (unsigned long) &a;
202 regs.gpr[5] = 0x5678;
205 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STD(5, 3, 0)));
206 if (stepped == 1 && regs.gpr[5] == a)
207 show_result("std", "PASS");
209 show_result("std", "FAIL");
212 static void __init test_pstd(void)
215 unsigned long a = 0x1234;
218 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
219 show_result("pstd", "SKIP (!CPU_FTR_ARCH_31)");
224 regs.gpr[3] = (unsigned long)&a;
225 regs.gpr[5] = 0x5678;
227 /* pstd r5, 0(r3), 0 */
228 stepped = emulate_step(®s, TEST_PSTD(5, 3, 0, 0));
229 if (stepped == 1 || regs.gpr[5] == a)
230 show_result("pstd", "PASS");
232 show_result("pstd", "FAIL");
235 static void __init test_ldarx_stdcx(void)
238 unsigned long a = 0x1234;
240 unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
243 asm volatile("mfcr %0" : "=r"(regs.ccr));
248 regs.gpr[3] = (unsigned long) &a;
250 regs.gpr[5] = 0x5678;
252 /* ldarx r5, r3, r4, 0 */
253 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LDARX(5, 3, 4, 0)));
256 * Don't touch 'a' here. Touching 'a' can do Load/store
257 * of 'a' which result in failure of subsequent stdcx.
258 * Instead, use hardcoded value for comparison.
260 if (stepped <= 0 || regs.gpr[5] != 0x1234) {
261 show_result("ldarx / stdcx.", "FAIL (ldarx)");
268 regs.gpr[5] = 0x9ABC;
270 /* stdcx. r5, r3, r4 */
271 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STDCX(5, 3, 4)));
274 * Two possible scenarios that indicates successful emulation
276 * 1. Reservation is active and store is performed. In this
277 * case cr0.eq bit will be set to 1.
278 * 2. Reservation is not active and store is not performed.
279 * In this case cr0.eq bit will be set to 0.
281 if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
282 || (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
283 show_result("ldarx / stdcx.", "PASS");
285 show_result("ldarx / stdcx.", "FAIL (stdcx.)");
288 #ifdef CONFIG_PPC_FPU
289 static void __init test_lfsx_stfsx(void)
307 regs.gpr[3] = (unsigned long) &c.a;
310 /* lfsx frt10, r3, r4 */
311 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LFSX(10, 3, 4)));
314 show_result("lfsx", "PASS");
316 show_result("lfsx", "FAIL");
323 /* stfsx frs10, r3, r4 */
324 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STFSX(10, 3, 4)));
326 if (stepped == 1 && c.b == cached_b)
327 show_result("stfsx", "PASS");
329 show_result("stfsx", "FAIL");
332 static void __init test_plfs_pstfs(void)
342 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
343 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
355 regs.gpr[3] = (unsigned long)&c.a;
357 /* plfs frt10, 0(r3), 0 */
358 stepped = emulate_step(®s, TEST_PLFS(10, 3, 0, 0));
361 show_result("plfs", "PASS");
363 show_result("plfs", "FAIL");
370 /* pstfs frs10, 0(r3), 0 */
371 stepped = emulate_step(®s, TEST_PSTFS(10, 3, 0, 0));
373 if (stepped == 1 && c.b == cached_b)
374 show_result("pstfs", "PASS");
376 show_result("pstfs", "FAIL");
379 static void __init test_lfdx_stfdx(void)
397 regs.gpr[3] = (unsigned long) &c.a;
400 /* lfdx frt10, r3, r4 */
401 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LFDX(10, 3, 4)));
404 show_result("lfdx", "PASS");
406 show_result("lfdx", "FAIL");
413 /* stfdx frs10, r3, r4 */
414 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STFDX(10, 3, 4)));
416 if (stepped == 1 && c.b == cached_b)
417 show_result("stfdx", "PASS");
419 show_result("stfdx", "FAIL");
422 static void __init test_plfd_pstfd(void)
432 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
433 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
445 regs.gpr[3] = (unsigned long)&c.a;
447 /* plfd frt10, 0(r3), 0 */
448 stepped = emulate_step(®s, TEST_PLFD(10, 3, 0, 0));
451 show_result("plfd", "PASS");
453 show_result("plfd", "FAIL");
460 /* pstfd frs10, 0(r3), 0 */
461 stepped = emulate_step(®s, TEST_PSTFD(10, 3, 0, 0));
463 if (stepped == 1 && c.b == cached_b)
464 show_result("pstfd", "PASS");
466 show_result("pstfd", "FAIL");
469 static void __init test_lfsx_stfsx(void)
471 show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
472 show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
475 static void __init test_plfs_pstfs(void)
477 show_result("plfs", "SKIP (CONFIG_PPC_FPU is not set)");
478 show_result("pstfs", "SKIP (CONFIG_PPC_FPU is not set)");
481 static void __init test_lfdx_stfdx(void)
483 show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
484 show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
487 static void __init test_plfd_pstfd(void)
489 show_result("plfd", "SKIP (CONFIG_PPC_FPU is not set)");
490 show_result("pstfd", "SKIP (CONFIG_PPC_FPU is not set)");
492 #endif /* CONFIG_PPC_FPU */
494 #ifdef CONFIG_ALTIVEC
495 static void __init test_lvx_stvx(void)
510 cached_b[0] = c.b[0] = 923745;
511 cached_b[1] = c.b[1] = 2139478;
512 cached_b[2] = c.b[2] = 9012;
513 cached_b[3] = c.b[3] = 982134;
515 regs.gpr[3] = (unsigned long) &c.a;
518 /* lvx vrt10, r3, r4 */
519 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LVX(10, 3, 4)));
522 show_result("lvx", "PASS");
524 show_result("lvx", "FAIL");
534 /* stvx vrs10, r3, r4 */
535 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STVX(10, 3, 4)));
537 if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
538 cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
539 show_result("stvx", "PASS");
541 show_result("stvx", "FAIL");
544 static void __init test_lvx_stvx(void)
546 show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
547 show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
549 #endif /* CONFIG_ALTIVEC */
552 static void __init test_lxvd2x_stxvd2x(void)
567 cached_b[0] = c.b[0] = 18233;
568 cached_b[1] = c.b[1] = 34863571;
569 cached_b[2] = c.b[2] = 834;
570 cached_b[3] = c.b[3] = 6138911;
572 regs.gpr[3] = (unsigned long) &c.a;
575 /* lxvd2x vsr39, r3, r4 */
576 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVD2X(39, R3, R4)));
578 if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
579 show_result("lxvd2x", "PASS");
581 if (!cpu_has_feature(CPU_FTR_VSX))
582 show_result("lxvd2x", "PASS (!CPU_FTR_VSX)");
584 show_result("lxvd2x", "FAIL");
595 /* stxvd2x vsr39, r3, r4 */
596 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVD2X(39, R3, R4)));
598 if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
599 cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
600 cpu_has_feature(CPU_FTR_VSX)) {
601 show_result("stxvd2x", "PASS");
603 if (!cpu_has_feature(CPU_FTR_VSX))
604 show_result("stxvd2x", "PASS (!CPU_FTR_VSX)");
606 show_result("stxvd2x", "FAIL");
610 static void __init test_lxvd2x_stxvd2x(void)
612 show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
613 show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
615 #endif /* CONFIG_VSX */
618 static void __init test_lxvp_stxvp(void)
628 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
629 show_result("lxvp", "SKIP (!CPU_FTR_ARCH_31)");
630 show_result("stxvp", "SKIP (!CPU_FTR_ARCH_31)");
638 cached_b[0] = c[0].b[0] = 18233;
639 cached_b[1] = c[0].b[1] = 34863571;
640 cached_b[2] = c[0].b[2] = 834;
641 cached_b[3] = c[0].b[3] = 6138911;
642 cached_b[4] = c[1].b[0] = 1234;
643 cached_b[5] = c[1].b[1] = 5678;
644 cached_b[6] = c[1].b[2] = 91011;
645 cached_b[7] = c[1].b[3] = 121314;
647 regs.gpr[4] = (unsigned long)&c[0].a;
652 * let TX=1 Tp=1 RA=4 DQ=0
654 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVP(34, 4, 0)));
656 if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
657 show_result("lxvp", "PASS");
659 if (!cpu_has_feature(CPU_FTR_VSX))
660 show_result("lxvp", "PASS (!CPU_FTR_VSX)");
662 show_result("lxvp", "FAIL");
667 c[0].b[0] = 21379463;
679 * let SX=1 Sp=1 RA=4 DQ=0
681 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVP(34, 4, 0)));
683 if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
684 cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
685 cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
686 cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
687 cpu_has_feature(CPU_FTR_VSX)) {
688 show_result("stxvp", "PASS");
690 if (!cpu_has_feature(CPU_FTR_VSX))
691 show_result("stxvp", "PASS (!CPU_FTR_VSX)");
693 show_result("stxvp", "FAIL");
697 static void __init test_lxvp_stxvp(void)
699 show_result("lxvp", "SKIP (CONFIG_VSX is not set)");
700 show_result("stxvp", "SKIP (CONFIG_VSX is not set)");
702 #endif /* CONFIG_VSX */
705 static void __init test_lxvpx_stxvpx(void)
715 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
716 show_result("lxvpx", "SKIP (!CPU_FTR_ARCH_31)");
717 show_result("stxvpx", "SKIP (!CPU_FTR_ARCH_31)");
725 cached_b[0] = c[0].b[0] = 18233;
726 cached_b[1] = c[0].b[1] = 34863571;
727 cached_b[2] = c[0].b[2] = 834;
728 cached_b[3] = c[0].b[3] = 6138911;
729 cached_b[4] = c[1].b[0] = 1234;
730 cached_b[5] = c[1].b[1] = 5678;
731 cached_b[6] = c[1].b[2] = 91011;
732 cached_b[7] = c[1].b[3] = 121314;
734 regs.gpr[3] = (unsigned long)&c[0].a;
740 * let TX=1 Tp=1 RA=3 RB=4
742 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVPX(34, 3, 4)));
744 if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
745 show_result("lxvpx", "PASS");
747 if (!cpu_has_feature(CPU_FTR_VSX))
748 show_result("lxvpx", "PASS (!CPU_FTR_VSX)");
750 show_result("lxvpx", "FAIL");
755 c[0].b[0] = 21379463;
767 * let SX=1 Sp=1 RA=3 RB=4
769 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVPX(34, 3, 4)));
771 if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
772 cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
773 cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
774 cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
775 cpu_has_feature(CPU_FTR_VSX)) {
776 show_result("stxvpx", "PASS");
778 if (!cpu_has_feature(CPU_FTR_VSX))
779 show_result("stxvpx", "PASS (!CPU_FTR_VSX)");
781 show_result("stxvpx", "FAIL");
785 static void __init test_lxvpx_stxvpx(void)
787 show_result("lxvpx", "SKIP (CONFIG_VSX is not set)");
788 show_result("stxvpx", "SKIP (CONFIG_VSX is not set)");
790 #endif /* CONFIG_VSX */
793 static void __init test_plxvp_pstxvp(void)
804 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
805 show_result("plxvp", "SKIP (!CPU_FTR_ARCH_31)");
806 show_result("pstxvp", "SKIP (!CPU_FTR_ARCH_31)");
812 cached_b[0] = c[0].b[0] = 18233;
813 cached_b[1] = c[0].b[1] = 34863571;
814 cached_b[2] = c[0].b[2] = 834;
815 cached_b[3] = c[0].b[3] = 6138911;
816 cached_b[4] = c[1].b[0] = 1234;
817 cached_b[5] = c[1].b[1] = 5678;
818 cached_b[6] = c[1].b[2] = 91011;
819 cached_b[7] = c[1].b[3] = 121314;
822 regs.gpr[3] = (unsigned long)&c[0].a;
827 * let RA=3 R=0 D=d0||d1=0 R=0 Tp=1 TX=1
829 instr = ppc_inst_prefix(PPC_RAW_PLXVP_P(34, 0, 3, 0), PPC_RAW_PLXVP_S(34, 0, 3, 0));
831 stepped = emulate_step(®s, instr);
832 if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
833 show_result("plxvp", "PASS");
835 if (!cpu_has_feature(CPU_FTR_VSX))
836 show_result("plxvp", "PASS (!CPU_FTR_VSX)");
838 show_result("plxvp", "FAIL");
843 c[0].b[0] = 21379463;
855 * let RA=3 D=d0||d1=0 R=0 Sp=1 SX=1
857 instr = ppc_inst_prefix(PPC_RAW_PSTXVP_P(34, 0, 3, 0), PPC_RAW_PSTXVP_S(34, 0, 3, 0));
859 stepped = emulate_step(®s, instr);
861 if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
862 cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
863 cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
864 cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
865 cpu_has_feature(CPU_FTR_VSX)) {
866 show_result("pstxvp", "PASS");
868 if (!cpu_has_feature(CPU_FTR_VSX))
869 show_result("pstxvp", "PASS (!CPU_FTR_VSX)");
871 show_result("pstxvp", "FAIL");
875 static void __init test_plxvp_pstxvp(void)
877 show_result("plxvp", "SKIP (CONFIG_VSX is not set)");
878 show_result("pstxvp", "SKIP (CONFIG_VSX is not set)");
880 #endif /* CONFIG_VSX */
882 static void __init run_tests_load_store(void)
897 test_lxvd2x_stxvd2x();
903 struct compute_test {
905 unsigned long cpu_feature;
911 } subtests[MAX_SUBTESTS + 1];
914 /* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
915 #define SI_MIN BIT(33)
916 #define SI_MAX (BIT(33) - 1)
917 #define SI_UMAX (BIT(34) - 1)
919 static struct compute_test compute_tests[] = {
924 .descr = "R0 = LONG_MAX",
925 .instr = ppc_inst(PPC_RAW_NOP()),
934 .cpu_feature = CPU_FTR_ARCH_300,
937 .descr = "BFA = 1, CR = GT",
938 .instr = TEST_SETB(20, 1),
944 .descr = "BFA = 4, CR = LT",
945 .instr = TEST_SETB(20, 4),
951 .descr = "BFA = 5, CR = EQ",
952 .instr = TEST_SETB(20, 5),
963 .descr = "RA = LONG_MIN, RB = LONG_MIN",
964 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
971 .descr = "RA = LONG_MIN, RB = LONG_MAX",
972 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
979 .descr = "RA = LONG_MAX, RB = LONG_MAX",
980 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
987 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
988 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
990 .gpr[21] = ULONG_MAX,
991 .gpr[22] = ULONG_MAX,
995 .descr = "RA = ULONG_MAX, RB = 0x1",
996 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
998 .gpr[21] = ULONG_MAX,
1003 .descr = "RA = INT_MIN, RB = INT_MIN",
1004 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1011 .descr = "RA = INT_MIN, RB = INT_MAX",
1012 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1019 .descr = "RA = INT_MAX, RB = INT_MAX",
1020 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1027 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1028 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1030 .gpr[21] = UINT_MAX,
1031 .gpr[22] = UINT_MAX,
1035 .descr = "RA = UINT_MAX, RB = 0x1",
1036 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1038 .gpr[21] = UINT_MAX,
1048 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1049 .flags = IGNORE_CCR,
1050 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1052 .gpr[21] = LONG_MIN,
1053 .gpr[22] = LONG_MIN,
1057 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1058 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1060 .gpr[21] = LONG_MIN,
1061 .gpr[22] = LONG_MAX,
1065 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1066 .flags = IGNORE_CCR,
1067 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1069 .gpr[21] = LONG_MAX,
1070 .gpr[22] = LONG_MAX,
1074 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1075 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1077 .gpr[21] = ULONG_MAX,
1078 .gpr[22] = ULONG_MAX,
1082 .descr = "RA = ULONG_MAX, RB = 0x1",
1083 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1085 .gpr[21] = ULONG_MAX,
1090 .descr = "RA = INT_MIN, RB = INT_MIN",
1091 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1098 .descr = "RA = INT_MIN, RB = INT_MAX",
1099 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1106 .descr = "RA = INT_MAX, RB = INT_MAX",
1107 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1114 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1115 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1117 .gpr[21] = UINT_MAX,
1118 .gpr[22] = UINT_MAX,
1122 .descr = "RA = UINT_MAX, RB = 0x1",
1123 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1125 .gpr[21] = UINT_MAX,
1135 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1136 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1138 .gpr[21] = LONG_MIN,
1139 .gpr[22] = LONG_MIN,
1143 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1144 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1146 .gpr[21] = LONG_MIN,
1147 .gpr[22] = LONG_MAX,
1151 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1152 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1154 .gpr[21] = LONG_MAX,
1155 .gpr[22] = LONG_MAX,
1159 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1160 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1162 .gpr[21] = ULONG_MAX,
1163 .gpr[22] = ULONG_MAX,
1167 .descr = "RA = ULONG_MAX, RB = 0x1",
1168 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1170 .gpr[21] = ULONG_MAX,
1175 .descr = "RA = INT_MIN, RB = INT_MIN",
1176 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1183 .descr = "RA = INT_MIN, RB = INT_MAX",
1184 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1191 .descr = "RA = INT_MAX, RB = INT_MAX",
1192 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1199 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1200 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1202 .gpr[21] = UINT_MAX,
1203 .gpr[22] = UINT_MAX,
1207 .descr = "RA = UINT_MAX, RB = 0x1",
1208 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1210 .gpr[21] = UINT_MAX,
1215 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1216 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1218 .gpr[21] = LONG_MIN | (uint)INT_MIN,
1219 .gpr[22] = LONG_MIN | (uint)INT_MIN,
1225 .mnemonic = "addc.",
1228 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1229 .flags = IGNORE_CCR,
1230 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1232 .gpr[21] = LONG_MIN,
1233 .gpr[22] = LONG_MIN,
1237 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1238 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1240 .gpr[21] = LONG_MIN,
1241 .gpr[22] = LONG_MAX,
1245 .descr = "RA = LONG_MAX, RB = LONG_MAX",
1246 .flags = IGNORE_CCR,
1247 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1249 .gpr[21] = LONG_MAX,
1250 .gpr[22] = LONG_MAX,
1254 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1255 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1257 .gpr[21] = ULONG_MAX,
1258 .gpr[22] = ULONG_MAX,
1262 .descr = "RA = ULONG_MAX, RB = 0x1",
1263 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1265 .gpr[21] = ULONG_MAX,
1270 .descr = "RA = INT_MIN, RB = INT_MIN",
1271 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1278 .descr = "RA = INT_MIN, RB = INT_MAX",
1279 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1286 .descr = "RA = INT_MAX, RB = INT_MAX",
1287 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1294 .descr = "RA = UINT_MAX, RB = UINT_MAX",
1295 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1297 .gpr[21] = UINT_MAX,
1298 .gpr[22] = UINT_MAX,
1302 .descr = "RA = UINT_MAX, RB = 0x1",
1303 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1305 .gpr[21] = UINT_MAX,
1310 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1311 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1313 .gpr[21] = LONG_MIN | (uint)INT_MIN,
1314 .gpr[22] = LONG_MIN | (uint)INT_MIN,
1320 .mnemonic = "divde",
1323 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1324 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1326 .gpr[21] = LONG_MIN,
1327 .gpr[22] = LONG_MIN,
1331 .descr = "RA = 1L, RB = 0",
1332 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1333 .flags = IGNORE_GPR(20),
1340 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1341 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1343 .gpr[21] = LONG_MIN,
1344 .gpr[22] = LONG_MAX,
1350 .mnemonic = "divde.",
1353 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1354 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1356 .gpr[21] = LONG_MIN,
1357 .gpr[22] = LONG_MIN,
1361 .descr = "RA = 1L, RB = 0",
1362 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1363 .flags = IGNORE_GPR(20),
1370 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1371 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1373 .gpr[21] = LONG_MIN,
1374 .gpr[22] = LONG_MAX,
1380 .mnemonic = "divdeu",
1383 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1384 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1385 .flags = IGNORE_GPR(20),
1387 .gpr[21] = LONG_MIN,
1388 .gpr[22] = LONG_MIN,
1392 .descr = "RA = 1L, RB = 0",
1393 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1394 .flags = IGNORE_GPR(20),
1401 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1402 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1404 .gpr[21] = LONG_MIN,
1405 .gpr[22] = LONG_MAX,
1409 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1410 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1412 .gpr[21] = LONG_MAX - 1,
1413 .gpr[22] = LONG_MAX,
1417 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1418 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1419 .flags = IGNORE_GPR(20),
1421 .gpr[21] = LONG_MIN + 1,
1422 .gpr[22] = LONG_MIN,
1428 .mnemonic = "divdeu.",
1431 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1432 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1433 .flags = IGNORE_GPR(20),
1435 .gpr[21] = LONG_MIN,
1436 .gpr[22] = LONG_MIN,
1440 .descr = "RA = 1L, RB = 0",
1441 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1442 .flags = IGNORE_GPR(20),
1449 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1450 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1452 .gpr[21] = LONG_MIN,
1453 .gpr[22] = LONG_MAX,
1457 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1458 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1460 .gpr[21] = LONG_MAX - 1,
1461 .gpr[22] = LONG_MAX,
1465 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1466 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1467 .flags = IGNORE_GPR(20),
1469 .gpr[21] = LONG_MIN + 1,
1470 .gpr[22] = LONG_MIN,
1476 .mnemonic = "paddi",
1477 .cpu_feature = CPU_FTR_ARCH_31,
1480 .descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
1481 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1484 .gpr[22] = LONG_MIN,
1488 .descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
1489 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1492 .gpr[22] = LONG_MIN,
1496 .descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
1497 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1500 .gpr[22] = LONG_MAX,
1504 .descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
1505 .instr = TEST_PADDI(21, 22, SI_UMAX, 0),
1508 .gpr[22] = ULONG_MAX,
1512 .descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
1513 .instr = TEST_PADDI(21, 22, 0x1, 0),
1516 .gpr[22] = ULONG_MAX,
1520 .descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
1521 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1528 .descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
1529 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1536 .descr = "RA = INT_MAX, SI = SI_MAX, R = 0",
1537 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1544 .descr = "RA = UINT_MAX, SI = 0x1, R = 0",
1545 .instr = TEST_PADDI(21, 22, 0x1, 0),
1548 .gpr[22] = UINT_MAX,
1552 .descr = "RA = UINT_MAX, SI = SI_MAX, R = 0",
1553 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1556 .gpr[22] = UINT_MAX,
1560 .descr = "RA is r0, SI = SI_MIN, R = 0",
1561 .instr = TEST_PADDI(21, 0, SI_MIN, 0),
1567 .descr = "RA = 0, SI = SI_MIN, R = 0",
1568 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1575 .descr = "RA is r0, SI = 0, R = 1",
1576 .instr = TEST_PADDI(21, 0, 0, 1),
1582 .descr = "RA is r0, SI = SI_MIN, R = 1",
1583 .instr = TEST_PADDI(21, 0, SI_MIN, 1),
1588 /* Invalid instruction form with R = 1 and RA != 0 */
1590 .descr = "RA = R22(0), SI = 0, R = 1",
1591 .instr = TEST_PADDI(21, 22, 0, 1),
1592 .flags = NEGATIVE_TEST,
1602 static int __init emulate_compute_instr(struct pt_regs *regs,
1607 struct instruction_op op;
1609 if (!regs || !ppc_inst_val(instr))
1612 /* This is not a return frame regs */
1613 regs->nip = patch_site_addr(&patch__exec_instr);
1615 analysed = analyse_instr(&op, regs, instr);
1616 if (analysed != 1 || GETTYPE(op.type) != COMPUTE) {
1619 pr_info("emulation failed, instruction = %s\n", ppc_inst_as_str(instr));
1622 if (analysed == 1 && negative)
1623 pr_info("negative test failed, instruction = %s\n", ppc_inst_as_str(instr));
1625 emulate_update_regs(regs, &op);
1629 static int __init execute_compute_instr(struct pt_regs *regs,
1632 extern int exec_instr(struct pt_regs *regs);
1634 if (!regs || !ppc_inst_val(instr))
1637 /* Patch the NOP with the actual instruction */
1638 patch_instruction_site(&patch__exec_instr, instr);
1639 if (exec_instr(regs)) {
1640 pr_info("execution failed, instruction = %s\n", ppc_inst_as_str(instr));
1647 #define gpr_mismatch(gprn, exp, got) \
1648 pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n", \
1651 #define reg_mismatch(name, exp, got) \
1652 pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n", \
1655 static void __init run_tests_compute(void)
1657 unsigned long flags;
1658 struct compute_test *test;
1659 struct pt_regs *regs, exp, got;
1660 unsigned int i, j, k;
1662 bool ignore_gpr, ignore_xer, ignore_ccr, passed, rc, negative;
1664 for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
1665 test = &compute_tests[i];
1667 if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) {
1668 show_result(test->mnemonic, "SKIP (!CPU_FTR)");
1672 for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
1673 instr = test->subtests[j].instr;
1674 flags = test->subtests[j].flags;
1675 regs = &test->subtests[j].regs;
1676 negative = flags & NEGATIVE_TEST;
1677 ignore_xer = flags & IGNORE_XER;
1678 ignore_ccr = flags & IGNORE_CCR;
1681 memcpy(&exp, regs, sizeof(struct pt_regs));
1682 memcpy(&got, regs, sizeof(struct pt_regs));
1685 * Set a compatible MSR value explicitly to ensure
1686 * that XER and CR bits are updated appropriately
1688 exp.msr = MSR_KERNEL;
1689 got.msr = MSR_KERNEL;
1691 rc = emulate_compute_instr(&got, instr, negative) != 0;
1693 /* skip executing instruction */
1696 } else if (rc || execute_compute_instr(&exp, instr)) {
1701 /* Verify GPR values */
1702 for (k = 0; k < 32; k++) {
1703 ignore_gpr = flags & IGNORE_GPR(k);
1704 if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
1706 gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
1710 /* Verify LR value */
1711 if (exp.link != got.link) {
1713 reg_mismatch("LR", exp.link, got.link);
1716 /* Verify XER value */
1717 if (!ignore_xer && exp.xer != got.xer) {
1719 reg_mismatch("XER", exp.xer, got.xer);
1722 /* Verify CR value */
1723 if (!ignore_ccr && exp.ccr != got.ccr) {
1725 reg_mismatch("CR", exp.ccr, got.ccr);
1729 show_result_with_descr(test->mnemonic,
1730 test->subtests[j].descr,
1731 passed ? "PASS" : "FAIL");
1736 static int __init test_emulate_step(void)
1738 printk(KERN_INFO "Running instruction emulation self-tests ...\n");
1739 run_tests_load_store();
1740 run_tests_compute();
1744 late_initcall(test_emulate_step);