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