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