1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Simple sanity tests for instruction emulation infrastructure. 4 * 5 * Copyright IBM Corp. 2016 6 */ 7 8 #define pr_fmt(fmt) "emulate_step_test: " fmt 9 10 #include <linux/ptrace.h> 11 #include <asm/sstep.h> 12 #include <asm/ppc-opcode.h> 13 #include <asm/code-patching.h> 14 #include <asm/inst.h> 15 16 #define MAX_SUBTESTS 16 17 18 #define IGNORE_GPR(n) (0x1UL << (n)) 19 #define IGNORE_XER (0x1UL << 32) 20 #define IGNORE_CCR (0x1UL << 33) 21 22 #define TEST_PLD(r, base, i, pr) \ 23 ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \ 24 PPC_INST_PLD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) 25 26 #define TEST_PLWZ(r, base, i, pr) \ 27 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \ 28 PPC_RAW_LWZ(r, base, i)) 29 30 #define TEST_PSTD(r, base, i, pr) \ 31 ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \ 32 PPC_INST_PSTD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) 33 34 #define TEST_PLFS(r, base, i, pr) \ 35 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \ 36 PPC_INST_LFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) 37 38 #define TEST_PSTFS(r, base, i, pr) \ 39 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \ 40 PPC_INST_STFS | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) 41 42 #define TEST_PLFD(r, base, i, pr) \ 43 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \ 44 PPC_INST_LFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) 45 46 #define TEST_PSTFD(r, base, i, pr) \ 47 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \ 48 PPC_INST_STFD | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) 49 50 #define TEST_PADDI(t, a, i, pr) \ 51 ppc_inst_prefix(PPC_PREFIX_MLS | __PPC_PRFX_R(pr) | IMM_H(i), \ 52 PPC_RAW_ADDI(t, a, i)) 53 54 55 static void __init init_pt_regs(struct pt_regs *regs) 56 { 57 static unsigned long msr; 58 static bool msr_cached; 59 60 memset(regs, 0, sizeof(struct pt_regs)); 61 62 if (likely(msr_cached)) { 63 regs->msr = msr; 64 return; 65 } 66 67 asm volatile("mfmsr %0" : "=r"(regs->msr)); 68 69 regs->msr |= MSR_FP; 70 regs->msr |= MSR_VEC; 71 regs->msr |= MSR_VSX; 72 73 msr = regs->msr; 74 msr_cached = true; 75 } 76 77 static void __init show_result(char *mnemonic, char *result) 78 { 79 pr_info("%-14s : %s\n", mnemonic, result); 80 } 81 82 static void __init show_result_with_descr(char *mnemonic, char *descr, 83 char *result) 84 { 85 pr_info("%-14s : %-50s %s\n", mnemonic, descr, result); 86 } 87 88 static void __init test_ld(void) 89 { 90 struct pt_regs regs; 91 unsigned long a = 0x23; 92 int stepped = -1; 93 94 init_pt_regs(®s); 95 regs.gpr[3] = (unsigned long) &a; 96 97 /* ld r5, 0(r3) */ 98 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LD(5, 3, 0))); 99 100 if (stepped == 1 && regs.gpr[5] == a) 101 show_result("ld", "PASS"); 102 else 103 show_result("ld", "FAIL"); 104 } 105 106 static void __init test_pld(void) 107 { 108 struct pt_regs regs; 109 unsigned long a = 0x23; 110 int stepped = -1; 111 112 if (!cpu_has_feature(CPU_FTR_ARCH_31)) { 113 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)"); 114 return; 115 } 116 117 init_pt_regs(®s); 118 regs.gpr[3] = (unsigned long)&a; 119 120 /* pld r5, 0(r3), 0 */ 121 stepped = emulate_step(®s, TEST_PLD(5, 3, 0, 0)); 122 123 if (stepped == 1 && regs.gpr[5] == a) 124 show_result("pld", "PASS"); 125 else 126 show_result("pld", "FAIL"); 127 } 128 129 static void __init test_lwz(void) 130 { 131 struct pt_regs regs; 132 unsigned int a = 0x4545; 133 int stepped = -1; 134 135 init_pt_regs(®s); 136 regs.gpr[3] = (unsigned long) &a; 137 138 /* lwz r5, 0(r3) */ 139 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LWZ(5, 3, 0))); 140 141 if (stepped == 1 && regs.gpr[5] == a) 142 show_result("lwz", "PASS"); 143 else 144 show_result("lwz", "FAIL"); 145 } 146 147 static void __init test_plwz(void) 148 { 149 struct pt_regs regs; 150 unsigned int a = 0x4545; 151 int stepped = -1; 152 153 if (!cpu_has_feature(CPU_FTR_ARCH_31)) { 154 show_result("plwz", "SKIP (!CPU_FTR_ARCH_31)"); 155 return; 156 } 157 158 init_pt_regs(®s); 159 regs.gpr[3] = (unsigned long)&a; 160 161 /* plwz r5, 0(r3), 0 */ 162 163 stepped = emulate_step(®s, TEST_PLWZ(5, 3, 0, 0)); 164 165 if (stepped == 1 && regs.gpr[5] == a) 166 show_result("plwz", "PASS"); 167 else 168 show_result("plwz", "FAIL"); 169 } 170 171 static void __init test_lwzx(void) 172 { 173 struct pt_regs regs; 174 unsigned int a[3] = {0x0, 0x0, 0x1234}; 175 int stepped = -1; 176 177 init_pt_regs(®s); 178 regs.gpr[3] = (unsigned long) a; 179 regs.gpr[4] = 8; 180 regs.gpr[5] = 0x8765; 181 182 /* lwzx r5, r3, r4 */ 183 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LWZX(5, 3, 4))); 184 if (stepped == 1 && regs.gpr[5] == a[2]) 185 show_result("lwzx", "PASS"); 186 else 187 show_result("lwzx", "FAIL"); 188 } 189 190 static void __init test_std(void) 191 { 192 struct pt_regs regs; 193 unsigned long a = 0x1234; 194 int stepped = -1; 195 196 init_pt_regs(®s); 197 regs.gpr[3] = (unsigned long) &a; 198 regs.gpr[5] = 0x5678; 199 200 /* std r5, 0(r3) */ 201 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STD(5, 3, 0))); 202 if (stepped == 1 && regs.gpr[5] == a) 203 show_result("std", "PASS"); 204 else 205 show_result("std", "FAIL"); 206 } 207 208 static void __init test_pstd(void) 209 { 210 struct pt_regs regs; 211 unsigned long a = 0x1234; 212 int stepped = -1; 213 214 if (!cpu_has_feature(CPU_FTR_ARCH_31)) { 215 show_result("pstd", "SKIP (!CPU_FTR_ARCH_31)"); 216 return; 217 } 218 219 init_pt_regs(®s); 220 regs.gpr[3] = (unsigned long)&a; 221 regs.gpr[5] = 0x5678; 222 223 /* pstd r5, 0(r3), 0 */ 224 stepped = emulate_step(®s, TEST_PSTD(5, 3, 0, 0)); 225 if (stepped == 1 || regs.gpr[5] == a) 226 show_result("pstd", "PASS"); 227 else 228 show_result("pstd", "FAIL"); 229 } 230 231 static void __init test_ldarx_stdcx(void) 232 { 233 struct pt_regs regs; 234 unsigned long a = 0x1234; 235 int stepped = -1; 236 unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */ 237 238 init_pt_regs(®s); 239 asm volatile("mfcr %0" : "=r"(regs.ccr)); 240 241 242 /*** ldarx ***/ 243 244 regs.gpr[3] = (unsigned long) &a; 245 regs.gpr[4] = 0; 246 regs.gpr[5] = 0x5678; 247 248 /* ldarx r5, r3, r4, 0 */ 249 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LDARX(5, 3, 4, 0))); 250 251 /* 252 * Don't touch 'a' here. Touching 'a' can do Load/store 253 * of 'a' which result in failure of subsequent stdcx. 254 * Instead, use hardcoded value for comparison. 255 */ 256 if (stepped <= 0 || regs.gpr[5] != 0x1234) { 257 show_result("ldarx / stdcx.", "FAIL (ldarx)"); 258 return; 259 } 260 261 262 /*** stdcx. ***/ 263 264 regs.gpr[5] = 0x9ABC; 265 266 /* stdcx. r5, r3, r4 */ 267 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STDCX(5, 3, 4))); 268 269 /* 270 * Two possible scenarios that indicates successful emulation 271 * of stdcx. : 272 * 1. Reservation is active and store is performed. In this 273 * case cr0.eq bit will be set to 1. 274 * 2. Reservation is not active and store is not performed. 275 * In this case cr0.eq bit will be set to 0. 276 */ 277 if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq)) 278 || (regs.gpr[5] != a && !(regs.ccr & cr0_eq)))) 279 show_result("ldarx / stdcx.", "PASS"); 280 else 281 show_result("ldarx / stdcx.", "FAIL (stdcx.)"); 282 } 283 284 #ifdef CONFIG_PPC_FPU 285 static void __init test_lfsx_stfsx(void) 286 { 287 struct pt_regs regs; 288 union { 289 float a; 290 int b; 291 } c; 292 int cached_b; 293 int stepped = -1; 294 295 init_pt_regs(®s); 296 297 298 /*** lfsx ***/ 299 300 c.a = 123.45; 301 cached_b = c.b; 302 303 regs.gpr[3] = (unsigned long) &c.a; 304 regs.gpr[4] = 0; 305 306 /* lfsx frt10, r3, r4 */ 307 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LFSX(10, 3, 4))); 308 309 if (stepped == 1) 310 show_result("lfsx", "PASS"); 311 else 312 show_result("lfsx", "FAIL"); 313 314 315 /*** stfsx ***/ 316 317 c.a = 678.91; 318 319 /* stfsx frs10, r3, r4 */ 320 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STFSX(10, 3, 4))); 321 322 if (stepped == 1 && c.b == cached_b) 323 show_result("stfsx", "PASS"); 324 else 325 show_result("stfsx", "FAIL"); 326 } 327 328 static void __init test_plfs_pstfs(void) 329 { 330 struct pt_regs regs; 331 union { 332 float a; 333 int b; 334 } c; 335 int cached_b; 336 int stepped = -1; 337 338 if (!cpu_has_feature(CPU_FTR_ARCH_31)) { 339 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)"); 340 return; 341 } 342 343 init_pt_regs(®s); 344 345 346 /*** plfs ***/ 347 348 c.a = 123.45; 349 cached_b = c.b; 350 351 regs.gpr[3] = (unsigned long)&c.a; 352 353 /* plfs frt10, 0(r3), 0 */ 354 stepped = emulate_step(®s, TEST_PLFS(10, 3, 0, 0)); 355 356 if (stepped == 1) 357 show_result("plfs", "PASS"); 358 else 359 show_result("plfs", "FAIL"); 360 361 362 /*** pstfs ***/ 363 364 c.a = 678.91; 365 366 /* pstfs frs10, 0(r3), 0 */ 367 stepped = emulate_step(®s, TEST_PSTFS(10, 3, 0, 0)); 368 369 if (stepped == 1 && c.b == cached_b) 370 show_result("pstfs", "PASS"); 371 else 372 show_result("pstfs", "FAIL"); 373 } 374 375 static void __init test_lfdx_stfdx(void) 376 { 377 struct pt_regs regs; 378 union { 379 double a; 380 long b; 381 } c; 382 long cached_b; 383 int stepped = -1; 384 385 init_pt_regs(®s); 386 387 388 /*** lfdx ***/ 389 390 c.a = 123456.78; 391 cached_b = c.b; 392 393 regs.gpr[3] = (unsigned long) &c.a; 394 regs.gpr[4] = 0; 395 396 /* lfdx frt10, r3, r4 */ 397 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LFDX(10, 3, 4))); 398 399 if (stepped == 1) 400 show_result("lfdx", "PASS"); 401 else 402 show_result("lfdx", "FAIL"); 403 404 405 /*** stfdx ***/ 406 407 c.a = 987654.32; 408 409 /* stfdx frs10, r3, r4 */ 410 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STFDX(10, 3, 4))); 411 412 if (stepped == 1 && c.b == cached_b) 413 show_result("stfdx", "PASS"); 414 else 415 show_result("stfdx", "FAIL"); 416 } 417 418 static void __init test_plfd_pstfd(void) 419 { 420 struct pt_regs regs; 421 union { 422 double a; 423 long b; 424 } c; 425 long cached_b; 426 int stepped = -1; 427 428 if (!cpu_has_feature(CPU_FTR_ARCH_31)) { 429 show_result("pld", "SKIP (!CPU_FTR_ARCH_31)"); 430 return; 431 } 432 433 init_pt_regs(®s); 434 435 436 /*** plfd ***/ 437 438 c.a = 123456.78; 439 cached_b = c.b; 440 441 regs.gpr[3] = (unsigned long)&c.a; 442 443 /* plfd frt10, 0(r3), 0 */ 444 stepped = emulate_step(®s, TEST_PLFD(10, 3, 0, 0)); 445 446 if (stepped == 1) 447 show_result("plfd", "PASS"); 448 else 449 show_result("plfd", "FAIL"); 450 451 452 /*** pstfd ***/ 453 454 c.a = 987654.32; 455 456 /* pstfd frs10, 0(r3), 0 */ 457 stepped = emulate_step(®s, TEST_PSTFD(10, 3, 0, 0)); 458 459 if (stepped == 1 && c.b == cached_b) 460 show_result("pstfd", "PASS"); 461 else 462 show_result("pstfd", "FAIL"); 463 } 464 #else 465 static void __init test_lfsx_stfsx(void) 466 { 467 show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)"); 468 show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)"); 469 } 470 471 static void __init test_plfs_pstfs(void) 472 { 473 show_result("plfs", "SKIP (CONFIG_PPC_FPU is not set)"); 474 show_result("pstfs", "SKIP (CONFIG_PPC_FPU is not set)"); 475 } 476 477 static void __init test_lfdx_stfdx(void) 478 { 479 show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)"); 480 show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)"); 481 } 482 483 static void __init test_plfd_pstfd(void) 484 { 485 show_result("plfd", "SKIP (CONFIG_PPC_FPU is not set)"); 486 show_result("pstfd", "SKIP (CONFIG_PPC_FPU is not set)"); 487 } 488 #endif /* CONFIG_PPC_FPU */ 489 490 #ifdef CONFIG_ALTIVEC 491 static void __init test_lvx_stvx(void) 492 { 493 struct pt_regs regs; 494 union { 495 vector128 a; 496 u32 b[4]; 497 } c; 498 u32 cached_b[4]; 499 int stepped = -1; 500 501 init_pt_regs(®s); 502 503 504 /*** lvx ***/ 505 506 cached_b[0] = c.b[0] = 923745; 507 cached_b[1] = c.b[1] = 2139478; 508 cached_b[2] = c.b[2] = 9012; 509 cached_b[3] = c.b[3] = 982134; 510 511 regs.gpr[3] = (unsigned long) &c.a; 512 regs.gpr[4] = 0; 513 514 /* lvx vrt10, r3, r4 */ 515 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LVX(10, 3, 4))); 516 517 if (stepped == 1) 518 show_result("lvx", "PASS"); 519 else 520 show_result("lvx", "FAIL"); 521 522 523 /*** stvx ***/ 524 525 c.b[0] = 4987513; 526 c.b[1] = 84313948; 527 c.b[2] = 71; 528 c.b[3] = 498532; 529 530 /* stvx vrs10, r3, r4 */ 531 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STVX(10, 3, 4))); 532 533 if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] && 534 cached_b[2] == c.b[2] && cached_b[3] == c.b[3]) 535 show_result("stvx", "PASS"); 536 else 537 show_result("stvx", "FAIL"); 538 } 539 #else 540 static void __init test_lvx_stvx(void) 541 { 542 show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)"); 543 show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)"); 544 } 545 #endif /* CONFIG_ALTIVEC */ 546 547 #ifdef CONFIG_VSX 548 static void __init test_lxvd2x_stxvd2x(void) 549 { 550 struct pt_regs regs; 551 union { 552 vector128 a; 553 u32 b[4]; 554 } c; 555 u32 cached_b[4]; 556 int stepped = -1; 557 558 init_pt_regs(®s); 559 560 561 /*** lxvd2x ***/ 562 563 cached_b[0] = c.b[0] = 18233; 564 cached_b[1] = c.b[1] = 34863571; 565 cached_b[2] = c.b[2] = 834; 566 cached_b[3] = c.b[3] = 6138911; 567 568 regs.gpr[3] = (unsigned long) &c.a; 569 regs.gpr[4] = 0; 570 571 /* lxvd2x vsr39, r3, r4 */ 572 stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVD2X(39, R3, R4))); 573 574 if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) { 575 show_result("lxvd2x", "PASS"); 576 } else { 577 if (!cpu_has_feature(CPU_FTR_VSX)) 578 show_result("lxvd2x", "PASS (!CPU_FTR_VSX)"); 579 else 580 show_result("lxvd2x", "FAIL"); 581 } 582 583 584 /*** stxvd2x ***/ 585 586 c.b[0] = 21379463; 587 c.b[1] = 87; 588 c.b[2] = 374234; 589 c.b[3] = 4; 590 591 /* stxvd2x vsr39, r3, r4 */ 592 stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVD2X(39, R3, R4))); 593 594 if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] && 595 cached_b[2] == c.b[2] && cached_b[3] == c.b[3] && 596 cpu_has_feature(CPU_FTR_VSX)) { 597 show_result("stxvd2x", "PASS"); 598 } else { 599 if (!cpu_has_feature(CPU_FTR_VSX)) 600 show_result("stxvd2x", "PASS (!CPU_FTR_VSX)"); 601 else 602 show_result("stxvd2x", "FAIL"); 603 } 604 } 605 #else 606 static void __init test_lxvd2x_stxvd2x(void) 607 { 608 show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)"); 609 show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)"); 610 } 611 #endif /* CONFIG_VSX */ 612 613 static void __init run_tests_load_store(void) 614 { 615 test_ld(); 616 test_pld(); 617 test_lwz(); 618 test_plwz(); 619 test_lwzx(); 620 test_std(); 621 test_pstd(); 622 test_ldarx_stdcx(); 623 test_lfsx_stfsx(); 624 test_plfs_pstfs(); 625 test_lfdx_stfdx(); 626 test_plfd_pstfd(); 627 test_lvx_stvx(); 628 test_lxvd2x_stxvd2x(); 629 } 630 631 struct compute_test { 632 char *mnemonic; 633 unsigned long cpu_feature; 634 struct { 635 char *descr; 636 unsigned long flags; 637 struct ppc_inst instr; 638 struct pt_regs regs; 639 } subtests[MAX_SUBTESTS + 1]; 640 }; 641 642 /* Extreme values for si0||si1 (the MLS:D-form 34 bit immediate field) */ 643 #define SI_MIN BIT(33) 644 #define SI_MAX (BIT(33) - 1) 645 #define SI_UMAX (BIT(34) - 1) 646 647 static struct compute_test compute_tests[] = { 648 { 649 .mnemonic = "nop", 650 .subtests = { 651 { 652 .descr = "R0 = LONG_MAX", 653 .instr = ppc_inst(PPC_INST_NOP), 654 .regs = { 655 .gpr[0] = LONG_MAX, 656 } 657 } 658 } 659 }, 660 { 661 .mnemonic = "add", 662 .subtests = { 663 { 664 .descr = "RA = LONG_MIN, RB = LONG_MIN", 665 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 666 .regs = { 667 .gpr[21] = LONG_MIN, 668 .gpr[22] = LONG_MIN, 669 } 670 }, 671 { 672 .descr = "RA = LONG_MIN, RB = LONG_MAX", 673 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 674 .regs = { 675 .gpr[21] = LONG_MIN, 676 .gpr[22] = LONG_MAX, 677 } 678 }, 679 { 680 .descr = "RA = LONG_MAX, RB = LONG_MAX", 681 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 682 .regs = { 683 .gpr[21] = LONG_MAX, 684 .gpr[22] = LONG_MAX, 685 } 686 }, 687 { 688 .descr = "RA = ULONG_MAX, RB = ULONG_MAX", 689 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 690 .regs = { 691 .gpr[21] = ULONG_MAX, 692 .gpr[22] = ULONG_MAX, 693 } 694 }, 695 { 696 .descr = "RA = ULONG_MAX, RB = 0x1", 697 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 698 .regs = { 699 .gpr[21] = ULONG_MAX, 700 .gpr[22] = 0x1, 701 } 702 }, 703 { 704 .descr = "RA = INT_MIN, RB = INT_MIN", 705 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 706 .regs = { 707 .gpr[21] = INT_MIN, 708 .gpr[22] = INT_MIN, 709 } 710 }, 711 { 712 .descr = "RA = INT_MIN, RB = INT_MAX", 713 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 714 .regs = { 715 .gpr[21] = INT_MIN, 716 .gpr[22] = INT_MAX, 717 } 718 }, 719 { 720 .descr = "RA = INT_MAX, RB = INT_MAX", 721 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 722 .regs = { 723 .gpr[21] = INT_MAX, 724 .gpr[22] = INT_MAX, 725 } 726 }, 727 { 728 .descr = "RA = UINT_MAX, RB = UINT_MAX", 729 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 730 .regs = { 731 .gpr[21] = UINT_MAX, 732 .gpr[22] = UINT_MAX, 733 } 734 }, 735 { 736 .descr = "RA = UINT_MAX, RB = 0x1", 737 .instr = ppc_inst(PPC_RAW_ADD(20, 21, 22)), 738 .regs = { 739 .gpr[21] = UINT_MAX, 740 .gpr[22] = 0x1, 741 } 742 } 743 } 744 }, 745 { 746 .mnemonic = "add.", 747 .subtests = { 748 { 749 .descr = "RA = LONG_MIN, RB = LONG_MIN", 750 .flags = IGNORE_CCR, 751 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 752 .regs = { 753 .gpr[21] = LONG_MIN, 754 .gpr[22] = LONG_MIN, 755 } 756 }, 757 { 758 .descr = "RA = LONG_MIN, RB = LONG_MAX", 759 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 760 .regs = { 761 .gpr[21] = LONG_MIN, 762 .gpr[22] = LONG_MAX, 763 } 764 }, 765 { 766 .descr = "RA = LONG_MAX, RB = LONG_MAX", 767 .flags = IGNORE_CCR, 768 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 769 .regs = { 770 .gpr[21] = LONG_MAX, 771 .gpr[22] = LONG_MAX, 772 } 773 }, 774 { 775 .descr = "RA = ULONG_MAX, RB = ULONG_MAX", 776 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 777 .regs = { 778 .gpr[21] = ULONG_MAX, 779 .gpr[22] = ULONG_MAX, 780 } 781 }, 782 { 783 .descr = "RA = ULONG_MAX, RB = 0x1", 784 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 785 .regs = { 786 .gpr[21] = ULONG_MAX, 787 .gpr[22] = 0x1, 788 } 789 }, 790 { 791 .descr = "RA = INT_MIN, RB = INT_MIN", 792 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 793 .regs = { 794 .gpr[21] = INT_MIN, 795 .gpr[22] = INT_MIN, 796 } 797 }, 798 { 799 .descr = "RA = INT_MIN, RB = INT_MAX", 800 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 801 .regs = { 802 .gpr[21] = INT_MIN, 803 .gpr[22] = INT_MAX, 804 } 805 }, 806 { 807 .descr = "RA = INT_MAX, RB = INT_MAX", 808 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 809 .regs = { 810 .gpr[21] = INT_MAX, 811 .gpr[22] = INT_MAX, 812 } 813 }, 814 { 815 .descr = "RA = UINT_MAX, RB = UINT_MAX", 816 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 817 .regs = { 818 .gpr[21] = UINT_MAX, 819 .gpr[22] = UINT_MAX, 820 } 821 }, 822 { 823 .descr = "RA = UINT_MAX, RB = 0x1", 824 .instr = ppc_inst(PPC_RAW_ADD_DOT(20, 21, 22)), 825 .regs = { 826 .gpr[21] = UINT_MAX, 827 .gpr[22] = 0x1, 828 } 829 } 830 } 831 }, 832 { 833 .mnemonic = "addc", 834 .subtests = { 835 { 836 .descr = "RA = LONG_MIN, RB = LONG_MIN", 837 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 838 .regs = { 839 .gpr[21] = LONG_MIN, 840 .gpr[22] = LONG_MIN, 841 } 842 }, 843 { 844 .descr = "RA = LONG_MIN, RB = LONG_MAX", 845 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 846 .regs = { 847 .gpr[21] = LONG_MIN, 848 .gpr[22] = LONG_MAX, 849 } 850 }, 851 { 852 .descr = "RA = LONG_MAX, RB = LONG_MAX", 853 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 854 .regs = { 855 .gpr[21] = LONG_MAX, 856 .gpr[22] = LONG_MAX, 857 } 858 }, 859 { 860 .descr = "RA = ULONG_MAX, RB = ULONG_MAX", 861 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 862 .regs = { 863 .gpr[21] = ULONG_MAX, 864 .gpr[22] = ULONG_MAX, 865 } 866 }, 867 { 868 .descr = "RA = ULONG_MAX, RB = 0x1", 869 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 870 .regs = { 871 .gpr[21] = ULONG_MAX, 872 .gpr[22] = 0x1, 873 } 874 }, 875 { 876 .descr = "RA = INT_MIN, RB = INT_MIN", 877 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 878 .regs = { 879 .gpr[21] = INT_MIN, 880 .gpr[22] = INT_MIN, 881 } 882 }, 883 { 884 .descr = "RA = INT_MIN, RB = INT_MAX", 885 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 886 .regs = { 887 .gpr[21] = INT_MIN, 888 .gpr[22] = INT_MAX, 889 } 890 }, 891 { 892 .descr = "RA = INT_MAX, RB = INT_MAX", 893 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 894 .regs = { 895 .gpr[21] = INT_MAX, 896 .gpr[22] = INT_MAX, 897 } 898 }, 899 { 900 .descr = "RA = UINT_MAX, RB = UINT_MAX", 901 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 902 .regs = { 903 .gpr[21] = UINT_MAX, 904 .gpr[22] = UINT_MAX, 905 } 906 }, 907 { 908 .descr = "RA = UINT_MAX, RB = 0x1", 909 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 910 .regs = { 911 .gpr[21] = UINT_MAX, 912 .gpr[22] = 0x1, 913 } 914 }, 915 { 916 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN", 917 .instr = ppc_inst(PPC_RAW_ADDC(20, 21, 22)), 918 .regs = { 919 .gpr[21] = LONG_MIN | (uint)INT_MIN, 920 .gpr[22] = LONG_MIN | (uint)INT_MIN, 921 } 922 } 923 } 924 }, 925 { 926 .mnemonic = "addc.", 927 .subtests = { 928 { 929 .descr = "RA = LONG_MIN, RB = LONG_MIN", 930 .flags = IGNORE_CCR, 931 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 932 .regs = { 933 .gpr[21] = LONG_MIN, 934 .gpr[22] = LONG_MIN, 935 } 936 }, 937 { 938 .descr = "RA = LONG_MIN, RB = LONG_MAX", 939 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 940 .regs = { 941 .gpr[21] = LONG_MIN, 942 .gpr[22] = LONG_MAX, 943 } 944 }, 945 { 946 .descr = "RA = LONG_MAX, RB = LONG_MAX", 947 .flags = IGNORE_CCR, 948 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 949 .regs = { 950 .gpr[21] = LONG_MAX, 951 .gpr[22] = LONG_MAX, 952 } 953 }, 954 { 955 .descr = "RA = ULONG_MAX, RB = ULONG_MAX", 956 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 957 .regs = { 958 .gpr[21] = ULONG_MAX, 959 .gpr[22] = ULONG_MAX, 960 } 961 }, 962 { 963 .descr = "RA = ULONG_MAX, RB = 0x1", 964 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 965 .regs = { 966 .gpr[21] = ULONG_MAX, 967 .gpr[22] = 0x1, 968 } 969 }, 970 { 971 .descr = "RA = INT_MIN, RB = INT_MIN", 972 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 973 .regs = { 974 .gpr[21] = INT_MIN, 975 .gpr[22] = INT_MIN, 976 } 977 }, 978 { 979 .descr = "RA = INT_MIN, RB = INT_MAX", 980 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 981 .regs = { 982 .gpr[21] = INT_MIN, 983 .gpr[22] = INT_MAX, 984 } 985 }, 986 { 987 .descr = "RA = INT_MAX, RB = INT_MAX", 988 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 989 .regs = { 990 .gpr[21] = INT_MAX, 991 .gpr[22] = INT_MAX, 992 } 993 }, 994 { 995 .descr = "RA = UINT_MAX, RB = UINT_MAX", 996 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 997 .regs = { 998 .gpr[21] = UINT_MAX, 999 .gpr[22] = UINT_MAX, 1000 } 1001 }, 1002 { 1003 .descr = "RA = UINT_MAX, RB = 0x1", 1004 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 1005 .regs = { 1006 .gpr[21] = UINT_MAX, 1007 .gpr[22] = 0x1, 1008 } 1009 }, 1010 { 1011 .descr = "RA = LONG_MIN | INT_MIN, RB = LONG_MIN | INT_MIN", 1012 .instr = ppc_inst(PPC_RAW_ADDC_DOT(20, 21, 22)), 1013 .regs = { 1014 .gpr[21] = LONG_MIN | (uint)INT_MIN, 1015 .gpr[22] = LONG_MIN | (uint)INT_MIN, 1016 } 1017 } 1018 } 1019 }, 1020 { 1021 .mnemonic = "paddi", 1022 .cpu_feature = CPU_FTR_ARCH_31, 1023 .subtests = { 1024 { 1025 .descr = "RA = LONG_MIN, SI = SI_MIN, R = 0", 1026 .instr = TEST_PADDI(21, 22, SI_MIN, 0), 1027 .regs = { 1028 .gpr[21] = 0, 1029 .gpr[22] = LONG_MIN, 1030 } 1031 }, 1032 { 1033 .descr = "RA = LONG_MIN, SI = SI_MAX, R = 0", 1034 .instr = TEST_PADDI(21, 22, SI_MAX, 0), 1035 .regs = { 1036 .gpr[21] = 0, 1037 .gpr[22] = LONG_MIN, 1038 } 1039 }, 1040 { 1041 .descr = "RA = LONG_MAX, SI = SI_MAX, R = 0", 1042 .instr = TEST_PADDI(21, 22, SI_MAX, 0), 1043 .regs = { 1044 .gpr[21] = 0, 1045 .gpr[22] = LONG_MAX, 1046 } 1047 }, 1048 { 1049 .descr = "RA = ULONG_MAX, SI = SI_UMAX, R = 0", 1050 .instr = TEST_PADDI(21, 22, SI_UMAX, 0), 1051 .regs = { 1052 .gpr[21] = 0, 1053 .gpr[22] = ULONG_MAX, 1054 } 1055 }, 1056 { 1057 .descr = "RA = ULONG_MAX, SI = 0x1, R = 0", 1058 .instr = TEST_PADDI(21, 22, 0x1, 0), 1059 .regs = { 1060 .gpr[21] = 0, 1061 .gpr[22] = ULONG_MAX, 1062 } 1063 }, 1064 { 1065 .descr = "RA = INT_MIN, SI = SI_MIN, R = 0", 1066 .instr = TEST_PADDI(21, 22, SI_MIN, 0), 1067 .regs = { 1068 .gpr[21] = 0, 1069 .gpr[22] = INT_MIN, 1070 } 1071 }, 1072 { 1073 .descr = "RA = INT_MIN, SI = SI_MAX, R = 0", 1074 .instr = TEST_PADDI(21, 22, SI_MAX, 0), 1075 .regs = { 1076 .gpr[21] = 0, 1077 .gpr[22] = INT_MIN, 1078 } 1079 }, 1080 { 1081 .descr = "RA = INT_MAX, SI = SI_MAX, R = 0", 1082 .instr = TEST_PADDI(21, 22, SI_MAX, 0), 1083 .regs = { 1084 .gpr[21] = 0, 1085 .gpr[22] = INT_MAX, 1086 } 1087 }, 1088 { 1089 .descr = "RA = UINT_MAX, SI = 0x1, R = 0", 1090 .instr = TEST_PADDI(21, 22, 0x1, 0), 1091 .regs = { 1092 .gpr[21] = 0, 1093 .gpr[22] = UINT_MAX, 1094 } 1095 }, 1096 { 1097 .descr = "RA = UINT_MAX, SI = SI_MAX, R = 0", 1098 .instr = TEST_PADDI(21, 22, SI_MAX, 0), 1099 .regs = { 1100 .gpr[21] = 0, 1101 .gpr[22] = UINT_MAX, 1102 } 1103 }, 1104 { 1105 .descr = "RA is r0, SI = SI_MIN, R = 0", 1106 .instr = TEST_PADDI(21, 0, SI_MIN, 0), 1107 .regs = { 1108 .gpr[21] = 0x0, 1109 } 1110 }, 1111 { 1112 .descr = "RA = 0, SI = SI_MIN, R = 0", 1113 .instr = TEST_PADDI(21, 22, SI_MIN, 0), 1114 .regs = { 1115 .gpr[21] = 0x0, 1116 .gpr[22] = 0x0, 1117 } 1118 }, 1119 { 1120 .descr = "RA is r0, SI = 0, R = 1", 1121 .instr = TEST_PADDI(21, 0, 0, 1), 1122 .regs = { 1123 .gpr[21] = 0, 1124 } 1125 }, 1126 { 1127 .descr = "RA is r0, SI = SI_MIN, R = 1", 1128 .instr = TEST_PADDI(21, 0, SI_MIN, 1), 1129 .regs = { 1130 .gpr[21] = 0, 1131 } 1132 } 1133 } 1134 } 1135 }; 1136 1137 static int __init emulate_compute_instr(struct pt_regs *regs, 1138 struct ppc_inst instr) 1139 { 1140 extern s32 patch__exec_instr; 1141 struct instruction_op op; 1142 1143 if (!regs || !ppc_inst_val(instr)) 1144 return -EINVAL; 1145 1146 regs->nip = patch_site_addr(&patch__exec_instr); 1147 1148 if (analyse_instr(&op, regs, instr) != 1 || 1149 GETTYPE(op.type) != COMPUTE) { 1150 pr_info("emulation failed, instruction = 0x%08x\n", ppc_inst_val(instr)); 1151 return -EFAULT; 1152 } 1153 1154 emulate_update_regs(regs, &op); 1155 return 0; 1156 } 1157 1158 static int __init execute_compute_instr(struct pt_regs *regs, 1159 struct ppc_inst instr) 1160 { 1161 extern int exec_instr(struct pt_regs *regs); 1162 extern s32 patch__exec_instr; 1163 1164 if (!regs || !ppc_inst_val(instr)) 1165 return -EINVAL; 1166 1167 /* Patch the NOP with the actual instruction */ 1168 patch_instruction_site(&patch__exec_instr, instr); 1169 if (exec_instr(regs)) { 1170 pr_info("execution failed, instruction = 0x%08x\n", ppc_inst_val(instr)); 1171 return -EFAULT; 1172 } 1173 1174 return 0; 1175 } 1176 1177 #define gpr_mismatch(gprn, exp, got) \ 1178 pr_info("GPR%u mismatch, exp = 0x%016lx, got = 0x%016lx\n", \ 1179 gprn, exp, got) 1180 1181 #define reg_mismatch(name, exp, got) \ 1182 pr_info("%s mismatch, exp = 0x%016lx, got = 0x%016lx\n", \ 1183 name, exp, got) 1184 1185 static void __init run_tests_compute(void) 1186 { 1187 unsigned long flags; 1188 struct compute_test *test; 1189 struct pt_regs *regs, exp, got; 1190 unsigned int i, j, k; 1191 struct ppc_inst instr; 1192 bool ignore_gpr, ignore_xer, ignore_ccr, passed; 1193 1194 for (i = 0; i < ARRAY_SIZE(compute_tests); i++) { 1195 test = &compute_tests[i]; 1196 1197 if (test->cpu_feature && !early_cpu_has_feature(test->cpu_feature)) { 1198 show_result(test->mnemonic, "SKIP (!CPU_FTR)"); 1199 continue; 1200 } 1201 1202 for (j = 0; j < MAX_SUBTESTS && test->subtests[j].descr; j++) { 1203 instr = test->subtests[j].instr; 1204 flags = test->subtests[j].flags; 1205 regs = &test->subtests[j].regs; 1206 ignore_xer = flags & IGNORE_XER; 1207 ignore_ccr = flags & IGNORE_CCR; 1208 passed = true; 1209 1210 memcpy(&exp, regs, sizeof(struct pt_regs)); 1211 memcpy(&got, regs, sizeof(struct pt_regs)); 1212 1213 /* 1214 * Set a compatible MSR value explicitly to ensure 1215 * that XER and CR bits are updated appropriately 1216 */ 1217 exp.msr = MSR_KERNEL; 1218 got.msr = MSR_KERNEL; 1219 1220 if (emulate_compute_instr(&got, instr) || 1221 execute_compute_instr(&exp, instr)) { 1222 passed = false; 1223 goto print; 1224 } 1225 1226 /* Verify GPR values */ 1227 for (k = 0; k < 32; k++) { 1228 ignore_gpr = flags & IGNORE_GPR(k); 1229 if (!ignore_gpr && exp.gpr[k] != got.gpr[k]) { 1230 passed = false; 1231 gpr_mismatch(k, exp.gpr[k], got.gpr[k]); 1232 } 1233 } 1234 1235 /* Verify LR value */ 1236 if (exp.link != got.link) { 1237 passed = false; 1238 reg_mismatch("LR", exp.link, got.link); 1239 } 1240 1241 /* Verify XER value */ 1242 if (!ignore_xer && exp.xer != got.xer) { 1243 passed = false; 1244 reg_mismatch("XER", exp.xer, got.xer); 1245 } 1246 1247 /* Verify CR value */ 1248 if (!ignore_ccr && exp.ccr != got.ccr) { 1249 passed = false; 1250 reg_mismatch("CR", exp.ccr, got.ccr); 1251 } 1252 1253 print: 1254 show_result_with_descr(test->mnemonic, 1255 test->subtests[j].descr, 1256 passed ? "PASS" : "FAIL"); 1257 } 1258 } 1259 } 1260 1261 static int __init test_emulate_step(void) 1262 { 1263 printk(KERN_INFO "Running instruction emulation self-tests ...\n"); 1264 run_tests_load_store(); 1265 run_tests_compute(); 1266 1267 return 0; 1268 } 1269 late_initcall(test_emulate_step); 1270