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