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