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