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