1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Simple sanity tests for instruction emulation infrastructure.
4  *
5  * Copyright IBM Corp. 2016
6  */
7 
8 #define pr_fmt(fmt) "emulate_step_test: " fmt
9 
10 #include <linux/ptrace.h>
11 #include <asm/sstep.h>
12 #include <asm/ppc-opcode.h>
13 #include <asm/code-patching.h>
14 #include <asm/inst.h>
15 
16 #define MAX_SUBTESTS	16
17 
18 #define IGNORE_GPR(n)	(0x1UL << (n))
19 #define IGNORE_XER	(0x1UL << 32)
20 #define IGNORE_CCR	(0x1UL << 33)
21 
22 #define TEST_PLD(r, base, i, pr) \
23 	ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
24 			PPC_INST_PLD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
25 
26 #define TEST_PLWZ(r, base, i, pr) \
27 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
28 			PPC_RAW_LWZ(r, base, i))
29 
30 #define TEST_PSTD(r, base, i, pr) \
31 	ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
32 			PPC_INST_PSTD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
33 
34 #define TEST_PLFS(r, base, i, pr) \
35 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
36 			PPC_INST_LFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
37 
38 #define TEST_PSTFS(r, base, i, pr) \
39 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
40 			PPC_INST_STFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
41 
42 #define TEST_PLFD(r, base, i, pr) \
43 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
44 			PPC_INST_LFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
45 
46 #define TEST_PSTFD(r, base, i, pr) \
47 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
48 			PPC_INST_STFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
49 
50 #define TEST_PADDI(t, a, i, pr) \
51 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
52 			PPC_RAW_ADDI(t, a, i))
53 
54 
55 static void __init init_pt_regs(struct pt_regs *regs)
56 {
57 	static unsigned long msr;
58 	static bool msr_cached;
59 
60 	memset(regs, 0, sizeof(struct pt_regs));
61 
62 	if (likely(msr_cached)) {
63 		regs->msr = msr;
64 		return;
65 	}
66 
67 	asm volatile("mfmsr %0" : "=r"(regs->msr));
68 
69 	regs->msr |= MSR_FP;
70 	regs->msr |= MSR_VEC;
71 	regs->msr |= MSR_VSX;
72 
73 	msr = regs->msr;
74 	msr_cached = true;
75 }
76 
77 static void __init show_result(char *mnemonic, char *result)
78 {
79 	pr_info("%-14s : %s\n", mnemonic, result);
80 }
81 
82 static void __init show_result_with_descr(char *mnemonic, char *descr,
83 					  char *result)
84 {
85 	pr_info("%-14s : %-50s %s\n", mnemonic, descr, result);
86 }
87 
88 static void __init test_ld(void)
89 {
90 	struct pt_regs regs;
91 	unsigned long a = 0x23;
92 	int stepped = -1;
93 
94 	init_pt_regs(&regs);
95 	regs.gpr[3] = (unsigned long) &a;
96 
97 	/* ld r5, 0(r3) */
98 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LD(5, 3, 0)));
99 
100 	if (stepped == 1 && regs.gpr[5] == a)
101 		show_result("ld", "PASS");
102 	else
103 		show_result("ld", "FAIL");
104 }
105 
106 static void __init test_pld(void)
107 {
108 	struct pt_regs regs;
109 	unsigned long a = 0x23;
110 	int stepped = -1;
111 
112 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
113 		show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
114 		return;
115 	}
116 
117 	init_pt_regs(&regs);
118 	regs.gpr[3] = (unsigned long)&a;
119 
120 	/* pld r5, 0(r3), 0 */
121 	stepped = emulate_step(&regs, TEST_PLD(5, 3, 0, 0));
122 
123 	if (stepped == 1 && regs.gpr[5] == a)
124 		show_result("pld", "PASS");
125 	else
126 		show_result("pld", "FAIL");
127 }
128 
129 static void __init test_lwz(void)
130 {
131 	struct pt_regs regs;
132 	unsigned int a = 0x4545;
133 	int stepped = -1;
134 
135 	init_pt_regs(&regs);
136 	regs.gpr[3] = (unsigned long) &a;
137 
138 	/* lwz r5, 0(r3) */
139 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LWZ(5, 3, 0)));
140 
141 	if (stepped == 1 && regs.gpr[5] == a)
142 		show_result("lwz", "PASS");
143 	else
144 		show_result("lwz", "FAIL");
145 }
146 
147 static void __init test_plwz(void)
148 {
149 	struct pt_regs regs;
150 	unsigned int a = 0x4545;
151 	int stepped = -1;
152 
153 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
154 		show_result("plwz", "SKIP (!CPU_FTR_ARCH_31)");
155 		return;
156 	}
157 
158 	init_pt_regs(&regs);
159 	regs.gpr[3] = (unsigned long)&a;
160 
161 	/* plwz r5, 0(r3), 0 */
162 
163 	stepped = emulate_step(&regs, TEST_PLWZ(5, 3, 0, 0));
164 
165 	if (stepped == 1 && regs.gpr[5] == a)
166 		show_result("plwz", "PASS");
167 	else
168 		show_result("plwz", "FAIL");
169 }
170 
171 static void __init test_lwzx(void)
172 {
173 	struct pt_regs regs;
174 	unsigned int a[3] = {0x0, 0x0, 0x1234};
175 	int stepped = -1;
176 
177 	init_pt_regs(&regs);
178 	regs.gpr[3] = (unsigned long) a;
179 	regs.gpr[4] = 8;
180 	regs.gpr[5] = 0x8765;
181 
182 	/* lwzx r5, r3, r4 */
183 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LWZX(5, 3, 4)));
184 	if (stepped == 1 && regs.gpr[5] == a[2])
185 		show_result("lwzx", "PASS");
186 	else
187 		show_result("lwzx", "FAIL");
188 }
189 
190 static void __init test_std(void)
191 {
192 	struct pt_regs regs;
193 	unsigned long a = 0x1234;
194 	int stepped = -1;
195 
196 	init_pt_regs(&regs);
197 	regs.gpr[3] = (unsigned long) &a;
198 	regs.gpr[5] = 0x5678;
199 
200 	/* std r5, 0(r3) */
201 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STD(5, 3, 0)));
202 	if (stepped == 1 && regs.gpr[5] == a)
203 		show_result("std", "PASS");
204 	else
205 		show_result("std", "FAIL");
206 }
207 
208 static void __init test_pstd(void)
209 {
210 	struct pt_regs regs;
211 	unsigned long a = 0x1234;
212 	int stepped = -1;
213 
214 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
215 		show_result("pstd", "SKIP (!CPU_FTR_ARCH_31)");
216 		return;
217 	}
218 
219 	init_pt_regs(&regs);
220 	regs.gpr[3] = (unsigned long)&a;
221 	regs.gpr[5] = 0x5678;
222 
223 	/* pstd r5, 0(r3), 0 */
224 	stepped = emulate_step(&regs, TEST_PSTD(5, 3, 0, 0));
225 	if (stepped == 1 || regs.gpr[5] == a)
226 		show_result("pstd", "PASS");
227 	else
228 		show_result("pstd", "FAIL");
229 }
230 
231 static void __init test_ldarx_stdcx(void)
232 {
233 	struct pt_regs regs;
234 	unsigned long a = 0x1234;
235 	int stepped = -1;
236 	unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
237 
238 	init_pt_regs(&regs);
239 	asm volatile("mfcr %0" : "=r"(regs.ccr));
240 
241 
242 	/*** ldarx ***/
243 
244 	regs.gpr[3] = (unsigned long) &a;
245 	regs.gpr[4] = 0;
246 	regs.gpr[5] = 0x5678;
247 
248 	/* ldarx r5, r3, r4, 0 */
249 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LDARX(5, 3, 4, 0)));
250 
251 	/*
252 	 * Don't touch 'a' here. Touching 'a' can do Load/store
253 	 * of 'a' which result in failure of subsequent stdcx.
254 	 * Instead, use hardcoded value for comparison.
255 	 */
256 	if (stepped <= 0 || regs.gpr[5] != 0x1234) {
257 		show_result("ldarx / stdcx.", "FAIL (ldarx)");
258 		return;
259 	}
260 
261 
262 	/*** stdcx. ***/
263 
264 	regs.gpr[5] = 0x9ABC;
265 
266 	/* stdcx. r5, r3, r4 */
267 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STDCX(5, 3, 4)));
268 
269 	/*
270 	 * Two possible scenarios that indicates successful emulation
271 	 * of stdcx. :
272 	 *  1. Reservation is active and store is performed. In this
273 	 *     case cr0.eq bit will be set to 1.
274 	 *  2. Reservation is not active and store is not performed.
275 	 *     In this case cr0.eq bit will be set to 0.
276 	 */
277 	if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
278 			|| (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
279 		show_result("ldarx / stdcx.", "PASS");
280 	else
281 		show_result("ldarx / stdcx.", "FAIL (stdcx.)");
282 }
283 
284 #ifdef CONFIG_PPC_FPU
285 static void __init test_lfsx_stfsx(void)
286 {
287 	struct pt_regs regs;
288 	union {
289 		float a;
290 		int b;
291 	} c;
292 	int cached_b;
293 	int stepped = -1;
294 
295 	init_pt_regs(&regs);
296 
297 
298 	/*** lfsx ***/
299 
300 	c.a = 123.45;
301 	cached_b = c.b;
302 
303 	regs.gpr[3] = (unsigned long) &c.a;
304 	regs.gpr[4] = 0;
305 
306 	/* lfsx frt10, r3, r4 */
307 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LFSX(10, 3, 4)));
308 
309 	if (stepped == 1)
310 		show_result("lfsx", "PASS");
311 	else
312 		show_result("lfsx", "FAIL");
313 
314 
315 	/*** stfsx ***/
316 
317 	c.a = 678.91;
318 
319 	/* stfsx frs10, r3, r4 */
320 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STFSX(10, 3, 4)));
321 
322 	if (stepped == 1 && c.b == cached_b)
323 		show_result("stfsx", "PASS");
324 	else
325 		show_result("stfsx", "FAIL");
326 }
327 
328 static void __init test_plfs_pstfs(void)
329 {
330 	struct pt_regs regs;
331 	union {
332 		float a;
333 		int b;
334 	} c;
335 	int cached_b;
336 	int stepped = -1;
337 
338 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
339 		show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
340 		return;
341 	}
342 
343 	init_pt_regs(&regs);
344 
345 
346 	/*** plfs ***/
347 
348 	c.a = 123.45;
349 	cached_b = c.b;
350 
351 	regs.gpr[3] = (unsigned long)&c.a;
352 
353 	/* plfs frt10, 0(r3), 0  */
354 	stepped = emulate_step(&regs, TEST_PLFS(10, 3, 0, 0));
355 
356 	if (stepped == 1)
357 		show_result("plfs", "PASS");
358 	else
359 		show_result("plfs", "FAIL");
360 
361 
362 	/*** pstfs ***/
363 
364 	c.a = 678.91;
365 
366 	/* pstfs frs10, 0(r3), 0 */
367 	stepped = emulate_step(&regs, TEST_PSTFS(10, 3, 0, 0));
368 
369 	if (stepped == 1 && c.b == cached_b)
370 		show_result("pstfs", "PASS");
371 	else
372 		show_result("pstfs", "FAIL");
373 }
374 
375 static void __init test_lfdx_stfdx(void)
376 {
377 	struct pt_regs regs;
378 	union {
379 		double a;
380 		long b;
381 	} c;
382 	long cached_b;
383 	int stepped = -1;
384 
385 	init_pt_regs(&regs);
386 
387 
388 	/*** lfdx ***/
389 
390 	c.a = 123456.78;
391 	cached_b = c.b;
392 
393 	regs.gpr[3] = (unsigned long) &c.a;
394 	regs.gpr[4] = 0;
395 
396 	/* lfdx frt10, r3, r4 */
397 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LFDX(10, 3, 4)));
398 
399 	if (stepped == 1)
400 		show_result("lfdx", "PASS");
401 	else
402 		show_result("lfdx", "FAIL");
403 
404 
405 	/*** stfdx ***/
406 
407 	c.a = 987654.32;
408 
409 	/* stfdx frs10, r3, r4 */
410 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STFDX(10, 3, 4)));
411 
412 	if (stepped == 1 && c.b == cached_b)
413 		show_result("stfdx", "PASS");
414 	else
415 		show_result("stfdx", "FAIL");
416 }
417 
418 static void __init test_plfd_pstfd(void)
419 {
420 	struct pt_regs regs;
421 	union {
422 		double a;
423 		long b;
424 	} c;
425 	long cached_b;
426 	int stepped = -1;
427 
428 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
429 		show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
430 		return;
431 	}
432 
433 	init_pt_regs(&regs);
434 
435 
436 	/*** plfd ***/
437 
438 	c.a = 123456.78;
439 	cached_b = c.b;
440 
441 	regs.gpr[3] = (unsigned long)&c.a;
442 
443 	/* plfd frt10, 0(r3), 0 */
444 	stepped = emulate_step(&regs, TEST_PLFD(10, 3, 0, 0));
445 
446 	if (stepped == 1)
447 		show_result("plfd", "PASS");
448 	else
449 		show_result("plfd", "FAIL");
450 
451 
452 	/*** pstfd ***/
453 
454 	c.a = 987654.32;
455 
456 	/* pstfd frs10, 0(r3), 0 */
457 	stepped = emulate_step(&regs, TEST_PSTFD(10, 3, 0, 0));
458 
459 	if (stepped == 1 && c.b == cached_b)
460 		show_result("pstfd", "PASS");
461 	else
462 		show_result("pstfd", "FAIL");
463 }
464 #else
465 static void __init test_lfsx_stfsx(void)
466 {
467 	show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
468 	show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
469 }
470 
471 static void __init test_plfs_pstfs(void)
472 {
473 	show_result("plfs", "SKIP (CONFIG_PPC_FPU is not set)");
474 	show_result("pstfs", "SKIP (CONFIG_PPC_FPU is not set)");
475 }
476 
477 static void __init test_lfdx_stfdx(void)
478 {
479 	show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
480 	show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
481 }
482 
483 static void __init test_plfd_pstfd(void)
484 {
485 	show_result("plfd", "SKIP (CONFIG_PPC_FPU is not set)");
486 	show_result("pstfd", "SKIP (CONFIG_PPC_FPU is not set)");
487 }
488 #endif /* CONFIG_PPC_FPU */
489 
490 #ifdef CONFIG_ALTIVEC
491 static void __init test_lvx_stvx(void)
492 {
493 	struct pt_regs regs;
494 	union {
495 		vector128 a;
496 		u32 b[4];
497 	} c;
498 	u32 cached_b[4];
499 	int stepped = -1;
500 
501 	init_pt_regs(&regs);
502 
503 
504 	/*** lvx ***/
505 
506 	cached_b[0] = c.b[0] = 923745;
507 	cached_b[1] = c.b[1] = 2139478;
508 	cached_b[2] = c.b[2] = 9012;
509 	cached_b[3] = c.b[3] = 982134;
510 
511 	regs.gpr[3] = (unsigned long) &c.a;
512 	regs.gpr[4] = 0;
513 
514 	/* lvx vrt10, r3, r4 */
515 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LVX(10, 3, 4)));
516 
517 	if (stepped == 1)
518 		show_result("lvx", "PASS");
519 	else
520 		show_result("lvx", "FAIL");
521 
522 
523 	/*** stvx ***/
524 
525 	c.b[0] = 4987513;
526 	c.b[1] = 84313948;
527 	c.b[2] = 71;
528 	c.b[3] = 498532;
529 
530 	/* stvx vrs10, r3, r4 */
531 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STVX(10, 3, 4)));
532 
533 	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
534 	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
535 		show_result("stvx", "PASS");
536 	else
537 		show_result("stvx", "FAIL");
538 }
539 #else
540 static void __init test_lvx_stvx(void)
541 {
542 	show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
543 	show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
544 }
545 #endif /* CONFIG_ALTIVEC */
546 
547 #ifdef CONFIG_VSX
548 static void __init test_lxvd2x_stxvd2x(void)
549 {
550 	struct pt_regs regs;
551 	union {
552 		vector128 a;
553 		u32 b[4];
554 	} c;
555 	u32 cached_b[4];
556 	int stepped = -1;
557 
558 	init_pt_regs(&regs);
559 
560 
561 	/*** lxvd2x ***/
562 
563 	cached_b[0] = c.b[0] = 18233;
564 	cached_b[1] = c.b[1] = 34863571;
565 	cached_b[2] = c.b[2] = 834;
566 	cached_b[3] = c.b[3] = 6138911;
567 
568 	regs.gpr[3] = (unsigned long) &c.a;
569 	regs.gpr[4] = 0;
570 
571 	/* lxvd2x vsr39, r3, r4 */
572 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVD2X(39, R3, R4)));
573 
574 	if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
575 		show_result("lxvd2x", "PASS");
576 	} else {
577 		if (!cpu_has_feature(CPU_FTR_VSX))
578 			show_result("lxvd2x", "PASS (!CPU_FTR_VSX)");
579 		else
580 			show_result("lxvd2x", "FAIL");
581 	}
582 
583 
584 	/*** stxvd2x ***/
585 
586 	c.b[0] = 21379463;
587 	c.b[1] = 87;
588 	c.b[2] = 374234;
589 	c.b[3] = 4;
590 
591 	/* stxvd2x vsr39, r3, r4 */
592 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVD2X(39, R3, R4)));
593 
594 	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
595 	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
596 	    cpu_has_feature(CPU_FTR_VSX)) {
597 		show_result("stxvd2x", "PASS");
598 	} else {
599 		if (!cpu_has_feature(CPU_FTR_VSX))
600 			show_result("stxvd2x", "PASS (!CPU_FTR_VSX)");
601 		else
602 			show_result("stxvd2x", "FAIL");
603 	}
604 }
605 #else
606 static void __init test_lxvd2x_stxvd2x(void)
607 {
608 	show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
609 	show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
610 }
611 #endif /* CONFIG_VSX */
612 
613 static void __init run_tests_load_store(void)
614 {
615 	test_ld();
616 	test_pld();
617 	test_lwz();
618 	test_plwz();
619 	test_lwzx();
620 	test_std();
621 	test_pstd();
622 	test_ldarx_stdcx();
623 	test_lfsx_stfsx();
624 	test_plfs_pstfs();
625 	test_lfdx_stfdx();
626 	test_plfd_pstfd();
627 	test_lvx_stvx();
628 	test_lxvd2x_stxvd2x();
629 }
630 
631 struct compute_test {
632 	char *mnemonic;
633 	unsigned long cpu_feature;
634 	struct {
635 		char *descr;
636 		unsigned long flags;
637 		struct ppc_inst instr;
638 		struct pt_regs regs;
639 	} subtests[MAX_SUBTESTS + 1];
640 };
641 
642 /* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
643 #define SI_MIN BIT(33)
644 #define SI_MAX (BIT(33) - 1)
645 #define SI_UMAX (BIT(34) - 1)
646 
647 static struct compute_test compute_tests[] = {
648 	{
649 		.mnemonic = "nop",
650 		.subtests = {
651 			{
652 				.descr = "R0 = LONG_MAX",
653 				.instr = ppc_inst(PPC_INST_NOP),
654 				.regs = {
655 					.gpr[0] = LONG_MAX,
656 				}
657 			}
658 		}
659 	},
660 	{
661 		.mnemonic = "add",
662 		.subtests = {
663 			{
664 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
665 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
666 				.regs = {
667 					.gpr[21] = LONG_MIN,
668 					.gpr[22] = LONG_MIN,
669 				}
670 			},
671 			{
672 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
673 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
674 				.regs = {
675 					.gpr[21] = LONG_MIN,
676 					.gpr[22] = LONG_MAX,
677 				}
678 			},
679 			{
680 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
681 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
682 				.regs = {
683 					.gpr[21] = LONG_MAX,
684 					.gpr[22] = LONG_MAX,
685 				}
686 			},
687 			{
688 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
689 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
690 				.regs = {
691 					.gpr[21] = ULONG_MAX,
692 					.gpr[22] = ULONG_MAX,
693 				}
694 			},
695 			{
696 				.descr = "RA = ULONG_MAX, RB = 0x1",
697 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
698 				.regs = {
699 					.gpr[21] = ULONG_MAX,
700 					.gpr[22] = 0x1,
701 				}
702 			},
703 			{
704 				.descr = "RA = INT_MIN, RB = INT_MIN",
705 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
706 				.regs = {
707 					.gpr[21] = INT_MIN,
708 					.gpr[22] = INT_MIN,
709 				}
710 			},
711 			{
712 				.descr = "RA = INT_MIN, RB = INT_MAX",
713 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
714 				.regs = {
715 					.gpr[21] = INT_MIN,
716 					.gpr[22] = INT_MAX,
717 				}
718 			},
719 			{
720 				.descr = "RA = INT_MAX, RB = INT_MAX",
721 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
722 				.regs = {
723 					.gpr[21] = INT_MAX,
724 					.gpr[22] = INT_MAX,
725 				}
726 			},
727 			{
728 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
729 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
730 				.regs = {
731 					.gpr[21] = UINT_MAX,
732 					.gpr[22] = UINT_MAX,
733 				}
734 			},
735 			{
736 				.descr = "RA = UINT_MAX, RB = 0x1",
737 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
738 				.regs = {
739 					.gpr[21] = UINT_MAX,
740 					.gpr[22] = 0x1,
741 				}
742 			}
743 		}
744 	},
745 	{
746 		.mnemonic = "add.",
747 		.subtests = {
748 			{
749 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
750 				.flags = IGNORE_CCR,
751 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
752 				.regs = {
753 					.gpr[21] = LONG_MIN,
754 					.gpr[22] = LONG_MIN,
755 				}
756 			},
757 			{
758 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
759 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
760 				.regs = {
761 					.gpr[21] = LONG_MIN,
762 					.gpr[22] = LONG_MAX,
763 				}
764 			},
765 			{
766 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
767 				.flags = IGNORE_CCR,
768 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
769 				.regs = {
770 					.gpr[21] = LONG_MAX,
771 					.gpr[22] = LONG_MAX,
772 				}
773 			},
774 			{
775 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
776 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
777 				.regs = {
778 					.gpr[21] = ULONG_MAX,
779 					.gpr[22] = ULONG_MAX,
780 				}
781 			},
782 			{
783 				.descr = "RA = ULONG_MAX, RB = 0x1",
784 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
785 				.regs = {
786 					.gpr[21] = ULONG_MAX,
787 					.gpr[22] = 0x1,
788 				}
789 			},
790 			{
791 				.descr = "RA = INT_MIN, RB = INT_MIN",
792 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
793 				.regs = {
794 					.gpr[21] = INT_MIN,
795 					.gpr[22] = INT_MIN,
796 				}
797 			},
798 			{
799 				.descr = "RA = INT_MIN, RB = INT_MAX",
800 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
801 				.regs = {
802 					.gpr[21] = INT_MIN,
803 					.gpr[22] = INT_MAX,
804 				}
805 			},
806 			{
807 				.descr = "RA = INT_MAX, RB = INT_MAX",
808 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
809 				.regs = {
810 					.gpr[21] = INT_MAX,
811 					.gpr[22] = INT_MAX,
812 				}
813 			},
814 			{
815 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
816 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
817 				.regs = {
818 					.gpr[21] = UINT_MAX,
819 					.gpr[22] = UINT_MAX,
820 				}
821 			},
822 			{
823 				.descr = "RA = UINT_MAX, RB = 0x1",
824 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
825 				.regs = {
826 					.gpr[21] = UINT_MAX,
827 					.gpr[22] = 0x1,
828 				}
829 			}
830 		}
831 	},
832 	{
833 		.mnemonic = "addc",
834 		.subtests = {
835 			{
836 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
837 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
838 				.regs = {
839 					.gpr[21] = LONG_MIN,
840 					.gpr[22] = LONG_MIN,
841 				}
842 			},
843 			{
844 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
845 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
846 				.regs = {
847 					.gpr[21] = LONG_MIN,
848 					.gpr[22] = LONG_MAX,
849 				}
850 			},
851 			{
852 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
853 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
854 				.regs = {
855 					.gpr[21] = LONG_MAX,
856 					.gpr[22] = LONG_MAX,
857 				}
858 			},
859 			{
860 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
861 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
862 				.regs = {
863 					.gpr[21] = ULONG_MAX,
864 					.gpr[22] = ULONG_MAX,
865 				}
866 			},
867 			{
868 				.descr = "RA = ULONG_MAX, RB = 0x1",
869 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
870 				.regs = {
871 					.gpr[21] = ULONG_MAX,
872 					.gpr[22] = 0x1,
873 				}
874 			},
875 			{
876 				.descr = "RA = INT_MIN, RB = INT_MIN",
877 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
878 				.regs = {
879 					.gpr[21] = INT_MIN,
880 					.gpr[22] = INT_MIN,
881 				}
882 			},
883 			{
884 				.descr = "RA = INT_MIN, RB = INT_MAX",
885 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
886 				.regs = {
887 					.gpr[21] = INT_MIN,
888 					.gpr[22] = INT_MAX,
889 				}
890 			},
891 			{
892 				.descr = "RA = INT_MAX, RB = INT_MAX",
893 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
894 				.regs = {
895 					.gpr[21] = INT_MAX,
896 					.gpr[22] = INT_MAX,
897 				}
898 			},
899 			{
900 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
901 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
902 				.regs = {
903 					.gpr[21] = UINT_MAX,
904 					.gpr[22] = UINT_MAX,
905 				}
906 			},
907 			{
908 				.descr = "RA = UINT_MAX, RB = 0x1",
909 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
910 				.regs = {
911 					.gpr[21] = UINT_MAX,
912 					.gpr[22] = 0x1,
913 				}
914 			},
915 			{
916 				.descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
917 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
918 				.regs = {
919 					.gpr[21] = LONG_MIN | (uint)INT_MIN,
920 					.gpr[22] = LONG_MIN | (uint)INT_MIN,
921 				}
922 			}
923 		}
924 	},
925 	{
926 		.mnemonic = "addc.",
927 		.subtests = {
928 			{
929 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
930 				.flags = IGNORE_CCR,
931 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
932 				.regs = {
933 					.gpr[21] = LONG_MIN,
934 					.gpr[22] = LONG_MIN,
935 				}
936 			},
937 			{
938 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
939 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
940 				.regs = {
941 					.gpr[21] = LONG_MIN,
942 					.gpr[22] = LONG_MAX,
943 				}
944 			},
945 			{
946 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
947 				.flags = IGNORE_CCR,
948 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
949 				.regs = {
950 					.gpr[21] = LONG_MAX,
951 					.gpr[22] = LONG_MAX,
952 				}
953 			},
954 			{
955 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
956 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
957 				.regs = {
958 					.gpr[21] = ULONG_MAX,
959 					.gpr[22] = ULONG_MAX,
960 				}
961 			},
962 			{
963 				.descr = "RA = ULONG_MAX, RB = 0x1",
964 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
965 				.regs = {
966 					.gpr[21] = ULONG_MAX,
967 					.gpr[22] = 0x1,
968 				}
969 			},
970 			{
971 				.descr = "RA = INT_MIN, RB = INT_MIN",
972 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
973 				.regs = {
974 					.gpr[21] = INT_MIN,
975 					.gpr[22] = INT_MIN,
976 				}
977 			},
978 			{
979 				.descr = "RA = INT_MIN, RB = INT_MAX",
980 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
981 				.regs = {
982 					.gpr[21] = INT_MIN,
983 					.gpr[22] = INT_MAX,
984 				}
985 			},
986 			{
987 				.descr = "RA = INT_MAX, RB = INT_MAX",
988 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
989 				.regs = {
990 					.gpr[21] = INT_MAX,
991 					.gpr[22] = INT_MAX,
992 				}
993 			},
994 			{
995 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
996 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
997 				.regs = {
998 					.gpr[21] = UINT_MAX,
999 					.gpr[22] = UINT_MAX,
1000 				}
1001 			},
1002 			{
1003 				.descr = "RA = UINT_MAX, RB = 0x1",
1004 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1005 				.regs = {
1006 					.gpr[21] = UINT_MAX,
1007 					.gpr[22] = 0x1,
1008 				}
1009 			},
1010 			{
1011 				.descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1012 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1013 				.regs = {
1014 					.gpr[21] = LONG_MIN | (uint)INT_MIN,
1015 					.gpr[22] = LONG_MIN | (uint)INT_MIN,
1016 				}
1017 			}
1018 		}
1019 	},
1020 	{
1021 		.mnemonic = "paddi",
1022 		.cpu_feature = CPU_FTR_ARCH_31,
1023 		.subtests = {
1024 			{
1025 				.descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
1026 				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1027 				.regs = {
1028 					.gpr[21] = 0,
1029 					.gpr[22] = LONG_MIN,
1030 				}
1031 			},
1032 			{
1033 				.descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
1034 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1035 				.regs = {
1036 					.gpr[21] = 0,
1037 					.gpr[22] = LONG_MIN,
1038 				}
1039 			},
1040 			{
1041 				.descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
1042 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1043 				.regs = {
1044 					.gpr[21] = 0,
1045 					.gpr[22] = LONG_MAX,
1046 				}
1047 			},
1048 			{
1049 				.descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
1050 				.instr = TEST_PADDI(21, 22, SI_UMAX, 0),
1051 				.regs = {
1052 					.gpr[21] = 0,
1053 					.gpr[22] = ULONG_MAX,
1054 				}
1055 			},
1056 			{
1057 				.descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
1058 				.instr = TEST_PADDI(21, 22, 0x1, 0),
1059 				.regs = {
1060 					.gpr[21] = 0,
1061 					.gpr[22] = ULONG_MAX,
1062 				}
1063 			},
1064 			{
1065 				.descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
1066 				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1067 				.regs = {
1068 					.gpr[21] = 0,
1069 					.gpr[22] = INT_MIN,
1070 				}
1071 			},
1072 			{
1073 				.descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
1074 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1075 				.regs = {
1076 					.gpr[21] = 0,
1077 					.gpr[22] = INT_MIN,
1078 				}
1079 			},
1080 			{
1081 				.descr = "RA = INT_MAX, SI = SI_MAX, R = 0",
1082 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1083 				.regs = {
1084 					.gpr[21] = 0,
1085 					.gpr[22] = INT_MAX,
1086 				}
1087 			},
1088 			{
1089 				.descr = "RA = UINT_MAX, SI = 0x1, R = 0",
1090 				.instr = TEST_PADDI(21, 22, 0x1, 0),
1091 				.regs = {
1092 					.gpr[21] = 0,
1093 					.gpr[22] = UINT_MAX,
1094 				}
1095 			},
1096 			{
1097 				.descr = "RA = UINT_MAX, SI = SI_MAX, R = 0",
1098 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1099 				.regs = {
1100 					.gpr[21] = 0,
1101 					.gpr[22] = UINT_MAX,
1102 				}
1103 			},
1104 			{
1105 				.descr = "RA is r0, SI = SI_MIN, R = 0",
1106 				.instr = TEST_PADDI(21, 0, SI_MIN, 0),
1107 				.regs = {
1108 					.gpr[21] = 0x0,
1109 				}
1110 			},
1111 			{
1112 				.descr = "RA = 0, SI = SI_MIN, R = 0",
1113 				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1114 				.regs = {
1115 					.gpr[21] = 0x0,
1116 					.gpr[22] = 0x0,
1117 				}
1118 			},
1119 			{
1120 				.descr = "RA is r0, SI = 0, R = 1",
1121 				.instr = TEST_PADDI(21, 0, 0, 1),
1122 				.regs = {
1123 					.gpr[21] = 0,
1124 				}
1125 			},
1126 			{
1127 				.descr = "RA is r0, SI = SI_MIN, R = 1",
1128 				.instr = TEST_PADDI(21, 0, SI_MIN, 1),
1129 				.regs = {
1130 					.gpr[21] = 0,
1131 				}
1132 			}
1133 		}
1134 	}
1135 };
1136 
1137 static int __init emulate_compute_instr(struct pt_regs *regs,
1138 					struct ppc_inst instr)
1139 {
1140 	extern s32 patch__exec_instr;
1141 	struct instruction_op op;
1142 
1143 	if (!regs || !ppc_inst_val(instr))
1144 		return -EINVAL;
1145 
1146 	regs->nip = patch_site_addr(&patch__exec_instr);
1147 
1148 	if (analyse_instr(&op, regs, instr) != 1 ||
1149 	    GETTYPE(op.type) != COMPUTE) {
1150 		pr_info("execution failed, instruction = %s\n", ppc_inst_as_str(instr));
1151 		return -EFAULT;
1152 	}
1153 
1154 	emulate_update_regs(regs, &op);
1155 	return 0;
1156 }
1157 
1158 static int __init execute_compute_instr(struct pt_regs *regs,
1159 					struct ppc_inst instr)
1160 {
1161 	extern int exec_instr(struct pt_regs *regs);
1162 	extern s32 patch__exec_instr;
1163 
1164 	if (!regs || !ppc_inst_val(instr))
1165 		return -EINVAL;
1166 
1167 	/* Patch the NOP with the actual instruction */
1168 	patch_instruction_site(&patch__exec_instr, instr);
1169 	if (exec_instr(regs)) {
1170 		pr_info("execution failed, instruction = %s\n", ppc_inst_as_str(instr));
1171 		return -EFAULT;
1172 	}
1173 
1174 	return 0;
1175 }
1176 
1177 #define gpr_mismatch(gprn, exp, got)	\
1178 	pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n",	\
1179 		gprn, exp, got)
1180 
1181 #define reg_mismatch(name, exp, got)	\
1182 	pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n",	\
1183 		name, exp, got)
1184 
1185 static void __init run_tests_compute(void)
1186 {
1187 	unsigned long flags;
1188 	struct compute_test *test;
1189 	struct pt_regs *regs, exp, got;
1190 	unsigned int i, j, k;
1191 	struct ppc_inst instr;
1192 	bool ignore_gpr, ignore_xer, ignore_ccr, passed;
1193 
1194 	for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
1195 		test = &compute_tests[i];
1196 
1197 		if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) {
1198 			show_result(test->mnemonic, "SKIP (!CPU_FTR)");
1199 			continue;
1200 		}
1201 
1202 		for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
1203 			instr = test->subtests[j].instr;
1204 			flags = test->subtests[j].flags;
1205 			regs = &test->subtests[j].regs;
1206 			ignore_xer = flags & IGNORE_XER;
1207 			ignore_ccr = flags & IGNORE_CCR;
1208 			passed = true;
1209 
1210 			memcpy(&exp, regs, sizeof(struct pt_regs));
1211 			memcpy(&got, regs, sizeof(struct pt_regs));
1212 
1213 			/*
1214 			 * Set a compatible MSR value explicitly to ensure
1215 			 * that XER and CR bits are updated appropriately
1216 			 */
1217 			exp.msr = MSR_KERNEL;
1218 			got.msr = MSR_KERNEL;
1219 
1220 			if (emulate_compute_instr(&got, instr) ||
1221 			    execute_compute_instr(&exp, instr)) {
1222 				passed = false;
1223 				goto print;
1224 			}
1225 
1226 			/* Verify GPR values */
1227 			for (k = 0; k < 32; k++) {
1228 				ignore_gpr = flags & IGNORE_GPR(k);
1229 				if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
1230 					passed = false;
1231 					gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
1232 				}
1233 			}
1234 
1235 			/* Verify LR value */
1236 			if (exp.link != got.link) {
1237 				passed = false;
1238 				reg_mismatch("LR", exp.link, got.link);
1239 			}
1240 
1241 			/* Verify XER value */
1242 			if (!ignore_xer && exp.xer != got.xer) {
1243 				passed = false;
1244 				reg_mismatch("XER", exp.xer, got.xer);
1245 			}
1246 
1247 			/* Verify CR value */
1248 			if (!ignore_ccr && exp.ccr != got.ccr) {
1249 				passed = false;
1250 				reg_mismatch("CR", exp.ccr, got.ccr);
1251 			}
1252 
1253 print:
1254 			show_result_with_descr(test->mnemonic,
1255 					       test->subtests[j].descr,
1256 					       passed ? "PASS" : "FAIL");
1257 		}
1258 	}
1259 }
1260 
1261 static int __init test_emulate_step(void)
1262 {
1263 	printk(KERN_INFO "Running instruction emulation self-tests ...\n");
1264 	run_tests_load_store();
1265 	run_tests_compute();
1266 
1267 	return 0;
1268 }
1269 late_initcall(test_emulate_step);
1270