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