1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2008 Michael Ellerman, IBM Corporation. 4 */ 5 6 #include <linux/kernel.h> 7 #include <linux/kprobes.h> 8 #include <linux/vmalloc.h> 9 #include <linux/init.h> 10 #include <linux/mm.h> 11 #include <linux/cpuhotplug.h> 12 #include <linux/slab.h> 13 #include <linux/uaccess.h> 14 15 #include <asm/tlbflush.h> 16 #include <asm/page.h> 17 #include <asm/code-patching.h> 18 #include <asm/setup.h> 19 #include <asm/inst.h> 20 21 static int __patch_instruction(u32 *exec_addr, struct ppc_inst instr, u32 *patch_addr) 22 { 23 if (!ppc_inst_prefixed(instr)) { 24 u32 val = ppc_inst_val(instr); 25 26 __put_kernel_nofault(patch_addr, &val, u32, failed); 27 } else { 28 u64 val = ppc_inst_as_ulong(instr); 29 30 __put_kernel_nofault(patch_addr, &val, u64, failed); 31 } 32 33 asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr), 34 "r" (exec_addr)); 35 36 return 0; 37 38 failed: 39 return -EFAULT; 40 } 41 42 int raw_patch_instruction(u32 *addr, struct ppc_inst instr) 43 { 44 return __patch_instruction(addr, instr, addr); 45 } 46 47 #ifdef CONFIG_STRICT_KERNEL_RWX 48 static DEFINE_PER_CPU(struct vm_struct *, text_poke_area); 49 50 static int text_area_cpu_up(unsigned int cpu) 51 { 52 struct vm_struct *area; 53 54 area = get_vm_area(PAGE_SIZE, VM_ALLOC); 55 if (!area) { 56 WARN_ONCE(1, "Failed to create text area for cpu %d\n", 57 cpu); 58 return -1; 59 } 60 this_cpu_write(text_poke_area, area); 61 62 return 0; 63 } 64 65 static int text_area_cpu_down(unsigned int cpu) 66 { 67 free_vm_area(this_cpu_read(text_poke_area)); 68 return 0; 69 } 70 71 /* 72 * Although BUG_ON() is rude, in this case it should only happen if ENOMEM, and 73 * we judge it as being preferable to a kernel that will crash later when 74 * someone tries to use patch_instruction(). 75 */ 76 void __init poking_init(void) 77 { 78 BUG_ON(!cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, 79 "powerpc/text_poke:online", text_area_cpu_up, 80 text_area_cpu_down)); 81 } 82 83 /* 84 * This can be called for kernel text or a module. 85 */ 86 static int map_patch_area(void *addr, unsigned long text_poke_addr) 87 { 88 unsigned long pfn; 89 int err; 90 91 if (is_vmalloc_or_module_addr(addr)) 92 pfn = vmalloc_to_pfn(addr); 93 else 94 pfn = __pa_symbol(addr) >> PAGE_SHIFT; 95 96 err = map_kernel_page(text_poke_addr, (pfn << PAGE_SHIFT), PAGE_KERNEL); 97 98 pr_devel("Mapped addr %lx with pfn %lx:%d\n", text_poke_addr, pfn, err); 99 if (err) 100 return -1; 101 102 return 0; 103 } 104 105 static inline int unmap_patch_area(unsigned long addr) 106 { 107 pte_t *ptep; 108 pmd_t *pmdp; 109 pud_t *pudp; 110 p4d_t *p4dp; 111 pgd_t *pgdp; 112 113 pgdp = pgd_offset_k(addr); 114 if (unlikely(!pgdp)) 115 return -EINVAL; 116 117 p4dp = p4d_offset(pgdp, addr); 118 if (unlikely(!p4dp)) 119 return -EINVAL; 120 121 pudp = pud_offset(p4dp, addr); 122 if (unlikely(!pudp)) 123 return -EINVAL; 124 125 pmdp = pmd_offset(pudp, addr); 126 if (unlikely(!pmdp)) 127 return -EINVAL; 128 129 ptep = pte_offset_kernel(pmdp, addr); 130 if (unlikely(!ptep)) 131 return -EINVAL; 132 133 pr_devel("clearing mm %p, pte %p, addr %lx\n", &init_mm, ptep, addr); 134 135 /* 136 * In hash, pte_clear flushes the tlb, in radix, we have to 137 */ 138 pte_clear(&init_mm, addr, ptep); 139 flush_tlb_kernel_range(addr, addr + PAGE_SIZE); 140 141 return 0; 142 } 143 144 static int do_patch_instruction(u32 *addr, struct ppc_inst instr) 145 { 146 int err; 147 u32 *patch_addr = NULL; 148 unsigned long flags; 149 unsigned long text_poke_addr; 150 unsigned long kaddr = (unsigned long)addr; 151 152 /* 153 * During early early boot patch_instruction is called 154 * when text_poke_area is not ready, but we still need 155 * to allow patching. We just do the plain old patching 156 */ 157 if (!this_cpu_read(text_poke_area)) 158 return raw_patch_instruction(addr, instr); 159 160 local_irq_save(flags); 161 162 text_poke_addr = (unsigned long)__this_cpu_read(text_poke_area)->addr; 163 if (map_patch_area(addr, text_poke_addr)) { 164 err = -1; 165 goto out; 166 } 167 168 patch_addr = (u32 *)(text_poke_addr + (kaddr & ~PAGE_MASK)); 169 170 __patch_instruction(addr, instr, patch_addr); 171 172 err = unmap_patch_area(text_poke_addr); 173 if (err) 174 pr_warn("failed to unmap %lx\n", text_poke_addr); 175 176 out: 177 local_irq_restore(flags); 178 179 return err; 180 } 181 #else /* !CONFIG_STRICT_KERNEL_RWX */ 182 183 static int do_patch_instruction(u32 *addr, struct ppc_inst instr) 184 { 185 return raw_patch_instruction(addr, instr); 186 } 187 188 #endif /* CONFIG_STRICT_KERNEL_RWX */ 189 190 int patch_instruction(u32 *addr, struct ppc_inst instr) 191 { 192 /* Make sure we aren't patching a freed init section */ 193 if (init_mem_is_free && init_section_contains(addr, 4)) { 194 pr_debug("Skipping init section patching addr: 0x%px\n", addr); 195 return 0; 196 } 197 return do_patch_instruction(addr, instr); 198 } 199 NOKPROBE_SYMBOL(patch_instruction); 200 201 int patch_branch(u32 *addr, unsigned long target, int flags) 202 { 203 struct ppc_inst instr; 204 205 create_branch(&instr, addr, target, flags); 206 return patch_instruction(addr, instr); 207 } 208 209 bool is_offset_in_branch_range(long offset) 210 { 211 /* 212 * Powerpc branch instruction is : 213 * 214 * 0 6 30 31 215 * +---------+----------------+---+---+ 216 * | opcode | LI |AA |LK | 217 * +---------+----------------+---+---+ 218 * Where AA = 0 and LK = 0 219 * 220 * LI is a signed 24 bits integer. The real branch offset is computed 221 * by: imm32 = SignExtend(LI:'0b00', 32); 222 * 223 * So the maximum forward branch should be: 224 * (0x007fffff << 2) = 0x01fffffc = 0x1fffffc 225 * The maximum backward branch should be: 226 * (0xff800000 << 2) = 0xfe000000 = -0x2000000 227 */ 228 return (offset >= -0x2000000 && offset <= 0x1fffffc && !(offset & 0x3)); 229 } 230 231 /* 232 * Helper to check if a given instruction is a conditional branch 233 * Derived from the conditional checks in analyse_instr() 234 */ 235 bool is_conditional_branch(struct ppc_inst instr) 236 { 237 unsigned int opcode = ppc_inst_primary_opcode(instr); 238 239 if (opcode == 16) /* bc, bca, bcl, bcla */ 240 return true; 241 if (opcode == 19) { 242 switch ((ppc_inst_val(instr) >> 1) & 0x3ff) { 243 case 16: /* bclr, bclrl */ 244 case 528: /* bcctr, bcctrl */ 245 case 560: /* bctar, bctarl */ 246 return true; 247 } 248 } 249 return false; 250 } 251 NOKPROBE_SYMBOL(is_conditional_branch); 252 253 int create_branch(struct ppc_inst *instr, const u32 *addr, 254 unsigned long target, int flags) 255 { 256 long offset; 257 258 *instr = ppc_inst(0); 259 offset = target; 260 if (! (flags & BRANCH_ABSOLUTE)) 261 offset = offset - (unsigned long)addr; 262 263 /* Check we can represent the target in the instruction format */ 264 if (!is_offset_in_branch_range(offset)) 265 return 1; 266 267 /* Mask out the flags and target, so they don't step on each other. */ 268 *instr = ppc_inst(0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC)); 269 270 return 0; 271 } 272 273 int create_cond_branch(struct ppc_inst *instr, const u32 *addr, 274 unsigned long target, int flags) 275 { 276 long offset; 277 278 offset = target; 279 if (! (flags & BRANCH_ABSOLUTE)) 280 offset = offset - (unsigned long)addr; 281 282 /* Check we can represent the target in the instruction format */ 283 if (offset < -0x8000 || offset > 0x7FFF || offset & 0x3) 284 return 1; 285 286 /* Mask out the flags and target, so they don't step on each other. */ 287 *instr = ppc_inst(0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC)); 288 289 return 0; 290 } 291 292 static unsigned int branch_opcode(struct ppc_inst instr) 293 { 294 return ppc_inst_primary_opcode(instr) & 0x3F; 295 } 296 297 static int instr_is_branch_iform(struct ppc_inst instr) 298 { 299 return branch_opcode(instr) == 18; 300 } 301 302 static int instr_is_branch_bform(struct ppc_inst instr) 303 { 304 return branch_opcode(instr) == 16; 305 } 306 307 int instr_is_relative_branch(struct ppc_inst instr) 308 { 309 if (ppc_inst_val(instr) & BRANCH_ABSOLUTE) 310 return 0; 311 312 return instr_is_branch_iform(instr) || instr_is_branch_bform(instr); 313 } 314 315 int instr_is_relative_link_branch(struct ppc_inst instr) 316 { 317 return instr_is_relative_branch(instr) && (ppc_inst_val(instr) & BRANCH_SET_LINK); 318 } 319 320 static unsigned long branch_iform_target(const u32 *instr) 321 { 322 signed long imm; 323 324 imm = ppc_inst_val(ppc_inst_read(instr)) & 0x3FFFFFC; 325 326 /* If the top bit of the immediate value is set this is negative */ 327 if (imm & 0x2000000) 328 imm -= 0x4000000; 329 330 if ((ppc_inst_val(ppc_inst_read(instr)) & BRANCH_ABSOLUTE) == 0) 331 imm += (unsigned long)instr; 332 333 return (unsigned long)imm; 334 } 335 336 static unsigned long branch_bform_target(const u32 *instr) 337 { 338 signed long imm; 339 340 imm = ppc_inst_val(ppc_inst_read(instr)) & 0xFFFC; 341 342 /* If the top bit of the immediate value is set this is negative */ 343 if (imm & 0x8000) 344 imm -= 0x10000; 345 346 if ((ppc_inst_val(ppc_inst_read(instr)) & BRANCH_ABSOLUTE) == 0) 347 imm += (unsigned long)instr; 348 349 return (unsigned long)imm; 350 } 351 352 unsigned long branch_target(const u32 *instr) 353 { 354 if (instr_is_branch_iform(ppc_inst_read(instr))) 355 return branch_iform_target(instr); 356 else if (instr_is_branch_bform(ppc_inst_read(instr))) 357 return branch_bform_target(instr); 358 359 return 0; 360 } 361 362 int translate_branch(struct ppc_inst *instr, const u32 *dest, const u32 *src) 363 { 364 unsigned long target; 365 target = branch_target(src); 366 367 if (instr_is_branch_iform(ppc_inst_read(src))) 368 return create_branch(instr, dest, target, 369 ppc_inst_val(ppc_inst_read(src))); 370 else if (instr_is_branch_bform(ppc_inst_read(src))) 371 return create_cond_branch(instr, dest, target, 372 ppc_inst_val(ppc_inst_read(src))); 373 374 return 1; 375 } 376 377 #ifdef CONFIG_PPC_BOOK3E_64 378 void __patch_exception(int exc, unsigned long addr) 379 { 380 extern unsigned int interrupt_base_book3e; 381 unsigned int *ibase = &interrupt_base_book3e; 382 383 /* Our exceptions vectors start with a NOP and -then- a branch 384 * to deal with single stepping from userspace which stops on 385 * the second instruction. Thus we need to patch the second 386 * instruction of the exception, not the first one 387 */ 388 389 patch_branch(ibase + (exc / 4) + 1, addr, 0); 390 } 391 #endif 392 393 #ifdef CONFIG_CODE_PATCHING_SELFTEST 394 395 static int instr_is_branch_to_addr(const u32 *instr, unsigned long addr) 396 { 397 if (instr_is_branch_iform(ppc_inst_read(instr)) || 398 instr_is_branch_bform(ppc_inst_read(instr))) 399 return branch_target(instr) == addr; 400 401 return 0; 402 } 403 404 static void __init test_trampoline(void) 405 { 406 asm ("nop;\n"); 407 } 408 409 #define check(x) \ 410 if (!(x)) printk("code-patching: test failed at line %d\n", __LINE__); 411 412 static void __init test_branch_iform(void) 413 { 414 int err; 415 struct ppc_inst instr; 416 u32 tmp[2]; 417 u32 *iptr = tmp; 418 unsigned long addr = (unsigned long)tmp; 419 420 /* The simplest case, branch to self, no flags */ 421 check(instr_is_branch_iform(ppc_inst(0x48000000))); 422 /* All bits of target set, and flags */ 423 check(instr_is_branch_iform(ppc_inst(0x4bffffff))); 424 /* High bit of opcode set, which is wrong */ 425 check(!instr_is_branch_iform(ppc_inst(0xcbffffff))); 426 /* Middle bits of opcode set, which is wrong */ 427 check(!instr_is_branch_iform(ppc_inst(0x7bffffff))); 428 429 /* Simplest case, branch to self with link */ 430 check(instr_is_branch_iform(ppc_inst(0x48000001))); 431 /* All bits of targets set */ 432 check(instr_is_branch_iform(ppc_inst(0x4bfffffd))); 433 /* Some bits of targets set */ 434 check(instr_is_branch_iform(ppc_inst(0x4bff00fd))); 435 /* Must be a valid branch to start with */ 436 check(!instr_is_branch_iform(ppc_inst(0x7bfffffd))); 437 438 /* Absolute branch to 0x100 */ 439 patch_instruction(iptr, ppc_inst(0x48000103)); 440 check(instr_is_branch_to_addr(iptr, 0x100)); 441 /* Absolute branch to 0x420fc */ 442 patch_instruction(iptr, ppc_inst(0x480420ff)); 443 check(instr_is_branch_to_addr(iptr, 0x420fc)); 444 /* Maximum positive relative branch, + 20MB - 4B */ 445 patch_instruction(iptr, ppc_inst(0x49fffffc)); 446 check(instr_is_branch_to_addr(iptr, addr + 0x1FFFFFC)); 447 /* Smallest negative relative branch, - 4B */ 448 patch_instruction(iptr, ppc_inst(0x4bfffffc)); 449 check(instr_is_branch_to_addr(iptr, addr - 4)); 450 /* Largest negative relative branch, - 32 MB */ 451 patch_instruction(iptr, ppc_inst(0x4a000000)); 452 check(instr_is_branch_to_addr(iptr, addr - 0x2000000)); 453 454 /* Branch to self, with link */ 455 err = create_branch(&instr, iptr, addr, BRANCH_SET_LINK); 456 patch_instruction(iptr, instr); 457 check(instr_is_branch_to_addr(iptr, addr)); 458 459 /* Branch to self - 0x100, with link */ 460 err = create_branch(&instr, iptr, addr - 0x100, BRANCH_SET_LINK); 461 patch_instruction(iptr, instr); 462 check(instr_is_branch_to_addr(iptr, addr - 0x100)); 463 464 /* Branch to self + 0x100, no link */ 465 err = create_branch(&instr, iptr, addr + 0x100, 0); 466 patch_instruction(iptr, instr); 467 check(instr_is_branch_to_addr(iptr, addr + 0x100)); 468 469 /* Maximum relative negative offset, - 32 MB */ 470 err = create_branch(&instr, iptr, addr - 0x2000000, BRANCH_SET_LINK); 471 patch_instruction(iptr, instr); 472 check(instr_is_branch_to_addr(iptr, addr - 0x2000000)); 473 474 /* Out of range relative negative offset, - 32 MB + 4*/ 475 err = create_branch(&instr, iptr, addr - 0x2000004, BRANCH_SET_LINK); 476 check(err); 477 478 /* Out of range relative positive offset, + 32 MB */ 479 err = create_branch(&instr, iptr, addr + 0x2000000, BRANCH_SET_LINK); 480 check(err); 481 482 /* Unaligned target */ 483 err = create_branch(&instr, iptr, addr + 3, BRANCH_SET_LINK); 484 check(err); 485 486 /* Check flags are masked correctly */ 487 err = create_branch(&instr, iptr, addr, 0xFFFFFFFC); 488 patch_instruction(iptr, instr); 489 check(instr_is_branch_to_addr(iptr, addr)); 490 check(ppc_inst_equal(instr, ppc_inst(0x48000000))); 491 } 492 493 static void __init test_create_function_call(void) 494 { 495 u32 *iptr; 496 unsigned long dest; 497 struct ppc_inst instr; 498 499 /* Check we can create a function call */ 500 iptr = (u32 *)ppc_function_entry(test_trampoline); 501 dest = ppc_function_entry(test_create_function_call); 502 create_branch(&instr, iptr, dest, BRANCH_SET_LINK); 503 patch_instruction(iptr, instr); 504 check(instr_is_branch_to_addr(iptr, dest)); 505 } 506 507 static void __init test_branch_bform(void) 508 { 509 int err; 510 unsigned long addr; 511 struct ppc_inst instr; 512 u32 tmp[2]; 513 u32 *iptr = tmp; 514 unsigned int flags; 515 516 addr = (unsigned long)iptr; 517 518 /* The simplest case, branch to self, no flags */ 519 check(instr_is_branch_bform(ppc_inst(0x40000000))); 520 /* All bits of target set, and flags */ 521 check(instr_is_branch_bform(ppc_inst(0x43ffffff))); 522 /* High bit of opcode set, which is wrong */ 523 check(!instr_is_branch_bform(ppc_inst(0xc3ffffff))); 524 /* Middle bits of opcode set, which is wrong */ 525 check(!instr_is_branch_bform(ppc_inst(0x7bffffff))); 526 527 /* Absolute conditional branch to 0x100 */ 528 patch_instruction(iptr, ppc_inst(0x43ff0103)); 529 check(instr_is_branch_to_addr(iptr, 0x100)); 530 /* Absolute conditional branch to 0x20fc */ 531 patch_instruction(iptr, ppc_inst(0x43ff20ff)); 532 check(instr_is_branch_to_addr(iptr, 0x20fc)); 533 /* Maximum positive relative conditional branch, + 32 KB - 4B */ 534 patch_instruction(iptr, ppc_inst(0x43ff7ffc)); 535 check(instr_is_branch_to_addr(iptr, addr + 0x7FFC)); 536 /* Smallest negative relative conditional branch, - 4B */ 537 patch_instruction(iptr, ppc_inst(0x43fffffc)); 538 check(instr_is_branch_to_addr(iptr, addr - 4)); 539 /* Largest negative relative conditional branch, - 32 KB */ 540 patch_instruction(iptr, ppc_inst(0x43ff8000)); 541 check(instr_is_branch_to_addr(iptr, addr - 0x8000)); 542 543 /* All condition code bits set & link */ 544 flags = 0x3ff000 | BRANCH_SET_LINK; 545 546 /* Branch to self */ 547 err = create_cond_branch(&instr, iptr, addr, flags); 548 patch_instruction(iptr, instr); 549 check(instr_is_branch_to_addr(iptr, addr)); 550 551 /* Branch to self - 0x100 */ 552 err = create_cond_branch(&instr, iptr, addr - 0x100, flags); 553 patch_instruction(iptr, instr); 554 check(instr_is_branch_to_addr(iptr, addr - 0x100)); 555 556 /* Branch to self + 0x100 */ 557 err = create_cond_branch(&instr, iptr, addr + 0x100, flags); 558 patch_instruction(iptr, instr); 559 check(instr_is_branch_to_addr(iptr, addr + 0x100)); 560 561 /* Maximum relative negative offset, - 32 KB */ 562 err = create_cond_branch(&instr, iptr, addr - 0x8000, flags); 563 patch_instruction(iptr, instr); 564 check(instr_is_branch_to_addr(iptr, addr - 0x8000)); 565 566 /* Out of range relative negative offset, - 32 KB + 4*/ 567 err = create_cond_branch(&instr, iptr, addr - 0x8004, flags); 568 check(err); 569 570 /* Out of range relative positive offset, + 32 KB */ 571 err = create_cond_branch(&instr, iptr, addr + 0x8000, flags); 572 check(err); 573 574 /* Unaligned target */ 575 err = create_cond_branch(&instr, iptr, addr + 3, flags); 576 check(err); 577 578 /* Check flags are masked correctly */ 579 err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC); 580 patch_instruction(iptr, instr); 581 check(instr_is_branch_to_addr(iptr, addr)); 582 check(ppc_inst_equal(instr, ppc_inst(0x43FF0000))); 583 } 584 585 static void __init test_translate_branch(void) 586 { 587 unsigned long addr; 588 void *p, *q; 589 struct ppc_inst instr; 590 void *buf; 591 592 buf = vmalloc(PAGE_ALIGN(0x2000000 + 1)); 593 check(buf); 594 if (!buf) 595 return; 596 597 /* Simple case, branch to self moved a little */ 598 p = buf; 599 addr = (unsigned long)p; 600 patch_branch(p, addr, 0); 601 check(instr_is_branch_to_addr(p, addr)); 602 q = p + 4; 603 translate_branch(&instr, q, p); 604 patch_instruction(q, instr); 605 check(instr_is_branch_to_addr(q, addr)); 606 607 /* Maximum negative case, move b . to addr + 32 MB */ 608 p = buf; 609 addr = (unsigned long)p; 610 patch_branch(p, addr, 0); 611 q = buf + 0x2000000; 612 translate_branch(&instr, q, p); 613 patch_instruction(q, instr); 614 check(instr_is_branch_to_addr(p, addr)); 615 check(instr_is_branch_to_addr(q, addr)); 616 check(ppc_inst_equal(ppc_inst_read(q), ppc_inst(0x4a000000))); 617 618 /* Maximum positive case, move x to x - 32 MB + 4 */ 619 p = buf + 0x2000000; 620 addr = (unsigned long)p; 621 patch_branch(p, addr, 0); 622 q = buf + 4; 623 translate_branch(&instr, q, p); 624 patch_instruction(q, instr); 625 check(instr_is_branch_to_addr(p, addr)); 626 check(instr_is_branch_to_addr(q, addr)); 627 check(ppc_inst_equal(ppc_inst_read(q), ppc_inst(0x49fffffc))); 628 629 /* Jump to x + 16 MB moved to x + 20 MB */ 630 p = buf; 631 addr = 0x1000000 + (unsigned long)buf; 632 patch_branch(p, addr, BRANCH_SET_LINK); 633 q = buf + 0x1400000; 634 translate_branch(&instr, q, p); 635 patch_instruction(q, instr); 636 check(instr_is_branch_to_addr(p, addr)); 637 check(instr_is_branch_to_addr(q, addr)); 638 639 /* Jump to x + 16 MB moved to x - 16 MB + 4 */ 640 p = buf + 0x1000000; 641 addr = 0x2000000 + (unsigned long)buf; 642 patch_branch(p, addr, 0); 643 q = buf + 4; 644 translate_branch(&instr, q, p); 645 patch_instruction(q, instr); 646 check(instr_is_branch_to_addr(p, addr)); 647 check(instr_is_branch_to_addr(q, addr)); 648 649 650 /* Conditional branch tests */ 651 652 /* Simple case, branch to self moved a little */ 653 p = buf; 654 addr = (unsigned long)p; 655 create_cond_branch(&instr, p, addr, 0); 656 patch_instruction(p, instr); 657 check(instr_is_branch_to_addr(p, addr)); 658 q = buf + 4; 659 translate_branch(&instr, q, p); 660 patch_instruction(q, instr); 661 check(instr_is_branch_to_addr(q, addr)); 662 663 /* Maximum negative case, move b . to addr + 32 KB */ 664 p = buf; 665 addr = (unsigned long)p; 666 create_cond_branch(&instr, p, addr, 0xFFFFFFFC); 667 patch_instruction(p, instr); 668 q = buf + 0x8000; 669 translate_branch(&instr, q, p); 670 patch_instruction(q, instr); 671 check(instr_is_branch_to_addr(p, addr)); 672 check(instr_is_branch_to_addr(q, addr)); 673 check(ppc_inst_equal(ppc_inst_read(q), ppc_inst(0x43ff8000))); 674 675 /* Maximum positive case, move x to x - 32 KB + 4 */ 676 p = buf + 0x8000; 677 addr = (unsigned long)p; 678 create_cond_branch(&instr, p, addr, 0xFFFFFFFC); 679 patch_instruction(p, instr); 680 q = buf + 4; 681 translate_branch(&instr, q, p); 682 patch_instruction(q, instr); 683 check(instr_is_branch_to_addr(p, addr)); 684 check(instr_is_branch_to_addr(q, addr)); 685 check(ppc_inst_equal(ppc_inst_read(q), ppc_inst(0x43ff7ffc))); 686 687 /* Jump to x + 12 KB moved to x + 20 KB */ 688 p = buf; 689 addr = 0x3000 + (unsigned long)buf; 690 create_cond_branch(&instr, p, addr, BRANCH_SET_LINK); 691 patch_instruction(p, instr); 692 q = buf + 0x5000; 693 translate_branch(&instr, q, p); 694 patch_instruction(q, instr); 695 check(instr_is_branch_to_addr(p, addr)); 696 check(instr_is_branch_to_addr(q, addr)); 697 698 /* Jump to x + 8 KB moved to x - 8 KB + 4 */ 699 p = buf + 0x2000; 700 addr = 0x4000 + (unsigned long)buf; 701 create_cond_branch(&instr, p, addr, 0); 702 patch_instruction(p, instr); 703 q = buf + 4; 704 translate_branch(&instr, q, p); 705 patch_instruction(q, instr); 706 check(instr_is_branch_to_addr(p, addr)); 707 check(instr_is_branch_to_addr(q, addr)); 708 709 /* Free the buffer we were using */ 710 vfree(buf); 711 } 712 713 #ifdef CONFIG_PPC64 714 static void __init test_prefixed_patching(void) 715 { 716 extern unsigned int code_patching_test1[]; 717 extern unsigned int code_patching_test1_expected[]; 718 extern unsigned int end_code_patching_test1[]; 719 720 __patch_instruction(code_patching_test1, 721 ppc_inst_prefix(OP_PREFIX << 26, 0x00000000), 722 code_patching_test1); 723 724 check(!memcmp(code_patching_test1, 725 code_patching_test1_expected, 726 sizeof(unsigned int) * 727 (end_code_patching_test1 - code_patching_test1))); 728 } 729 #else 730 static inline void test_prefixed_patching(void) {} 731 #endif 732 733 static int __init test_code_patching(void) 734 { 735 printk(KERN_DEBUG "Running code patching self-tests ...\n"); 736 737 test_branch_iform(); 738 test_branch_bform(); 739 test_create_function_call(); 740 test_translate_branch(); 741 test_prefixed_patching(); 742 743 return 0; 744 } 745 late_initcall(test_code_patching); 746 747 #endif /* CONFIG_CODE_PATCHING_SELFTEST */ 748