1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Simple sanity tests for instruction emulation infrastructure.
4  *
5  * Copyright IBM Corp. 2016
6  */
7 
8 #define pr_fmt(fmt) "emulate_step_test: " fmt
9 
10 #include <linux/ptrace.h>
11 #include <asm/cpu_has_feature.h>
12 #include <asm/sstep.h>
13 #include <asm/ppc-opcode.h>
14 #include <asm/code-patching.h>
15 #include <asm/inst.h>
16 
17 #define MAX_SUBTESTS	16
18 
19 #define IGNORE_GPR(n)	(0x1UL << (n))
20 #define IGNORE_XER	(0x1UL << 32)
21 #define IGNORE_CCR	(0x1UL << 33)
22 #define NEGATIVE_TEST	(0x1UL << 63)
23 
24 #define TEST_PLD(r, base, i, pr) \
25 	ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
26 			PPC_INST_PLD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
27 
28 #define TEST_PLWZ(r, base, i, pr) \
29 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
30 			PPC_RAW_LWZ(r, base, i))
31 
32 #define TEST_PSTD(r, base, i, pr) \
33 	ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
34 			PPC_INST_PSTD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
35 
36 #define TEST_PLFS(r, base, i, pr) \
37 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
38 			PPC_INST_LFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
39 
40 #define TEST_PSTFS(r, base, i, pr) \
41 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
42 			PPC_INST_STFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
43 
44 #define TEST_PLFD(r, base, i, pr) \
45 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
46 			PPC_INST_LFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
47 
48 #define TEST_PSTFD(r, base, i, pr) \
49 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
50 			PPC_INST_STFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
51 
52 #define TEST_PADDI(t, a, i, pr) \
53 	ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \
54 			PPC_RAW_ADDI(t, a, i))
55 
init_pt_regs(struct pt_regs * regs)56 static void __init init_pt_regs(struct pt_regs *regs)
57 {
58 	static unsigned long msr;
59 	static bool msr_cached;
60 
61 	memset(regs, 0, sizeof(struct pt_regs));
62 
63 	if (likely(msr_cached)) {
64 		regs->msr = msr;
65 		return;
66 	}
67 
68 	asm volatile("mfmsr %0" : "=r"(regs->msr));
69 
70 	regs->msr |= MSR_FP;
71 	regs->msr |= MSR_VEC;
72 	regs->msr |= MSR_VSX;
73 
74 	msr = regs->msr;
75 	msr_cached = true;
76 }
77 
show_result(char * mnemonic,char * result)78 static void __init show_result(char *mnemonic, char *result)
79 {
80 	pr_info("%-14s : %s\n", mnemonic, result);
81 }
82 
show_result_with_descr(char * mnemonic,char * descr,char * result)83 static void __init show_result_with_descr(char *mnemonic, char *descr,
84 					  char *result)
85 {
86 	pr_info("%-14s : %-50s %s\n", mnemonic, descr, result);
87 }
88 
test_ld(void)89 static void __init test_ld(void)
90 {
91 	struct pt_regs regs;
92 	unsigned long a = 0x23;
93 	int stepped = -1;
94 
95 	init_pt_regs(&regs);
96 	regs.gpr[3] = (unsigned long) &a;
97 
98 	/* ld r5, 0(r3) */
99 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LD(5, 3, 0)));
100 
101 	if (stepped == 1 && regs.gpr[5] == a)
102 		show_result("ld", "PASS");
103 	else
104 		show_result("ld", "FAIL");
105 }
106 
test_pld(void)107 static void __init test_pld(void)
108 {
109 	struct pt_regs regs;
110 	unsigned long a = 0x23;
111 	int stepped = -1;
112 
113 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
114 		show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
115 		return;
116 	}
117 
118 	init_pt_regs(&regs);
119 	regs.gpr[3] = (unsigned long)&a;
120 
121 	/* pld r5, 0(r3), 0 */
122 	stepped = emulate_step(&regs, TEST_PLD(5, 3, 0, 0));
123 
124 	if (stepped == 1 && regs.gpr[5] == a)
125 		show_result("pld", "PASS");
126 	else
127 		show_result("pld", "FAIL");
128 }
129 
test_lwz(void)130 static void __init test_lwz(void)
131 {
132 	struct pt_regs regs;
133 	unsigned int a = 0x4545;
134 	int stepped = -1;
135 
136 	init_pt_regs(&regs);
137 	regs.gpr[3] = (unsigned long) &a;
138 
139 	/* lwz r5, 0(r3) */
140 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LWZ(5, 3, 0)));
141 
142 	if (stepped == 1 && regs.gpr[5] == a)
143 		show_result("lwz", "PASS");
144 	else
145 		show_result("lwz", "FAIL");
146 }
147 
test_plwz(void)148 static void __init test_plwz(void)
149 {
150 	struct pt_regs regs;
151 	unsigned int a = 0x4545;
152 	int stepped = -1;
153 
154 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
155 		show_result("plwz", "SKIP (!CPU_FTR_ARCH_31)");
156 		return;
157 	}
158 
159 	init_pt_regs(&regs);
160 	regs.gpr[3] = (unsigned long)&a;
161 
162 	/* plwz r5, 0(r3), 0 */
163 
164 	stepped = emulate_step(&regs, TEST_PLWZ(5, 3, 0, 0));
165 
166 	if (stepped == 1 && regs.gpr[5] == a)
167 		show_result("plwz", "PASS");
168 	else
169 		show_result("plwz", "FAIL");
170 }
171 
test_lwzx(void)172 static void __init test_lwzx(void)
173 {
174 	struct pt_regs regs;
175 	unsigned int a[3] = {0x0, 0x0, 0x1234};
176 	int stepped = -1;
177 
178 	init_pt_regs(&regs);
179 	regs.gpr[3] = (unsigned long) a;
180 	regs.gpr[4] = 8;
181 	regs.gpr[5] = 0x8765;
182 
183 	/* lwzx r5, r3, r4 */
184 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LWZX(5, 3, 4)));
185 	if (stepped == 1 && regs.gpr[5] == a[2])
186 		show_result("lwzx", "PASS");
187 	else
188 		show_result("lwzx", "FAIL");
189 }
190 
test_std(void)191 static void __init test_std(void)
192 {
193 	struct pt_regs regs;
194 	unsigned long a = 0x1234;
195 	int stepped = -1;
196 
197 	init_pt_regs(&regs);
198 	regs.gpr[3] = (unsigned long) &a;
199 	regs.gpr[5] = 0x5678;
200 
201 	/* std r5, 0(r3) */
202 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STD(5, 3, 0)));
203 	if (stepped == 1 && regs.gpr[5] == a)
204 		show_result("std", "PASS");
205 	else
206 		show_result("std", "FAIL");
207 }
208 
test_pstd(void)209 static void __init test_pstd(void)
210 {
211 	struct pt_regs regs;
212 	unsigned long a = 0x1234;
213 	int stepped = -1;
214 
215 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
216 		show_result("pstd", "SKIP (!CPU_FTR_ARCH_31)");
217 		return;
218 	}
219 
220 	init_pt_regs(&regs);
221 	regs.gpr[3] = (unsigned long)&a;
222 	regs.gpr[5] = 0x5678;
223 
224 	/* pstd r5, 0(r3), 0 */
225 	stepped = emulate_step(&regs, TEST_PSTD(5, 3, 0, 0));
226 	if (stepped == 1 || regs.gpr[5] == a)
227 		show_result("pstd", "PASS");
228 	else
229 		show_result("pstd", "FAIL");
230 }
231 
test_ldarx_stdcx(void)232 static void __init test_ldarx_stdcx(void)
233 {
234 	struct pt_regs regs;
235 	unsigned long a = 0x1234;
236 	int stepped = -1;
237 	unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
238 
239 	init_pt_regs(&regs);
240 	asm volatile("mfcr %0" : "=r"(regs.ccr));
241 
242 
243 	/*** ldarx ***/
244 
245 	regs.gpr[3] = (unsigned long) &a;
246 	regs.gpr[4] = 0;
247 	regs.gpr[5] = 0x5678;
248 
249 	/* ldarx r5, r3, r4, 0 */
250 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LDARX(5, 3, 4, 0)));
251 
252 	/*
253 	 * Don't touch 'a' here. Touching 'a' can do Load/store
254 	 * of 'a' which result in failure of subsequent stdcx.
255 	 * Instead, use hardcoded value for comparison.
256 	 */
257 	if (stepped <= 0 || regs.gpr[5] != 0x1234) {
258 		show_result("ldarx / stdcx.", "FAIL (ldarx)");
259 		return;
260 	}
261 
262 
263 	/*** stdcx. ***/
264 
265 	regs.gpr[5] = 0x9ABC;
266 
267 	/* stdcx. r5, r3, r4 */
268 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STDCX(5, 3, 4)));
269 
270 	/*
271 	 * Two possible scenarios that indicates successful emulation
272 	 * of stdcx. :
273 	 *  1. Reservation is active and store is performed. In this
274 	 *     case cr0.eq bit will be set to 1.
275 	 *  2. Reservation is not active and store is not performed.
276 	 *     In this case cr0.eq bit will be set to 0.
277 	 */
278 	if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
279 			|| (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
280 		show_result("ldarx / stdcx.", "PASS");
281 	else
282 		show_result("ldarx / stdcx.", "FAIL (stdcx.)");
283 }
284 
285 #ifdef CONFIG_PPC_FPU
test_lfsx_stfsx(void)286 static void __init test_lfsx_stfsx(void)
287 {
288 	struct pt_regs regs;
289 	union {
290 		float a;
291 		int b;
292 	} c;
293 	int cached_b;
294 	int stepped = -1;
295 
296 	init_pt_regs(&regs);
297 
298 
299 	/*** lfsx ***/
300 
301 	c.a = 123.45;
302 	cached_b = c.b;
303 
304 	regs.gpr[3] = (unsigned long) &c.a;
305 	regs.gpr[4] = 0;
306 
307 	/* lfsx frt10, r3, r4 */
308 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LFSX(10, 3, 4)));
309 
310 	if (stepped == 1)
311 		show_result("lfsx", "PASS");
312 	else
313 		show_result("lfsx", "FAIL");
314 
315 
316 	/*** stfsx ***/
317 
318 	c.a = 678.91;
319 
320 	/* stfsx frs10, r3, r4 */
321 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STFSX(10, 3, 4)));
322 
323 	if (stepped == 1 && c.b == cached_b)
324 		show_result("stfsx", "PASS");
325 	else
326 		show_result("stfsx", "FAIL");
327 }
328 
test_plfs_pstfs(void)329 static void __init test_plfs_pstfs(void)
330 {
331 	struct pt_regs regs;
332 	union {
333 		float a;
334 		int b;
335 	} c;
336 	int cached_b;
337 	int stepped = -1;
338 
339 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
340 		show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
341 		return;
342 	}
343 
344 	init_pt_regs(&regs);
345 
346 
347 	/*** plfs ***/
348 
349 	c.a = 123.45;
350 	cached_b = c.b;
351 
352 	regs.gpr[3] = (unsigned long)&c.a;
353 
354 	/* plfs frt10, 0(r3), 0  */
355 	stepped = emulate_step(&regs, TEST_PLFS(10, 3, 0, 0));
356 
357 	if (stepped == 1)
358 		show_result("plfs", "PASS");
359 	else
360 		show_result("plfs", "FAIL");
361 
362 
363 	/*** pstfs ***/
364 
365 	c.a = 678.91;
366 
367 	/* pstfs frs10, 0(r3), 0 */
368 	stepped = emulate_step(&regs, TEST_PSTFS(10, 3, 0, 0));
369 
370 	if (stepped == 1 && c.b == cached_b)
371 		show_result("pstfs", "PASS");
372 	else
373 		show_result("pstfs", "FAIL");
374 }
375 
test_lfdx_stfdx(void)376 static void __init test_lfdx_stfdx(void)
377 {
378 	struct pt_regs regs;
379 	union {
380 		double a;
381 		long b;
382 	} c;
383 	long cached_b;
384 	int stepped = -1;
385 
386 	init_pt_regs(&regs);
387 
388 
389 	/*** lfdx ***/
390 
391 	c.a = 123456.78;
392 	cached_b = c.b;
393 
394 	regs.gpr[3] = (unsigned long) &c.a;
395 	regs.gpr[4] = 0;
396 
397 	/* lfdx frt10, r3, r4 */
398 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LFDX(10, 3, 4)));
399 
400 	if (stepped == 1)
401 		show_result("lfdx", "PASS");
402 	else
403 		show_result("lfdx", "FAIL");
404 
405 
406 	/*** stfdx ***/
407 
408 	c.a = 987654.32;
409 
410 	/* stfdx frs10, r3, r4 */
411 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STFDX(10, 3, 4)));
412 
413 	if (stepped == 1 && c.b == cached_b)
414 		show_result("stfdx", "PASS");
415 	else
416 		show_result("stfdx", "FAIL");
417 }
418 
test_plfd_pstfd(void)419 static void __init test_plfd_pstfd(void)
420 {
421 	struct pt_regs regs;
422 	union {
423 		double a;
424 		long b;
425 	} c;
426 	long cached_b;
427 	int stepped = -1;
428 
429 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
430 		show_result("pld", "SKIP (!CPU_FTR_ARCH_31)");
431 		return;
432 	}
433 
434 	init_pt_regs(&regs);
435 
436 
437 	/*** plfd ***/
438 
439 	c.a = 123456.78;
440 	cached_b = c.b;
441 
442 	regs.gpr[3] = (unsigned long)&c.a;
443 
444 	/* plfd frt10, 0(r3), 0 */
445 	stepped = emulate_step(&regs, TEST_PLFD(10, 3, 0, 0));
446 
447 	if (stepped == 1)
448 		show_result("plfd", "PASS");
449 	else
450 		show_result("plfd", "FAIL");
451 
452 
453 	/*** pstfd ***/
454 
455 	c.a = 987654.32;
456 
457 	/* pstfd frs10, 0(r3), 0 */
458 	stepped = emulate_step(&regs, TEST_PSTFD(10, 3, 0, 0));
459 
460 	if (stepped == 1 && c.b == cached_b)
461 		show_result("pstfd", "PASS");
462 	else
463 		show_result("pstfd", "FAIL");
464 }
465 #else
test_lfsx_stfsx(void)466 static void __init test_lfsx_stfsx(void)
467 {
468 	show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
469 	show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
470 }
471 
test_plfs_pstfs(void)472 static void __init test_plfs_pstfs(void)
473 {
474 	show_result("plfs", "SKIP (CONFIG_PPC_FPU is not set)");
475 	show_result("pstfs", "SKIP (CONFIG_PPC_FPU is not set)");
476 }
477 
test_lfdx_stfdx(void)478 static void __init test_lfdx_stfdx(void)
479 {
480 	show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
481 	show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
482 }
483 
test_plfd_pstfd(void)484 static void __init test_plfd_pstfd(void)
485 {
486 	show_result("plfd", "SKIP (CONFIG_PPC_FPU is not set)");
487 	show_result("pstfd", "SKIP (CONFIG_PPC_FPU is not set)");
488 }
489 #endif /* CONFIG_PPC_FPU */
490 
491 #ifdef CONFIG_ALTIVEC
test_lvx_stvx(void)492 static void __init test_lvx_stvx(void)
493 {
494 	struct pt_regs regs;
495 	union {
496 		vector128 a;
497 		u32 b[4];
498 	} c;
499 	u32 cached_b[4];
500 	int stepped = -1;
501 
502 	init_pt_regs(&regs);
503 
504 
505 	/*** lvx ***/
506 
507 	cached_b[0] = c.b[0] = 923745;
508 	cached_b[1] = c.b[1] = 2139478;
509 	cached_b[2] = c.b[2] = 9012;
510 	cached_b[3] = c.b[3] = 982134;
511 
512 	regs.gpr[3] = (unsigned long) &c.a;
513 	regs.gpr[4] = 0;
514 
515 	/* lvx vrt10, r3, r4 */
516 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LVX(10, 3, 4)));
517 
518 	if (stepped == 1)
519 		show_result("lvx", "PASS");
520 	else
521 		show_result("lvx", "FAIL");
522 
523 
524 	/*** stvx ***/
525 
526 	c.b[0] = 4987513;
527 	c.b[1] = 84313948;
528 	c.b[2] = 71;
529 	c.b[3] = 498532;
530 
531 	/* stvx vrs10, r3, r4 */
532 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STVX(10, 3, 4)));
533 
534 	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
535 	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
536 		show_result("stvx", "PASS");
537 	else
538 		show_result("stvx", "FAIL");
539 }
540 #else
test_lvx_stvx(void)541 static void __init test_lvx_stvx(void)
542 {
543 	show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
544 	show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
545 }
546 #endif /* CONFIG_ALTIVEC */
547 
548 #ifdef CONFIG_VSX
test_lxvd2x_stxvd2x(void)549 static void __init test_lxvd2x_stxvd2x(void)
550 {
551 	struct pt_regs regs;
552 	union {
553 		vector128 a;
554 		u32 b[4];
555 	} c;
556 	u32 cached_b[4];
557 	int stepped = -1;
558 
559 	init_pt_regs(&regs);
560 
561 
562 	/*** lxvd2x ***/
563 
564 	cached_b[0] = c.b[0] = 18233;
565 	cached_b[1] = c.b[1] = 34863571;
566 	cached_b[2] = c.b[2] = 834;
567 	cached_b[3] = c.b[3] = 6138911;
568 
569 	regs.gpr[3] = (unsigned long) &c.a;
570 	regs.gpr[4] = 0;
571 
572 	/* lxvd2x vsr39, r3, r4 */
573 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVD2X(39, R3, R4)));
574 
575 	if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
576 		show_result("lxvd2x", "PASS");
577 	} else {
578 		if (!cpu_has_feature(CPU_FTR_VSX))
579 			show_result("lxvd2x", "PASS (!CPU_FTR_VSX)");
580 		else
581 			show_result("lxvd2x", "FAIL");
582 	}
583 
584 
585 	/*** stxvd2x ***/
586 
587 	c.b[0] = 21379463;
588 	c.b[1] = 87;
589 	c.b[2] = 374234;
590 	c.b[3] = 4;
591 
592 	/* stxvd2x vsr39, r3, r4 */
593 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVD2X(39, R3, R4)));
594 
595 	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
596 	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3] &&
597 	    cpu_has_feature(CPU_FTR_VSX)) {
598 		show_result("stxvd2x", "PASS");
599 	} else {
600 		if (!cpu_has_feature(CPU_FTR_VSX))
601 			show_result("stxvd2x", "PASS (!CPU_FTR_VSX)");
602 		else
603 			show_result("stxvd2x", "FAIL");
604 	}
605 }
606 #else
test_lxvd2x_stxvd2x(void)607 static void __init test_lxvd2x_stxvd2x(void)
608 {
609 	show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
610 	show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
611 }
612 #endif /* CONFIG_VSX */
613 
614 #ifdef CONFIG_VSX
test_lxvp_stxvp(void)615 static void __init test_lxvp_stxvp(void)
616 {
617 	struct pt_regs regs;
618 	union {
619 		vector128 a;
620 		u32 b[4];
621 	} c[2];
622 	u32 cached_b[8];
623 	int stepped = -1;
624 
625 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
626 		show_result("lxvp", "SKIP (!CPU_FTR_ARCH_31)");
627 		show_result("stxvp", "SKIP (!CPU_FTR_ARCH_31)");
628 		return;
629 	}
630 
631 	init_pt_regs(&regs);
632 
633 	/*** lxvp ***/
634 
635 	cached_b[0] = c[0].b[0] = 18233;
636 	cached_b[1] = c[0].b[1] = 34863571;
637 	cached_b[2] = c[0].b[2] = 834;
638 	cached_b[3] = c[0].b[3] = 6138911;
639 	cached_b[4] = c[1].b[0] = 1234;
640 	cached_b[5] = c[1].b[1] = 5678;
641 	cached_b[6] = c[1].b[2] = 91011;
642 	cached_b[7] = c[1].b[3] = 121314;
643 
644 	regs.gpr[4] = (unsigned long)&c[0].a;
645 
646 	/*
647 	 * lxvp XTp,DQ(RA)
648 	 * XTp = 32xTX + 2xTp
649 	 * let TX=1 Tp=1 RA=4 DQ=0
650 	 */
651 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVP(34, 4, 0)));
652 
653 	if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
654 		show_result("lxvp", "PASS");
655 	} else {
656 		if (!cpu_has_feature(CPU_FTR_VSX))
657 			show_result("lxvp", "PASS (!CPU_FTR_VSX)");
658 		else
659 			show_result("lxvp", "FAIL");
660 	}
661 
662 	/*** stxvp ***/
663 
664 	c[0].b[0] = 21379463;
665 	c[0].b[1] = 87;
666 	c[0].b[2] = 374234;
667 	c[0].b[3] = 4;
668 	c[1].b[0] = 90;
669 	c[1].b[1] = 122;
670 	c[1].b[2] = 555;
671 	c[1].b[3] = 32144;
672 
673 	/*
674 	 * stxvp XSp,DQ(RA)
675 	 * XSp = 32xSX + 2xSp
676 	 * let SX=1 Sp=1 RA=4 DQ=0
677 	 */
678 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVP(34, 4, 0)));
679 
680 	if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
681 	    cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
682 	    cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
683 	    cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
684 	    cpu_has_feature(CPU_FTR_VSX)) {
685 		show_result("stxvp", "PASS");
686 	} else {
687 		if (!cpu_has_feature(CPU_FTR_VSX))
688 			show_result("stxvp", "PASS (!CPU_FTR_VSX)");
689 		else
690 			show_result("stxvp", "FAIL");
691 	}
692 }
693 #else
test_lxvp_stxvp(void)694 static void __init test_lxvp_stxvp(void)
695 {
696 	show_result("lxvp", "SKIP (CONFIG_VSX is not set)");
697 	show_result("stxvp", "SKIP (CONFIG_VSX is not set)");
698 }
699 #endif /* CONFIG_VSX */
700 
701 #ifdef CONFIG_VSX
test_lxvpx_stxvpx(void)702 static void __init test_lxvpx_stxvpx(void)
703 {
704 	struct pt_regs regs;
705 	union {
706 		vector128 a;
707 		u32 b[4];
708 	} c[2];
709 	u32 cached_b[8];
710 	int stepped = -1;
711 
712 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
713 		show_result("lxvpx", "SKIP (!CPU_FTR_ARCH_31)");
714 		show_result("stxvpx", "SKIP (!CPU_FTR_ARCH_31)");
715 		return;
716 	}
717 
718 	init_pt_regs(&regs);
719 
720 	/*** lxvpx ***/
721 
722 	cached_b[0] = c[0].b[0] = 18233;
723 	cached_b[1] = c[0].b[1] = 34863571;
724 	cached_b[2] = c[0].b[2] = 834;
725 	cached_b[3] = c[0].b[3] = 6138911;
726 	cached_b[4] = c[1].b[0] = 1234;
727 	cached_b[5] = c[1].b[1] = 5678;
728 	cached_b[6] = c[1].b[2] = 91011;
729 	cached_b[7] = c[1].b[3] = 121314;
730 
731 	regs.gpr[3] = (unsigned long)&c[0].a;
732 	regs.gpr[4] = 0;
733 
734 	/*
735 	 * lxvpx XTp,RA,RB
736 	 * XTp = 32xTX + 2xTp
737 	 * let TX=1 Tp=1 RA=3 RB=4
738 	 */
739 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_LXVPX(34, 3, 4)));
740 
741 	if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
742 		show_result("lxvpx", "PASS");
743 	} else {
744 		if (!cpu_has_feature(CPU_FTR_VSX))
745 			show_result("lxvpx", "PASS (!CPU_FTR_VSX)");
746 		else
747 			show_result("lxvpx", "FAIL");
748 	}
749 
750 	/*** stxvpx ***/
751 
752 	c[0].b[0] = 21379463;
753 	c[0].b[1] = 87;
754 	c[0].b[2] = 374234;
755 	c[0].b[3] = 4;
756 	c[1].b[0] = 90;
757 	c[1].b[1] = 122;
758 	c[1].b[2] = 555;
759 	c[1].b[3] = 32144;
760 
761 	/*
762 	 * stxvpx XSp,RA,RB
763 	 * XSp = 32xSX + 2xSp
764 	 * let SX=1 Sp=1 RA=3 RB=4
765 	 */
766 	stepped = emulate_step(&regs, ppc_inst(PPC_RAW_STXVPX(34, 3, 4)));
767 
768 	if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
769 	    cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
770 	    cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
771 	    cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
772 	    cpu_has_feature(CPU_FTR_VSX)) {
773 		show_result("stxvpx", "PASS");
774 	} else {
775 		if (!cpu_has_feature(CPU_FTR_VSX))
776 			show_result("stxvpx", "PASS (!CPU_FTR_VSX)");
777 		else
778 			show_result("stxvpx", "FAIL");
779 	}
780 }
781 #else
test_lxvpx_stxvpx(void)782 static void __init test_lxvpx_stxvpx(void)
783 {
784 	show_result("lxvpx", "SKIP (CONFIG_VSX is not set)");
785 	show_result("stxvpx", "SKIP (CONFIG_VSX is not set)");
786 }
787 #endif /* CONFIG_VSX */
788 
789 #ifdef CONFIG_VSX
test_plxvp_pstxvp(void)790 static void __init test_plxvp_pstxvp(void)
791 {
792 	ppc_inst_t instr;
793 	struct pt_regs regs;
794 	union {
795 		vector128 a;
796 		u32 b[4];
797 	} c[2];
798 	u32 cached_b[8];
799 	int stepped = -1;
800 
801 	if (!cpu_has_feature(CPU_FTR_ARCH_31)) {
802 		show_result("plxvp", "SKIP (!CPU_FTR_ARCH_31)");
803 		show_result("pstxvp", "SKIP (!CPU_FTR_ARCH_31)");
804 		return;
805 	}
806 
807 	/*** plxvp ***/
808 
809 	cached_b[0] = c[0].b[0] = 18233;
810 	cached_b[1] = c[0].b[1] = 34863571;
811 	cached_b[2] = c[0].b[2] = 834;
812 	cached_b[3] = c[0].b[3] = 6138911;
813 	cached_b[4] = c[1].b[0] = 1234;
814 	cached_b[5] = c[1].b[1] = 5678;
815 	cached_b[6] = c[1].b[2] = 91011;
816 	cached_b[7] = c[1].b[3] = 121314;
817 
818 	init_pt_regs(&regs);
819 	regs.gpr[3] = (unsigned long)&c[0].a;
820 
821 	/*
822 	 * plxvp XTp,D(RA),R
823 	 * XTp = 32xTX + 2xTp
824 	 * let RA=3 R=0 D=d0||d1=0 R=0 Tp=1 TX=1
825 	 */
826 	instr = ppc_inst_prefix(PPC_RAW_PLXVP_P(34, 0, 3, 0), PPC_RAW_PLXVP_S(34, 0, 3, 0));
827 
828 	stepped = emulate_step(&regs, instr);
829 	if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) {
830 		show_result("plxvp", "PASS");
831 	} else {
832 		if (!cpu_has_feature(CPU_FTR_VSX))
833 			show_result("plxvp", "PASS (!CPU_FTR_VSX)");
834 		else
835 			show_result("plxvp", "FAIL");
836 	}
837 
838 	/*** pstxvp ***/
839 
840 	c[0].b[0] = 21379463;
841 	c[0].b[1] = 87;
842 	c[0].b[2] = 374234;
843 	c[0].b[3] = 4;
844 	c[1].b[0] = 90;
845 	c[1].b[1] = 122;
846 	c[1].b[2] = 555;
847 	c[1].b[3] = 32144;
848 
849 	/*
850 	 * pstxvp XSp,D(RA),R
851 	 * XSp = 32xSX + 2xSp
852 	 * let RA=3 D=d0||d1=0 R=0 Sp=1 SX=1
853 	 */
854 	instr = ppc_inst_prefix(PPC_RAW_PSTXVP_P(34, 0, 3, 0), PPC_RAW_PSTXVP_S(34, 0, 3, 0));
855 
856 	stepped = emulate_step(&regs, instr);
857 
858 	if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] &&
859 	    cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] &&
860 	    cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] &&
861 	    cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] &&
862 	    cpu_has_feature(CPU_FTR_VSX)) {
863 		show_result("pstxvp", "PASS");
864 	} else {
865 		if (!cpu_has_feature(CPU_FTR_VSX))
866 			show_result("pstxvp", "PASS (!CPU_FTR_VSX)");
867 		else
868 			show_result("pstxvp", "FAIL");
869 	}
870 }
871 #else
test_plxvp_pstxvp(void)872 static void __init test_plxvp_pstxvp(void)
873 {
874 	show_result("plxvp", "SKIP (CONFIG_VSX is not set)");
875 	show_result("pstxvp", "SKIP (CONFIG_VSX is not set)");
876 }
877 #endif /* CONFIG_VSX */
878 
run_tests_load_store(void)879 static void __init run_tests_load_store(void)
880 {
881 	test_ld();
882 	test_pld();
883 	test_lwz();
884 	test_plwz();
885 	test_lwzx();
886 	test_std();
887 	test_pstd();
888 	test_ldarx_stdcx();
889 	test_lfsx_stfsx();
890 	test_plfs_pstfs();
891 	test_lfdx_stfdx();
892 	test_plfd_pstfd();
893 	test_lvx_stvx();
894 	test_lxvd2x_stxvd2x();
895 	test_lxvp_stxvp();
896 	test_lxvpx_stxvpx();
897 	test_plxvp_pstxvp();
898 }
899 
900 struct compute_test {
901 	char *mnemonic;
902 	unsigned long cpu_feature;
903 	struct {
904 		char *descr;
905 		unsigned long flags;
906 		ppc_inst_t instr;
907 		struct pt_regs regs;
908 	} subtests[MAX_SUBTESTS + 1];
909 };
910 
911 /* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */
912 #define SI_MIN BIT(33)
913 #define SI_MAX (BIT(33) - 1)
914 #define SI_UMAX (BIT(34) - 1)
915 
916 static struct compute_test compute_tests[] = {
917 	{
918 		.mnemonic = "nop",
919 		.subtests = {
920 			{
921 				.descr = "R0 = LONG_MAX",
922 				.instr = ppc_inst(PPC_RAW_NOP()),
923 				.regs = {
924 					.gpr[0] = LONG_MAX,
925 				}
926 			}
927 		}
928 	},
929 	{
930 		.mnemonic = "setb",
931 		.cpu_feature = CPU_FTR_ARCH_300,
932 		.subtests = {
933 			{
934 				.descr = "BFA = 1, CR = GT",
935 				.instr = ppc_inst(PPC_RAW_SETB(20, 1)),
936 				.regs = {
937 					.ccr = 0x4000000,
938 				}
939 			},
940 			{
941 				.descr = "BFA = 4, CR = LT",
942 				.instr = ppc_inst(PPC_RAW_SETB(20, 4)),
943 				.regs = {
944 					.ccr = 0x8000,
945 				}
946 			},
947 			{
948 				.descr = "BFA = 5, CR = EQ",
949 				.instr = ppc_inst(PPC_RAW_SETB(20, 5)),
950 				.regs = {
951 					.ccr = 0x200,
952 				}
953 			}
954 		}
955 	},
956 	{
957 		.mnemonic = "add",
958 		.subtests = {
959 			{
960 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
961 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
962 				.regs = {
963 					.gpr[21] = LONG_MIN,
964 					.gpr[22] = LONG_MIN,
965 				}
966 			},
967 			{
968 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
969 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
970 				.regs = {
971 					.gpr[21] = LONG_MIN,
972 					.gpr[22] = LONG_MAX,
973 				}
974 			},
975 			{
976 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
977 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
978 				.regs = {
979 					.gpr[21] = LONG_MAX,
980 					.gpr[22] = LONG_MAX,
981 				}
982 			},
983 			{
984 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
985 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
986 				.regs = {
987 					.gpr[21] = ULONG_MAX,
988 					.gpr[22] = ULONG_MAX,
989 				}
990 			},
991 			{
992 				.descr = "RA = ULONG_MAX, RB = 0x1",
993 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
994 				.regs = {
995 					.gpr[21] = ULONG_MAX,
996 					.gpr[22] = 0x1,
997 				}
998 			},
999 			{
1000 				.descr = "RA = INT_MIN, RB = INT_MIN",
1001 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1002 				.regs = {
1003 					.gpr[21] = INT_MIN,
1004 					.gpr[22] = INT_MIN,
1005 				}
1006 			},
1007 			{
1008 				.descr = "RA = INT_MIN, RB = INT_MAX",
1009 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1010 				.regs = {
1011 					.gpr[21] = INT_MIN,
1012 					.gpr[22] = INT_MAX,
1013 				}
1014 			},
1015 			{
1016 				.descr = "RA = INT_MAX, RB = INT_MAX",
1017 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1018 				.regs = {
1019 					.gpr[21] = INT_MAX,
1020 					.gpr[22] = INT_MAX,
1021 				}
1022 			},
1023 			{
1024 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
1025 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1026 				.regs = {
1027 					.gpr[21] = UINT_MAX,
1028 					.gpr[22] = UINT_MAX,
1029 				}
1030 			},
1031 			{
1032 				.descr = "RA = UINT_MAX, RB = 0x1",
1033 				.instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)),
1034 				.regs = {
1035 					.gpr[21] = UINT_MAX,
1036 					.gpr[22] = 0x1,
1037 				}
1038 			}
1039 		}
1040 	},
1041 	{
1042 		.mnemonic = "add.",
1043 		.subtests = {
1044 			{
1045 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1046 				.flags = IGNORE_CCR,
1047 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1048 				.regs = {
1049 					.gpr[21] = LONG_MIN,
1050 					.gpr[22] = LONG_MIN,
1051 				}
1052 			},
1053 			{
1054 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1055 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1056 				.regs = {
1057 					.gpr[21] = LONG_MIN,
1058 					.gpr[22] = LONG_MAX,
1059 				}
1060 			},
1061 			{
1062 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
1063 				.flags = IGNORE_CCR,
1064 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1065 				.regs = {
1066 					.gpr[21] = LONG_MAX,
1067 					.gpr[22] = LONG_MAX,
1068 				}
1069 			},
1070 			{
1071 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1072 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1073 				.regs = {
1074 					.gpr[21] = ULONG_MAX,
1075 					.gpr[22] = ULONG_MAX,
1076 				}
1077 			},
1078 			{
1079 				.descr = "RA = ULONG_MAX, RB = 0x1",
1080 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1081 				.regs = {
1082 					.gpr[21] = ULONG_MAX,
1083 					.gpr[22] = 0x1,
1084 				}
1085 			},
1086 			{
1087 				.descr = "RA = INT_MIN, RB = INT_MIN",
1088 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1089 				.regs = {
1090 					.gpr[21] = INT_MIN,
1091 					.gpr[22] = INT_MIN,
1092 				}
1093 			},
1094 			{
1095 				.descr = "RA = INT_MIN, RB = INT_MAX",
1096 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1097 				.regs = {
1098 					.gpr[21] = INT_MIN,
1099 					.gpr[22] = INT_MAX,
1100 				}
1101 			},
1102 			{
1103 				.descr = "RA = INT_MAX, RB = INT_MAX",
1104 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1105 				.regs = {
1106 					.gpr[21] = INT_MAX,
1107 					.gpr[22] = INT_MAX,
1108 				}
1109 			},
1110 			{
1111 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
1112 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1113 				.regs = {
1114 					.gpr[21] = UINT_MAX,
1115 					.gpr[22] = UINT_MAX,
1116 				}
1117 			},
1118 			{
1119 				.descr = "RA = UINT_MAX, RB = 0x1",
1120 				.instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)),
1121 				.regs = {
1122 					.gpr[21] = UINT_MAX,
1123 					.gpr[22] = 0x1,
1124 				}
1125 			}
1126 		}
1127 	},
1128 	{
1129 		.mnemonic = "addc",
1130 		.subtests = {
1131 			{
1132 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1133 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1134 				.regs = {
1135 					.gpr[21] = LONG_MIN,
1136 					.gpr[22] = LONG_MIN,
1137 				}
1138 			},
1139 			{
1140 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1141 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1142 				.regs = {
1143 					.gpr[21] = LONG_MIN,
1144 					.gpr[22] = LONG_MAX,
1145 				}
1146 			},
1147 			{
1148 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
1149 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1150 				.regs = {
1151 					.gpr[21] = LONG_MAX,
1152 					.gpr[22] = LONG_MAX,
1153 				}
1154 			},
1155 			{
1156 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1157 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1158 				.regs = {
1159 					.gpr[21] = ULONG_MAX,
1160 					.gpr[22] = ULONG_MAX,
1161 				}
1162 			},
1163 			{
1164 				.descr = "RA = ULONG_MAX, RB = 0x1",
1165 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1166 				.regs = {
1167 					.gpr[21] = ULONG_MAX,
1168 					.gpr[22] = 0x1,
1169 				}
1170 			},
1171 			{
1172 				.descr = "RA = INT_MIN, RB = INT_MIN",
1173 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1174 				.regs = {
1175 					.gpr[21] = INT_MIN,
1176 					.gpr[22] = INT_MIN,
1177 				}
1178 			},
1179 			{
1180 				.descr = "RA = INT_MIN, RB = INT_MAX",
1181 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1182 				.regs = {
1183 					.gpr[21] = INT_MIN,
1184 					.gpr[22] = INT_MAX,
1185 				}
1186 			},
1187 			{
1188 				.descr = "RA = INT_MAX, RB = INT_MAX",
1189 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1190 				.regs = {
1191 					.gpr[21] = INT_MAX,
1192 					.gpr[22] = INT_MAX,
1193 				}
1194 			},
1195 			{
1196 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
1197 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1198 				.regs = {
1199 					.gpr[21] = UINT_MAX,
1200 					.gpr[22] = UINT_MAX,
1201 				}
1202 			},
1203 			{
1204 				.descr = "RA = UINT_MAX, RB = 0x1",
1205 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1206 				.regs = {
1207 					.gpr[21] = UINT_MAX,
1208 					.gpr[22] = 0x1,
1209 				}
1210 			},
1211 			{
1212 				.descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1213 				.instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)),
1214 				.regs = {
1215 					.gpr[21] = LONG_MIN | (uint)INT_MIN,
1216 					.gpr[22] = LONG_MIN | (uint)INT_MIN,
1217 				}
1218 			}
1219 		}
1220 	},
1221 	{
1222 		.mnemonic = "addc.",
1223 		.subtests = {
1224 			{
1225 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1226 				.flags = IGNORE_CCR,
1227 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1228 				.regs = {
1229 					.gpr[21] = LONG_MIN,
1230 					.gpr[22] = LONG_MIN,
1231 				}
1232 			},
1233 			{
1234 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1235 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1236 				.regs = {
1237 					.gpr[21] = LONG_MIN,
1238 					.gpr[22] = LONG_MAX,
1239 				}
1240 			},
1241 			{
1242 				.descr = "RA = LONG_MAX, RB = LONG_MAX",
1243 				.flags = IGNORE_CCR,
1244 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1245 				.regs = {
1246 					.gpr[21] = LONG_MAX,
1247 					.gpr[22] = LONG_MAX,
1248 				}
1249 			},
1250 			{
1251 				.descr = "RA = ULONG_MAX, RB = ULONG_MAX",
1252 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1253 				.regs = {
1254 					.gpr[21] = ULONG_MAX,
1255 					.gpr[22] = ULONG_MAX,
1256 				}
1257 			},
1258 			{
1259 				.descr = "RA = ULONG_MAX, RB = 0x1",
1260 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1261 				.regs = {
1262 					.gpr[21] = ULONG_MAX,
1263 					.gpr[22] = 0x1,
1264 				}
1265 			},
1266 			{
1267 				.descr = "RA = INT_MIN, RB = INT_MIN",
1268 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1269 				.regs = {
1270 					.gpr[21] = INT_MIN,
1271 					.gpr[22] = INT_MIN,
1272 				}
1273 			},
1274 			{
1275 				.descr = "RA = INT_MIN, RB = INT_MAX",
1276 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1277 				.regs = {
1278 					.gpr[21] = INT_MIN,
1279 					.gpr[22] = INT_MAX,
1280 				}
1281 			},
1282 			{
1283 				.descr = "RA = INT_MAX, RB = INT_MAX",
1284 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1285 				.regs = {
1286 					.gpr[21] = INT_MAX,
1287 					.gpr[22] = INT_MAX,
1288 				}
1289 			},
1290 			{
1291 				.descr = "RA = UINT_MAX, RB = UINT_MAX",
1292 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1293 				.regs = {
1294 					.gpr[21] = UINT_MAX,
1295 					.gpr[22] = UINT_MAX,
1296 				}
1297 			},
1298 			{
1299 				.descr = "RA = UINT_MAX, RB = 0x1",
1300 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1301 				.regs = {
1302 					.gpr[21] = UINT_MAX,
1303 					.gpr[22] = 0x1,
1304 				}
1305 			},
1306 			{
1307 				.descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN",
1308 				.instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)),
1309 				.regs = {
1310 					.gpr[21] = LONG_MIN | (uint)INT_MIN,
1311 					.gpr[22] = LONG_MIN | (uint)INT_MIN,
1312 				}
1313 			}
1314 		}
1315 	},
1316 	{
1317 		.mnemonic = "divde",
1318 		.subtests = {
1319 			{
1320 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1321 				.instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1322 				.regs = {
1323 					.gpr[21] = LONG_MIN,
1324 					.gpr[22] = LONG_MIN,
1325 				}
1326 			},
1327 			{
1328 				.descr = "RA = 1L, RB = 0",
1329 				.instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1330 				.flags = IGNORE_GPR(20),
1331 				.regs = {
1332 					.gpr[21] = 1L,
1333 					.gpr[22] = 0,
1334 				}
1335 			},
1336 			{
1337 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1338 				.instr = ppc_inst(PPC_RAW_DIVDE(20, 21, 22)),
1339 				.regs = {
1340 					.gpr[21] = LONG_MIN,
1341 					.gpr[22] = LONG_MAX,
1342 				}
1343 			}
1344 		}
1345 	},
1346 	{
1347 		.mnemonic = "divde.",
1348 		.subtests = {
1349 			{
1350 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1351 				.instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1352 				.regs = {
1353 					.gpr[21] = LONG_MIN,
1354 					.gpr[22] = LONG_MIN,
1355 				}
1356 			},
1357 			{
1358 				.descr = "RA = 1L, RB = 0",
1359 				.instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1360 				.flags = IGNORE_GPR(20),
1361 				.regs = {
1362 					.gpr[21] = 1L,
1363 					.gpr[22] = 0,
1364 				}
1365 			},
1366 			{
1367 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1368 				.instr = ppc_inst(PPC_RAW_DIVDE_DOT(20, 21, 22)),
1369 				.regs = {
1370 					.gpr[21] = LONG_MIN,
1371 					.gpr[22] = LONG_MAX,
1372 				}
1373 			}
1374 		}
1375 	},
1376 	{
1377 		.mnemonic = "divdeu",
1378 		.subtests = {
1379 			{
1380 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1381 				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1382 				.flags = IGNORE_GPR(20),
1383 				.regs = {
1384 					.gpr[21] = LONG_MIN,
1385 					.gpr[22] = LONG_MIN,
1386 				}
1387 			},
1388 			{
1389 				.descr = "RA = 1L, RB = 0",
1390 				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1391 				.flags = IGNORE_GPR(20),
1392 				.regs = {
1393 					.gpr[21] = 1L,
1394 					.gpr[22] = 0,
1395 				}
1396 			},
1397 			{
1398 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1399 				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1400 				.regs = {
1401 					.gpr[21] = LONG_MIN,
1402 					.gpr[22] = LONG_MAX,
1403 				}
1404 			},
1405 			{
1406 				.descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1407 				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1408 				.regs = {
1409 					.gpr[21] = LONG_MAX - 1,
1410 					.gpr[22] = LONG_MAX,
1411 				}
1412 			},
1413 			{
1414 				.descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1415 				.instr = ppc_inst(PPC_RAW_DIVDEU(20, 21, 22)),
1416 				.flags = IGNORE_GPR(20),
1417 				.regs = {
1418 					.gpr[21] = LONG_MIN + 1,
1419 					.gpr[22] = LONG_MIN,
1420 				}
1421 			}
1422 		}
1423 	},
1424 	{
1425 		.mnemonic = "divdeu.",
1426 		.subtests = {
1427 			{
1428 				.descr = "RA = LONG_MIN, RB = LONG_MIN",
1429 				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1430 				.flags = IGNORE_GPR(20),
1431 				.regs = {
1432 					.gpr[21] = LONG_MIN,
1433 					.gpr[22] = LONG_MIN,
1434 				}
1435 			},
1436 			{
1437 				.descr = "RA = 1L, RB = 0",
1438 				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1439 				.flags = IGNORE_GPR(20),
1440 				.regs = {
1441 					.gpr[21] = 1L,
1442 					.gpr[22] = 0,
1443 				}
1444 			},
1445 			{
1446 				.descr = "RA = LONG_MIN, RB = LONG_MAX",
1447 				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1448 				.regs = {
1449 					.gpr[21] = LONG_MIN,
1450 					.gpr[22] = LONG_MAX,
1451 				}
1452 			},
1453 			{
1454 				.descr = "RA = LONG_MAX - 1, RB = LONG_MAX",
1455 				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1456 				.regs = {
1457 					.gpr[21] = LONG_MAX - 1,
1458 					.gpr[22] = LONG_MAX,
1459 				}
1460 			},
1461 			{
1462 				.descr = "RA = LONG_MIN + 1, RB = LONG_MIN",
1463 				.instr = ppc_inst(PPC_RAW_DIVDEU_DOT(20, 21, 22)),
1464 				.flags = IGNORE_GPR(20),
1465 				.regs = {
1466 					.gpr[21] = LONG_MIN + 1,
1467 					.gpr[22] = LONG_MIN,
1468 				}
1469 			}
1470 		}
1471 	},
1472 	{
1473 		.mnemonic = "paddi",
1474 		.cpu_feature = CPU_FTR_ARCH_31,
1475 		.subtests = {
1476 			{
1477 				.descr = "RA = LONG_MIN, SI = SI_MIN, R = 0",
1478 				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1479 				.regs = {
1480 					.gpr[21] = 0,
1481 					.gpr[22] = LONG_MIN,
1482 				}
1483 			},
1484 			{
1485 				.descr = "RA = LONG_MIN, SI = SI_MAX, R = 0",
1486 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1487 				.regs = {
1488 					.gpr[21] = 0,
1489 					.gpr[22] = LONG_MIN,
1490 				}
1491 			},
1492 			{
1493 				.descr = "RA = LONG_MAX, SI = SI_MAX, R = 0",
1494 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1495 				.regs = {
1496 					.gpr[21] = 0,
1497 					.gpr[22] = LONG_MAX,
1498 				}
1499 			},
1500 			{
1501 				.descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0",
1502 				.instr = TEST_PADDI(21, 22, SI_UMAX, 0),
1503 				.regs = {
1504 					.gpr[21] = 0,
1505 					.gpr[22] = ULONG_MAX,
1506 				}
1507 			},
1508 			{
1509 				.descr = "RA = ULONG_MAX, SI = 0x1, R = 0",
1510 				.instr = TEST_PADDI(21, 22, 0x1, 0),
1511 				.regs = {
1512 					.gpr[21] = 0,
1513 					.gpr[22] = ULONG_MAX,
1514 				}
1515 			},
1516 			{
1517 				.descr = "RA = INT_MIN, SI = SI_MIN, R = 0",
1518 				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1519 				.regs = {
1520 					.gpr[21] = 0,
1521 					.gpr[22] = INT_MIN,
1522 				}
1523 			},
1524 			{
1525 				.descr = "RA = INT_MIN, SI = SI_MAX, R = 0",
1526 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1527 				.regs = {
1528 					.gpr[21] = 0,
1529 					.gpr[22] = INT_MIN,
1530 				}
1531 			},
1532 			{
1533 				.descr = "RA = INT_MAX, SI = SI_MAX, R = 0",
1534 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1535 				.regs = {
1536 					.gpr[21] = 0,
1537 					.gpr[22] = INT_MAX,
1538 				}
1539 			},
1540 			{
1541 				.descr = "RA = UINT_MAX, SI = 0x1, R = 0",
1542 				.instr = TEST_PADDI(21, 22, 0x1, 0),
1543 				.regs = {
1544 					.gpr[21] = 0,
1545 					.gpr[22] = UINT_MAX,
1546 				}
1547 			},
1548 			{
1549 				.descr = "RA = UINT_MAX, SI = SI_MAX, R = 0",
1550 				.instr = TEST_PADDI(21, 22, SI_MAX, 0),
1551 				.regs = {
1552 					.gpr[21] = 0,
1553 					.gpr[22] = UINT_MAX,
1554 				}
1555 			},
1556 			{
1557 				.descr = "RA is r0, SI = SI_MIN, R = 0",
1558 				.instr = TEST_PADDI(21, 0, SI_MIN, 0),
1559 				.regs = {
1560 					.gpr[21] = 0x0,
1561 				}
1562 			},
1563 			{
1564 				.descr = "RA = 0, SI = SI_MIN, R = 0",
1565 				.instr = TEST_PADDI(21, 22, SI_MIN, 0),
1566 				.regs = {
1567 					.gpr[21] = 0x0,
1568 					.gpr[22] = 0x0,
1569 				}
1570 			},
1571 			{
1572 				.descr = "RA is r0, SI = 0, R = 1",
1573 				.instr = TEST_PADDI(21, 0, 0, 1),
1574 				.regs = {
1575 					.gpr[21] = 0,
1576 				}
1577 			},
1578 			{
1579 				.descr = "RA is r0, SI = SI_MIN, R = 1",
1580 				.instr = TEST_PADDI(21, 0, SI_MIN, 1),
1581 				.regs = {
1582 					.gpr[21] = 0,
1583 				}
1584 			},
1585 			/* Invalid instruction form with R = 1 and RA != 0 */
1586 			{
1587 				.descr = "RA = R22(0), SI = 0, R = 1",
1588 				.instr = TEST_PADDI(21, 22, 0, 1),
1589 				.flags = NEGATIVE_TEST,
1590 				.regs = {
1591 					.gpr[21] = 0,
1592 					.gpr[22] = 0,
1593 				}
1594 			}
1595 		}
1596 	}
1597 };
1598 
emulate_compute_instr(struct pt_regs * regs,ppc_inst_t instr,bool negative)1599 static int __init emulate_compute_instr(struct pt_regs *regs,
1600 					ppc_inst_t instr,
1601 					bool negative)
1602 {
1603 	int analysed;
1604 	struct instruction_op op;
1605 
1606 	if (!regs || !ppc_inst_val(instr))
1607 		return -EINVAL;
1608 
1609 	/* This is not a return frame regs */
1610 	regs->nip = patch_site_addr(&patch__exec_instr);
1611 
1612 	analysed = analyse_instr(&op, regs, instr);
1613 	if (analysed != 1 || GETTYPE(op.type) != COMPUTE) {
1614 		if (negative)
1615 			return -EFAULT;
1616 		pr_info("emulation failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1617 		return -EFAULT;
1618 	}
1619 	if (analysed == 1 && negative)
1620 		pr_info("negative test failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1621 	if (!negative)
1622 		emulate_update_regs(regs, &op);
1623 	return 0;
1624 }
1625 
execute_compute_instr(struct pt_regs * regs,ppc_inst_t instr)1626 static int __init execute_compute_instr(struct pt_regs *regs,
1627 					ppc_inst_t instr)
1628 {
1629 	extern int exec_instr(struct pt_regs *regs);
1630 
1631 	if (!regs || !ppc_inst_val(instr))
1632 		return -EINVAL;
1633 
1634 	/* Patch the NOP with the actual instruction */
1635 	patch_instruction_site(&patch__exec_instr, instr);
1636 	if (exec_instr(regs)) {
1637 		pr_info("execution failed, instruction = %08lx\n", ppc_inst_as_ulong(instr));
1638 		return -EFAULT;
1639 	}
1640 
1641 	return 0;
1642 }
1643 
1644 #define gpr_mismatch(gprn, exp, got)	\
1645 	pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n",	\
1646 		gprn, exp, got)
1647 
1648 #define reg_mismatch(name, exp, got)	\
1649 	pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n",	\
1650 		name, exp, got)
1651 
run_tests_compute(void)1652 static void __init run_tests_compute(void)
1653 {
1654 	unsigned long flags;
1655 	struct compute_test *test;
1656 	struct pt_regs *regs, exp, got;
1657 	unsigned int i, j, k;
1658 	ppc_inst_t instr;
1659 	bool ignore_gpr, ignore_xer, ignore_ccr, passed, rc, negative;
1660 
1661 	for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
1662 		test = &compute_tests[i];
1663 
1664 		if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) {
1665 			show_result(test->mnemonic, "SKIP (!CPU_FTR)");
1666 			continue;
1667 		}
1668 
1669 		for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) {
1670 			instr = test->subtests[j].instr;
1671 			flags = test->subtests[j].flags;
1672 			regs = &test->subtests[j].regs;
1673 			negative = flags & NEGATIVE_TEST;
1674 			ignore_xer = flags & IGNORE_XER;
1675 			ignore_ccr = flags & IGNORE_CCR;
1676 			passed = true;
1677 
1678 			memcpy(&exp, regs, sizeof(struct pt_regs));
1679 			memcpy(&got, regs, sizeof(struct pt_regs));
1680 
1681 			/*
1682 			 * Set a compatible MSR value explicitly to ensure
1683 			 * that XER and CR bits are updated appropriately
1684 			 */
1685 			exp.msr = MSR_KERNEL;
1686 			got.msr = MSR_KERNEL;
1687 
1688 			rc = emulate_compute_instr(&got, instr, negative) != 0;
1689 			if (negative) {
1690 				/* skip executing instruction */
1691 				passed = rc;
1692 				goto print;
1693 			} else if (rc || execute_compute_instr(&exp, instr)) {
1694 				passed = false;
1695 				goto print;
1696 			}
1697 
1698 			/* Verify GPR values */
1699 			for (k = 0; k < 32; k++) {
1700 				ignore_gpr = flags & IGNORE_GPR(k);
1701 				if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) {
1702 					passed = false;
1703 					gpr_mismatch(k, exp.gpr[k], got.gpr[k]);
1704 				}
1705 			}
1706 
1707 			/* Verify LR value */
1708 			if (exp.link != got.link) {
1709 				passed = false;
1710 				reg_mismatch("LR", exp.link, got.link);
1711 			}
1712 
1713 			/* Verify XER value */
1714 			if (!ignore_xer && exp.xer != got.xer) {
1715 				passed = false;
1716 				reg_mismatch("XER", exp.xer, got.xer);
1717 			}
1718 
1719 			/* Verify CR value */
1720 			if (!ignore_ccr && exp.ccr != got.ccr) {
1721 				passed = false;
1722 				reg_mismatch("CR", exp.ccr, got.ccr);
1723 			}
1724 
1725 print:
1726 			show_result_with_descr(test->mnemonic,
1727 					       test->subtests[j].descr,
1728 					       passed ? "PASS" : "FAIL");
1729 		}
1730 	}
1731 }
1732 
test_emulate_step(void)1733 static int __init test_emulate_step(void)
1734 {
1735 	printk(KERN_INFO "Running instruction emulation self-tests ...\n");
1736 	run_tests_load_store();
1737 	run_tests_compute();
1738 
1739 	return 0;
1740 }
1741 late_initcall(test_emulate_step);
1742