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