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))
57 static void __init init_pt_regs(struct pt_regs *regs)
59 static unsigned long msr;
60 static bool msr_cached;
62 memset(regs, 0, sizeof(struct pt_regs));
64 if (likely(msr_cached)) {
69 asm volatile("mfmsr %0" : "=r"(regs->msr));
79 static void __init show_result(char *mnemonic, char *result)
81 pr_info("%-14s : %s\n", mnemonic, result);
84 static void __init show_result_with_descr(char *mnemonic, char *descr,
87 pr_info("%-14s : %-50s %s\n", mnemonic, descr, result);
90 static void __init test_ld(void)
93 unsigned long a = 0x23;
97 regs.gpr[3] = (unsigned long) &a;
100 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LD(5, 3, 0)));
102 if (stepped == 1 && regs.gpr[5] == a)
103 show_result("ld", "PASS");
105 show_result("ld", "FAIL");
108 static void __init test_pld(void)
111 unsigned long a = 0x23;
114 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
115 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
120 regs.gpr[3] = (unsigned long)&a;
122 /* pld r5, 0(r3), 0 */
123 stepped = emulate_step(®s, TEST_PLD(5, 3, 0, 0));
125 if (stepped == 1 && regs.gpr[5] == a)
126 show_result("pld", "PASS");
128 show_result("pld", "FAIL");
131 static void __init test_lwz(void)
134 unsigned int a = 0x4545;
138 regs.gpr[3] = (unsigned long) &a;
141 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LWZ(5, 3, 0)));
143 if (stepped == 1 && regs.gpr[5] == a)
144 show_result("lwz", "PASS");
146 show_result("lwz", "FAIL");
149 static void __init test_plwz(void)
152 unsigned int a = 0x4545;
155 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
156 show_result("plwz", "SKIP (!CPU_FTR_ARCH_31)");
161 regs.gpr[3] = (unsigned long)&a;
163 /* plwz r5, 0(r3), 0 */
165 stepped = emulate_step(®s, TEST_PLWZ(5, 3, 0, 0));
167 if (stepped == 1 && regs.gpr[5] == a)
168 show_result("plwz", "PASS");
170 show_result("plwz", "FAIL");
173 static void __init test_lwzx(void)
176 unsigned int a[3] = {0x0, 0x0, 0x1234};
180 regs.gpr[3] = (unsigned long) a;
182 regs.gpr[5] = 0x8765;
184 /* lwzx r5, r3, r4 */
185 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LWZX(5, 3, 4)));
186 if (stepped == 1 && regs.gpr[5] == a[2])
187 show_result("lwzx", "PASS");
189 show_result("lwzx", "FAIL");
192 static void __init test_std(void)
195 unsigned long a = 0x1234;
199 regs.gpr[3] = (unsigned long) &a;
200 regs.gpr[5] = 0x5678;
203 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STD(5, 3, 0)));
204 if (stepped == 1 && regs.gpr[5] == a)
205 show_result("std", "PASS");
207 show_result("std", "FAIL");
210 static void __init test_pstd(void)
213 unsigned long a = 0x1234;
216 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
217 show_result("pstd", "SKIP (!CPU_FTR_ARCH_31)");
222 regs.gpr[3] = (unsigned long)&a;
223 regs.gpr[5] = 0x5678;
225 /* pstd r5, 0(r3), 0 */
226 stepped = emulate_step(®s, TEST_PSTD(5, 3, 0, 0));
227 if (stepped == 1 || regs.gpr[5] == a)
228 show_result("pstd", "PASS");
230 show_result("pstd", "FAIL");
233 static void __init test_ldarx_stdcx(void)
236 unsigned long a = 0x1234;
238 unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
241 asm volatile("mfcr %0" : "=r"(regs.ccr));
246 regs.gpr[3] = (unsigned long) &a;
248 regs.gpr[5] = 0x5678;
250 /* ldarx r5, r3, r4, 0 */
251 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LDARX(5, 3, 4, 0)));
254 * Don't touch 'a' here. Touching 'a' can do Load/store
255 * of 'a' which result in failure of subsequent stdcx.
256 * Instead, use hardcoded value for comparison.
258 if (stepped <= 0 || regs.gpr[5] != 0x1234) {
259 show_result("ldarx / stdcx.", "FAIL (ldarx)");
266 regs.gpr[5] = 0x9ABC;
268 /* stdcx. r5, r3, r4 */
269 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STDCX(5, 3, 4)));
272 * Two possible scenarios that indicates successful emulation
274 * 1. Reservation is active and store is performed. In this
275 * case cr0.eq bit will be set to 1.
276 * 2. Reservation is not active and store is not performed.
277 * In this case cr0.eq bit will be set to 0.
279 if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
280 || (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
281 show_result("ldarx / stdcx.", "PASS");
283 show_result("ldarx / stdcx.", "FAIL (stdcx.)");
286 #ifdef CONFIG_PPC_FPU
287 static void __init test_lfsx_stfsx(void)
305 regs.gpr[3] = (unsigned long) &c.a;
308 /* lfsx frt10, r3, r4 */
309 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LFSX(10, 3, 4)));
312 show_result("lfsx", "PASS");
314 show_result("lfsx", "FAIL");
321 /* stfsx frs10, r3, r4 */
322 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STFSX(10, 3, 4)));
324 if (stepped == 1 && c.b == cached_b)
325 show_result("stfsx", "PASS");
327 show_result("stfsx", "FAIL");
330 static void __init test_plfs_pstfs(void)
340 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
341 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
353 regs.gpr[3] = (unsigned long)&c.a;
355 /* plfs frt10, 0(r3), 0 */
356 stepped = emulate_step(®s, TEST_PLFS(10, 3, 0, 0));
359 show_result("plfs", "PASS");
361 show_result("plfs", "FAIL");
368 /* pstfs frs10, 0(r3), 0 */
369 stepped = emulate_step(®s, TEST_PSTFS(10, 3, 0, 0));
371 if (stepped == 1 && c.b == cached_b)
372 show_result("pstfs", "PASS");
374 show_result("pstfs", "FAIL");
377 static void __init test_lfdx_stfdx(void)
395 regs.gpr[3] = (unsigned long) &c.a;
398 /* lfdx frt10, r3, r4 */
399 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LFDX(10, 3, 4)));
402 show_result("lfdx", "PASS");
404 show_result("lfdx", "FAIL");
411 /* stfdx frs10, r3, r4 */
412 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STFDX(10, 3, 4)));
414 if (stepped == 1 && c.b == cached_b)
415 show_result("stfdx", "PASS");
417 show_result("stfdx", "FAIL");
420 static void __init test_plfd_pstfd(void)
430 if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
431 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
443 regs.gpr[3] = (unsigned long)&c.a;
445 /* plfd frt10, 0(r3), 0 */
446 stepped = emulate_step(®s, TEST_PLFD(10, 3, 0, 0));
449 show_result("plfd", "PASS");
451 show_result("plfd", "FAIL");
458 /* pstfd frs10, 0(r3), 0 */
459 stepped = emulate_step(®s, TEST_PSTFD(10, 3, 0, 0));
461 if (stepped == 1 && c.b == cached_b)
462 show_result("pstfd", "PASS");
464 show_result("pstfd", "FAIL");
467 static void __init test_lfsx_stfsx(void)
469 show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
470 show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
473 static void __init test_plfs_pstfs(void)
475 show_result("plfs", "SKIP (CONFIG_PPC_FPU is not set)");
476 show_result("pstfs", "SKIP (CONFIG_PPC_FPU is not set)");
479 static void __init test_lfdx_stfdx(void)
481 show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
482 show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
485 static void __init test_plfd_pstfd(void)
487 show_result("plfd", "SKIP (CONFIG_PPC_FPU is not set)");
488 show_result("pstfd", "SKIP (CONFIG_PPC_FPU is not set)");
490 #endif /* CONFIG_PPC_FPU */
492 #ifdef CONFIG_ALTIVEC
493 static void __init test_lvx_stvx(void)
508 cached_b[0] = c.b[0] = 923745;
509 cached_b[1] = c.b[1] = 2139478;
510 cached_b[2] = c.b[2] = 9012;
511 cached_b[3] = c.b[3] = 982134;
513 regs.gpr[3] = (unsigned long) &c.a;
516 /* lvx vrt10, r3, r4 */
517 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LVX(10, 3, 4)));
520 show_result("lvx", "PASS");
522 show_result("lvx", "FAIL");
532 /* stvx vrs10, r3, r4 */
533 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STVX(10, 3, 4)));
535 if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
536 cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
537 show_result("stvx", "PASS");
539 show_result("stvx", "FAIL");
542 static void __init test_lvx_stvx(void)
544 show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
545 show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
547 #endif /* CONFIG_ALTIVEC */
550 static void __init test_lxvd2x_stxvd2x(void)
565 cached_b[0] = c.b[0] = 18233;
566 cached_b[1] = c.b[1] = 34863571;
567 cached_b[2] = c.b[2] = 834;
568 cached_b[3] = c.b[3] = 6138911;
570 regs.gpr[3] = (unsigned long) &c.a;
573 /* lxvd2x vsr39, r3, r4 */
574 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVD2X(39, R3, R4)));
576 if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
577 show_result("lxvd2x", "PASS");
579 if (!cpu_has_feature(CPU_FTR_VSX))
580 show_result("lxvd2x", "PASS (!CPU_FTR_VSX)");
582 show_result("lxvd2x", "FAIL");
593 /* stxvd2x vsr39, r3, r4 */
594 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVD2X(39, R3, R4)));
596 if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
597 cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
598 cpu_has_feature(CPU_FTR_VSX)) {
599 show_result("stxvd2x", "PASS");
601 if (!cpu_has_feature(CPU_FTR_VSX))
602 show_result("stxvd2x", "PASS (!CPU_FTR_VSX)");
604 show_result("stxvd2x", "FAIL");
608 static void __init test_lxvd2x_stxvd2x(void)
610 show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
611 show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
613 #endif /* CONFIG_VSX */
615 static void __init run_tests_load_store(void)
630 test_lxvd2x_stxvd2x();
633 struct compute_test {
635 unsigned long cpu_feature;
639 struct ppc_inst instr;
641 } subtests[MAX_SUBTESTS + 1];
644 /* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
645 #define SI_MIN BIT(33)
646 #define SI_MAX (BIT(33) - 1)
647 #define SI_UMAX (BIT(34) - 1)
649 static struct compute_test compute_tests[] = {
654 .descr = "R0 = LONG_MAX",
655 .instr = ppc_inst(PPC_INST_NOP),
666 .descr = "RA = LONG_MIN, RB = LONG_MIN",
667 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
674 .descr = "RA = LONG_MIN, RB = LONG_MAX",
675 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
682 .descr = "RA = LONG_MAX, RB = LONG_MAX",
683 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
690 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
691 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
693 .gpr[21] = ULONG_MAX,
694 .gpr[22] = ULONG_MAX,
698 .descr = "RA = ULONG_MAX, RB = 0x1",
699 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
701 .gpr[21] = ULONG_MAX,
706 .descr = "RA = INT_MIN, RB = INT_MIN",
707 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
714 .descr = "RA = INT_MIN, RB = INT_MAX",
715 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
722 .descr = "RA = INT_MAX, RB = INT_MAX",
723 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
730 .descr = "RA = UINT_MAX, RB = UINT_MAX",
731 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
738 .descr = "RA = UINT_MAX, RB = 0x1",
739 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
751 .descr = "RA = LONG_MIN, RB = LONG_MIN",
753 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
760 .descr = "RA = LONG_MIN, RB = LONG_MAX",
761 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
768 .descr = "RA = LONG_MAX, RB = LONG_MAX",
770 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
777 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
778 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
780 .gpr[21] = ULONG_MAX,
781 .gpr[22] = ULONG_MAX,
785 .descr = "RA = ULONG_MAX, RB = 0x1",
786 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
788 .gpr[21] = ULONG_MAX,
793 .descr = "RA = INT_MIN, RB = INT_MIN",
794 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
801 .descr = "RA = INT_MIN, RB = INT_MAX",
802 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
809 .descr = "RA = INT_MAX, RB = INT_MAX",
810 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
817 .descr = "RA = UINT_MAX, RB = UINT_MAX",
818 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
825 .descr = "RA = UINT_MAX, RB = 0x1",
826 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
838 .descr = "RA = LONG_MIN, RB = LONG_MIN",
839 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
846 .descr = "RA = LONG_MIN, RB = LONG_MAX",
847 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
854 .descr = "RA = LONG_MAX, RB = LONG_MAX",
855 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
862 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
863 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
865 .gpr[21] = ULONG_MAX,
866 .gpr[22] = ULONG_MAX,
870 .descr = "RA = ULONG_MAX, RB = 0x1",
871 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
873 .gpr[21] = ULONG_MAX,
878 .descr = "RA = INT_MIN, RB = INT_MIN",
879 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
886 .descr = "RA = INT_MIN, RB = INT_MAX",
887 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
894 .descr = "RA = INT_MAX, RB = INT_MAX",
895 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
902 .descr = "RA = UINT_MAX, RB = UINT_MAX",
903 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
910 .descr = "RA = UINT_MAX, RB = 0x1",
911 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
918 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
919 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
921 .gpr[21] = LONG_MIN | (uint)INT_MIN,
922 .gpr[22] = LONG_MIN | (uint)INT_MIN,
931 .descr = "RA = LONG_MIN, RB = LONG_MIN",
933 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
940 .descr = "RA = LONG_MIN, RB = LONG_MAX",
941 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
948 .descr = "RA = LONG_MAX, RB = LONG_MAX",
950 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
957 .descr = "RA = ULONG_MAX, RB = ULONG_MAX",
958 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
960 .gpr[21] = ULONG_MAX,
961 .gpr[22] = ULONG_MAX,
965 .descr = "RA = ULONG_MAX, RB = 0x1",
966 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
968 .gpr[21] = ULONG_MAX,
973 .descr = "RA = INT_MIN, RB = INT_MIN",
974 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
981 .descr = "RA = INT_MIN, RB = INT_MAX",
982 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
989 .descr = "RA = INT_MAX, RB = INT_MAX",
990 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
997 .descr = "RA = UINT_MAX, RB = UINT_MAX",
998 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1000 .gpr[21] = UINT_MAX,
1001 .gpr[22] = UINT_MAX,
1005 .descr = "RA = UINT_MAX, RB = 0x1",
1006 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1008 .gpr[21] = UINT_MAX,
1013 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1014 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1016 .gpr[21] = LONG_MIN | (uint)INT_MIN,
1017 .gpr[22] = LONG_MIN | (uint)INT_MIN,
1023 .mnemonic = "divde",
1026 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1027 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1029 .gpr[21] = LONG_MIN,
1030 .gpr[22] = LONG_MIN,
1034 .descr = "RA = 1L, RB = 0",
1035 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1036 .flags = IGNORE_GPR(20),
1043 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1044 .instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1046 .gpr[21] = LONG_MIN,
1047 .gpr[22] = LONG_MAX,
1053 .mnemonic = "divde.",
1056 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1057 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1059 .gpr[21] = LONG_MIN,
1060 .gpr[22] = LONG_MIN,
1064 .descr = "RA = 1L, RB = 0",
1065 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1066 .flags = IGNORE_GPR(20),
1073 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1074 .instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1076 .gpr[21] = LONG_MIN,
1077 .gpr[22] = LONG_MAX,
1083 .mnemonic = "divdeu",
1086 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1087 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1088 .flags = IGNORE_GPR(20),
1090 .gpr[21] = LONG_MIN,
1091 .gpr[22] = LONG_MIN,
1095 .descr = "RA = 1L, RB = 0",
1096 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1097 .flags = IGNORE_GPR(20),
1104 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1105 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1107 .gpr[21] = LONG_MIN,
1108 .gpr[22] = LONG_MAX,
1112 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1113 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1115 .gpr[21] = LONG_MAX - 1,
1116 .gpr[22] = LONG_MAX,
1120 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1121 .instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1122 .flags = IGNORE_GPR(20),
1124 .gpr[21] = LONG_MIN + 1,
1125 .gpr[22] = LONG_MIN,
1131 .mnemonic = "divdeu.",
1134 .descr = "RA = LONG_MIN, RB = LONG_MIN",
1135 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1136 .flags = IGNORE_GPR(20),
1138 .gpr[21] = LONG_MIN,
1139 .gpr[22] = LONG_MIN,
1143 .descr = "RA = 1L, RB = 0",
1144 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1145 .flags = IGNORE_GPR(20),
1152 .descr = "RA = LONG_MIN, RB = LONG_MAX",
1153 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1155 .gpr[21] = LONG_MIN,
1156 .gpr[22] = LONG_MAX,
1160 .descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1161 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1163 .gpr[21] = LONG_MAX - 1,
1164 .gpr[22] = LONG_MAX,
1168 .descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1169 .instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1170 .flags = IGNORE_GPR(20),
1172 .gpr[21] = LONG_MIN + 1,
1173 .gpr[22] = LONG_MIN,
1179 .mnemonic = "paddi",
1180 .cpu_feature = CPU_FTR_ARCH_31,
1183 .descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
1184 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1187 .gpr[22] = LONG_MIN,
1191 .descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
1192 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1195 .gpr[22] = LONG_MIN,
1199 .descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
1200 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1203 .gpr[22] = LONG_MAX,
1207 .descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
1208 .instr = TEST_PADDI(21, 22, SI_UMAX, 0),
1211 .gpr[22] = ULONG_MAX,
1215 .descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
1216 .instr = TEST_PADDI(21, 22, 0x1, 0),
1219 .gpr[22] = ULONG_MAX,
1223 .descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
1224 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1231 .descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
1232 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1239 .descr = "RA = INT_MAX, SI = SI_MAX, R = 0",
1240 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1247 .descr = "RA = UINT_MAX, SI = 0x1, R = 0",
1248 .instr = TEST_PADDI(21, 22, 0x1, 0),
1251 .gpr[22] = UINT_MAX,
1255 .descr = "RA = UINT_MAX, SI = SI_MAX, R = 0",
1256 .instr = TEST_PADDI(21, 22, SI_MAX, 0),
1259 .gpr[22] = UINT_MAX,
1263 .descr = "RA is r0, SI = SI_MIN, R = 0",
1264 .instr = TEST_PADDI(21, 0, SI_MIN, 0),
1270 .descr = "RA = 0, SI = SI_MIN, R = 0",
1271 .instr = TEST_PADDI(21, 22, SI_MIN, 0),
1278 .descr = "RA is r0, SI = 0, R = 1",
1279 .instr = TEST_PADDI(21, 0, 0, 1),
1285 .descr = "RA is r0, SI = SI_MIN, R = 1",
1286 .instr = TEST_PADDI(21, 0, SI_MIN, 1),
1291 /* Invalid instruction form with R = 1 and RA != 0 */
1293 .descr = "RA = R22(0), SI = 0, R = 1",
1294 .instr = TEST_PADDI(21, 22, 0, 1),
1295 .flags = NEGATIVE_TEST,
1305 static int __init emulate_compute_instr(struct pt_regs *regs,
1306 struct ppc_inst instr,
1310 struct instruction_op op;
1312 if (!regs || !ppc_inst_val(instr))
1315 regs->nip = patch_site_addr(&patch__exec_instr);
1317 analysed = analyse_instr(&op, regs, instr);
1318 if (analysed != 1 || GETTYPE(op.type) != COMPUTE) {
1321 pr_info("emulation failed, instruction = %s\n", ppc_inst_as_str(instr));
1324 if (analysed == 1 && negative)
1325 pr_info("negative test failed, instruction = %s\n", ppc_inst_as_str(instr));
1327 emulate_update_regs(regs, &op);
1331 static int __init execute_compute_instr(struct pt_regs *regs,
1332 struct ppc_inst instr)
1334 extern int exec_instr(struct pt_regs *regs);
1336 if (!regs || !ppc_inst_val(instr))
1339 /* Patch the NOP with the actual instruction */
1340 patch_instruction_site(&patch__exec_instr, instr);
1341 if (exec_instr(regs)) {
1342 pr_info("execution failed, instruction = %s\n", ppc_inst_as_str(instr));
1349 #define gpr_mismatch(gprn, exp, got) \
1350 pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n", \
1353 #define reg_mismatch(name, exp, got) \
1354 pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n", \
1357 static void __init run_tests_compute(void)
1359 unsigned long flags;
1360 struct compute_test *test;
1361 struct pt_regs *regs, exp, got;
1362 unsigned int i, j, k;
1363 struct ppc_inst instr;
1364 bool ignore_gpr, ignore_xer, ignore_ccr, passed, rc, negative;
1366 for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
1367 test = &compute_tests[i];
1369 if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) {
1370 show_result(test->mnemonic, "SKIP (!CPU_FTR)");
1374 for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
1375 instr = test->subtests[j].instr;
1376 flags = test->subtests[j].flags;
1377 regs = &test->subtests[j].regs;
1378 negative = flags & NEGATIVE_TEST;
1379 ignore_xer = flags & IGNORE_XER;
1380 ignore_ccr = flags & IGNORE_CCR;
1383 memcpy(&exp, regs, sizeof(struct pt_regs));
1384 memcpy(&got, regs, sizeof(struct pt_regs));
1387 * Set a compatible MSR value explicitly to ensure
1388 * that XER and CR bits are updated appropriately
1390 exp.msr = MSR_KERNEL;
1391 got.msr = MSR_KERNEL;
1393 rc = emulate_compute_instr(&got, instr, negative) != 0;
1395 /* skip executing instruction */
1398 } else if (rc || execute_compute_instr(&exp, instr)) {
1403 /* Verify GPR values */
1404 for (k = 0; k < 32; k++) {
1405 ignore_gpr = flags & IGNORE_GPR(k);
1406 if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
1408 gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
1412 /* Verify LR value */
1413 if (exp.link != got.link) {
1415 reg_mismatch("LR", exp.link, got.link);
1418 /* Verify XER value */
1419 if (!ignore_xer && exp.xer != got.xer) {
1421 reg_mismatch("XER", exp.xer, got.xer);
1424 /* Verify CR value */
1425 if (!ignore_ccr && exp.ccr != got.ccr) {
1427 reg_mismatch("CR", exp.ccr, got.ccr);
1431 show_result_with_descr(test->mnemonic,
1432 test->subtests[j].descr,
1433 passed ? "PASS" : "FAIL");
1438 static int __init test_emulate_step(void)
1440 printk(KERN_INFO "Running instruction emulation self-tests ...\n");
1441 run_tests_load_store();
1442 run_tests_compute();
1446 late_initcall(test_emulate_step);