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 bool is_offset_in_cond_branch_range(long offset) 232 { 233 return offset >= -0x8000 && offset <= 0x7fff && !(offset & 0x3); 234 } 235 236 /* 237 * Helper to check if a given instruction is a conditional branch 238 * Derived from the conditional checks in analyse_instr() 239 */ 240 bool is_conditional_branch(struct ppc_inst instr) 241 { 242 unsigned int opcode = ppc_inst_primary_opcode(instr); 243 244 if (opcode == 16) /* bc, bca, bcl, bcla */ 245 return true; 246 if (opcode == 19) { 247 switch ((ppc_inst_val(instr) >> 1) & 0x3ff) { 248 case 16: /* bclr, bclrl */ 249 case 528: /* bcctr, bcctrl */ 250 case 560: /* bctar, bctarl */ 251 return true; 252 } 253 } 254 return false; 255 } 256 NOKPROBE_SYMBOL(is_conditional_branch); 257 258 int create_branch(struct ppc_inst *instr, const u32 *addr, 259 unsigned long target, int flags) 260 { 261 long offset; 262 263 *instr = ppc_inst(0); 264 offset = target; 265 if (! (flags & BRANCH_ABSOLUTE)) 266 offset = offset - (unsigned long)addr; 267 268 /* Check we can represent the target in the instruction format */ 269 if (!is_offset_in_branch_range(offset)) 270 return 1; 271 272 /* Mask out the flags and target, so they don't step on each other. */ 273 *instr = ppc_inst(0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC)); 274 275 return 0; 276 } 277 278 int create_cond_branch(struct ppc_inst *instr, const u32 *addr, 279 unsigned long target, int flags) 280 { 281 long offset; 282 283 offset = target; 284 if (! (flags & BRANCH_ABSOLUTE)) 285 offset = offset - (unsigned long)addr; 286 287 /* Check we can represent the target in the instruction format */ 288 if (!is_offset_in_cond_branch_range(offset)) 289 return 1; 290 291 /* Mask out the flags and target, so they don't step on each other. */ 292 *instr = ppc_inst(0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC)); 293 294 return 0; 295 } 296 297 static unsigned int branch_opcode(struct ppc_inst instr) 298 { 299 return ppc_inst_primary_opcode(instr) & 0x3F; 300 } 301 302 static int instr_is_branch_iform(struct ppc_inst instr) 303 { 304 return branch_opcode(instr) == 18; 305 } 306 307 static int instr_is_branch_bform(struct ppc_inst instr) 308 { 309 return branch_opcode(instr) == 16; 310 } 311 312 int instr_is_relative_branch(struct ppc_inst instr) 313 { 314 if (ppc_inst_val(instr) & BRANCH_ABSOLUTE) 315 return 0; 316 317 return instr_is_branch_iform(instr) || instr_is_branch_bform(instr); 318 } 319 320 int instr_is_relative_link_branch(struct ppc_inst instr) 321 { 322 return instr_is_relative_branch(instr) && (ppc_inst_val(instr) & BRANCH_SET_LINK); 323 } 324 325 static unsigned long branch_iform_target(const u32 *instr) 326 { 327 signed long imm; 328 329 imm = ppc_inst_val(ppc_inst_read(instr)) & 0x3FFFFFC; 330 331 /* If the top bit of the immediate value is set this is negative */ 332 if (imm & 0x2000000) 333 imm -= 0x4000000; 334 335 if ((ppc_inst_val(ppc_inst_read(instr)) & BRANCH_ABSOLUTE) == 0) 336 imm += (unsigned long)instr; 337 338 return (unsigned long)imm; 339 } 340 341 static unsigned long branch_bform_target(const u32 *instr) 342 { 343 signed long imm; 344 345 imm = ppc_inst_val(ppc_inst_read(instr)) & 0xFFFC; 346 347 /* If the top bit of the immediate value is set this is negative */ 348 if (imm & 0x8000) 349 imm -= 0x10000; 350 351 if ((ppc_inst_val(ppc_inst_read(instr)) & BRANCH_ABSOLUTE) == 0) 352 imm += (unsigned long)instr; 353 354 return (unsigned long)imm; 355 } 356 357 unsigned long branch_target(const u32 *instr) 358 { 359 if (instr_is_branch_iform(ppc_inst_read(instr))) 360 return branch_iform_target(instr); 361 else if (instr_is_branch_bform(ppc_inst_read(instr))) 362 return branch_bform_target(instr); 363 364 return 0; 365 } 366 367 int translate_branch(struct ppc_inst *instr, const u32 *dest, const u32 *src) 368 { 369 unsigned long target; 370 target = branch_target(src); 371 372 if (instr_is_branch_iform(ppc_inst_read(src))) 373 return create_branch(instr, dest, target, 374 ppc_inst_val(ppc_inst_read(src))); 375 else if (instr_is_branch_bform(ppc_inst_read(src))) 376 return create_cond_branch(instr, dest, target, 377 ppc_inst_val(ppc_inst_read(src))); 378 379 return 1; 380 } 381 382 #ifdef CONFIG_PPC_BOOK3E_64 383 void __patch_exception(int exc, unsigned long addr) 384 { 385 extern unsigned int interrupt_base_book3e; 386 unsigned int *ibase = &interrupt_base_book3e; 387 388 /* Our exceptions vectors start with a NOP and -then- a branch 389 * to deal with single stepping from userspace which stops on 390 * the second instruction. Thus we need to patch the second 391 * instruction of the exception, not the first one 392 */ 393 394 patch_branch(ibase + (exc / 4) + 1, addr, 0); 395 } 396 #endif 397 398 #ifdef CONFIG_CODE_PATCHING_SELFTEST 399 400 static int instr_is_branch_to_addr(const u32 *instr, unsigned long addr) 401 { 402 if (instr_is_branch_iform(ppc_inst_read(instr)) || 403 instr_is_branch_bform(ppc_inst_read(instr))) 404 return branch_target(instr) == addr; 405 406 return 0; 407 } 408 409 static void __init test_trampoline(void) 410 { 411 asm ("nop;\n"); 412 } 413 414 #define check(x) \ 415 if (!(x)) printk("code-patching: test failed at line %d\n", __LINE__); 416 417 static void __init test_branch_iform(void) 418 { 419 int err; 420 struct ppc_inst instr; 421 u32 tmp[2]; 422 u32 *iptr = tmp; 423 unsigned long addr = (unsigned long)tmp; 424 425 /* The simplest case, branch to self, no flags */ 426 check(instr_is_branch_iform(ppc_inst(0x48000000))); 427 /* All bits of target set, and flags */ 428 check(instr_is_branch_iform(ppc_inst(0x4bffffff))); 429 /* High bit of opcode set, which is wrong */ 430 check(!instr_is_branch_iform(ppc_inst(0xcbffffff))); 431 /* Middle bits of opcode set, which is wrong */ 432 check(!instr_is_branch_iform(ppc_inst(0x7bffffff))); 433 434 /* Simplest case, branch to self with link */ 435 check(instr_is_branch_iform(ppc_inst(0x48000001))); 436 /* All bits of targets set */ 437 check(instr_is_branch_iform(ppc_inst(0x4bfffffd))); 438 /* Some bits of targets set */ 439 check(instr_is_branch_iform(ppc_inst(0x4bff00fd))); 440 /* Must be a valid branch to start with */ 441 check(!instr_is_branch_iform(ppc_inst(0x7bfffffd))); 442 443 /* Absolute branch to 0x100 */ 444 patch_instruction(iptr, ppc_inst(0x48000103)); 445 check(instr_is_branch_to_addr(iptr, 0x100)); 446 /* Absolute branch to 0x420fc */ 447 patch_instruction(iptr, ppc_inst(0x480420ff)); 448 check(instr_is_branch_to_addr(iptr, 0x420fc)); 449 /* Maximum positive relative branch, + 20MB - 4B */ 450 patch_instruction(iptr, ppc_inst(0x49fffffc)); 451 check(instr_is_branch_to_addr(iptr, addr + 0x1FFFFFC)); 452 /* Smallest negative relative branch, - 4B */ 453 patch_instruction(iptr, ppc_inst(0x4bfffffc)); 454 check(instr_is_branch_to_addr(iptr, addr - 4)); 455 /* Largest negative relative branch, - 32 MB */ 456 patch_instruction(iptr, ppc_inst(0x4a000000)); 457 check(instr_is_branch_to_addr(iptr, addr - 0x2000000)); 458 459 /* Branch to self, with link */ 460 err = create_branch(&instr, iptr, addr, BRANCH_SET_LINK); 461 patch_instruction(iptr, instr); 462 check(instr_is_branch_to_addr(iptr, addr)); 463 464 /* Branch to self - 0x100, with link */ 465 err = create_branch(&instr, iptr, addr - 0x100, BRANCH_SET_LINK); 466 patch_instruction(iptr, instr); 467 check(instr_is_branch_to_addr(iptr, addr - 0x100)); 468 469 /* Branch to self + 0x100, no link */ 470 err = create_branch(&instr, iptr, addr + 0x100, 0); 471 patch_instruction(iptr, instr); 472 check(instr_is_branch_to_addr(iptr, addr + 0x100)); 473 474 /* Maximum relative negative offset, - 32 MB */ 475 err = create_branch(&instr, iptr, addr - 0x2000000, BRANCH_SET_LINK); 476 patch_instruction(iptr, instr); 477 check(instr_is_branch_to_addr(iptr, addr - 0x2000000)); 478 479 /* Out of range relative negative offset, - 32 MB + 4*/ 480 err = create_branch(&instr, iptr, addr - 0x2000004, BRANCH_SET_LINK); 481 check(err); 482 483 /* Out of range relative positive offset, + 32 MB */ 484 err = create_branch(&instr, iptr, addr + 0x2000000, BRANCH_SET_LINK); 485 check(err); 486 487 /* Unaligned target */ 488 err = create_branch(&instr, iptr, addr + 3, BRANCH_SET_LINK); 489 check(err); 490 491 /* Check flags are masked correctly */ 492 err = create_branch(&instr, iptr, addr, 0xFFFFFFFC); 493 patch_instruction(iptr, instr); 494 check(instr_is_branch_to_addr(iptr, addr)); 495 check(ppc_inst_equal(instr, ppc_inst(0x48000000))); 496 } 497 498 static void __init test_create_function_call(void) 499 { 500 u32 *iptr; 501 unsigned long dest; 502 struct ppc_inst instr; 503 504 /* Check we can create a function call */ 505 iptr = (u32 *)ppc_function_entry(test_trampoline); 506 dest = ppc_function_entry(test_create_function_call); 507 create_branch(&instr, iptr, dest, BRANCH_SET_LINK); 508 patch_instruction(iptr, instr); 509 check(instr_is_branch_to_addr(iptr, dest)); 510 } 511 512 static void __init test_branch_bform(void) 513 { 514 int err; 515 unsigned long addr; 516 struct ppc_inst instr; 517 u32 tmp[2]; 518 u32 *iptr = tmp; 519 unsigned int flags; 520 521 addr = (unsigned long)iptr; 522 523 /* The simplest case, branch to self, no flags */ 524 check(instr_is_branch_bform(ppc_inst(0x40000000))); 525 /* All bits of target set, and flags */ 526 check(instr_is_branch_bform(ppc_inst(0x43ffffff))); 527 /* High bit of opcode set, which is wrong */ 528 check(!instr_is_branch_bform(ppc_inst(0xc3ffffff))); 529 /* Middle bits of opcode set, which is wrong */ 530 check(!instr_is_branch_bform(ppc_inst(0x7bffffff))); 531 532 /* Absolute conditional branch to 0x100 */ 533 patch_instruction(iptr, ppc_inst(0x43ff0103)); 534 check(instr_is_branch_to_addr(iptr, 0x100)); 535 /* Absolute conditional branch to 0x20fc */ 536 patch_instruction(iptr, ppc_inst(0x43ff20ff)); 537 check(instr_is_branch_to_addr(iptr, 0x20fc)); 538 /* Maximum positive relative conditional branch, + 32 KB - 4B */ 539 patch_instruction(iptr, ppc_inst(0x43ff7ffc)); 540 check(instr_is_branch_to_addr(iptr, addr + 0x7FFC)); 541 /* Smallest negative relative conditional branch, - 4B */ 542 patch_instruction(iptr, ppc_inst(0x43fffffc)); 543 check(instr_is_branch_to_addr(iptr, addr - 4)); 544 /* Largest negative relative conditional branch, - 32 KB */ 545 patch_instruction(iptr, ppc_inst(0x43ff8000)); 546 check(instr_is_branch_to_addr(iptr, addr - 0x8000)); 547 548 /* All condition code bits set & link */ 549 flags = 0x3ff000 | BRANCH_SET_LINK; 550 551 /* Branch to self */ 552 err = create_cond_branch(&instr, iptr, addr, flags); 553 patch_instruction(iptr, instr); 554 check(instr_is_branch_to_addr(iptr, addr)); 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 /* Branch to self + 0x100 */ 562 err = create_cond_branch(&instr, iptr, addr + 0x100, flags); 563 patch_instruction(iptr, instr); 564 check(instr_is_branch_to_addr(iptr, addr + 0x100)); 565 566 /* Maximum relative negative offset, - 32 KB */ 567 err = create_cond_branch(&instr, iptr, addr - 0x8000, flags); 568 patch_instruction(iptr, instr); 569 check(instr_is_branch_to_addr(iptr, addr - 0x8000)); 570 571 /* Out of range relative negative offset, - 32 KB + 4*/ 572 err = create_cond_branch(&instr, iptr, addr - 0x8004, flags); 573 check(err); 574 575 /* Out of range relative positive offset, + 32 KB */ 576 err = create_cond_branch(&instr, iptr, addr + 0x8000, flags); 577 check(err); 578 579 /* Unaligned target */ 580 err = create_cond_branch(&instr, iptr, addr + 3, flags); 581 check(err); 582 583 /* Check flags are masked correctly */ 584 err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC); 585 patch_instruction(iptr, instr); 586 check(instr_is_branch_to_addr(iptr, addr)); 587 check(ppc_inst_equal(instr, ppc_inst(0x43FF0000))); 588 } 589 590 static void __init test_translate_branch(void) 591 { 592 unsigned long addr; 593 void *p, *q; 594 struct ppc_inst instr; 595 void *buf; 596 597 buf = vmalloc(PAGE_ALIGN(0x2000000 + 1)); 598 check(buf); 599 if (!buf) 600 return; 601 602 /* Simple case, branch to self moved a little */ 603 p = buf; 604 addr = (unsigned long)p; 605 patch_branch(p, addr, 0); 606 check(instr_is_branch_to_addr(p, addr)); 607 q = p + 4; 608 translate_branch(&instr, q, p); 609 patch_instruction(q, instr); 610 check(instr_is_branch_to_addr(q, addr)); 611 612 /* Maximum negative case, move b . to addr + 32 MB */ 613 p = buf; 614 addr = (unsigned long)p; 615 patch_branch(p, addr, 0); 616 q = buf + 0x2000000; 617 translate_branch(&instr, q, p); 618 patch_instruction(q, instr); 619 check(instr_is_branch_to_addr(p, addr)); 620 check(instr_is_branch_to_addr(q, addr)); 621 check(ppc_inst_equal(ppc_inst_read(q), ppc_inst(0x4a000000))); 622 623 /* Maximum positive case, move x to x - 32 MB + 4 */ 624 p = buf + 0x2000000; 625 addr = (unsigned long)p; 626 patch_branch(p, addr, 0); 627 q = buf + 4; 628 translate_branch(&instr, q, p); 629 patch_instruction(q, instr); 630 check(instr_is_branch_to_addr(p, addr)); 631 check(instr_is_branch_to_addr(q, addr)); 632 check(ppc_inst_equal(ppc_inst_read(q), ppc_inst(0x49fffffc))); 633 634 /* Jump to x + 16 MB moved to x + 20 MB */ 635 p = buf; 636 addr = 0x1000000 + (unsigned long)buf; 637 patch_branch(p, addr, BRANCH_SET_LINK); 638 q = buf + 0x1400000; 639 translate_branch(&instr, q, p); 640 patch_instruction(q, instr); 641 check(instr_is_branch_to_addr(p, addr)); 642 check(instr_is_branch_to_addr(q, addr)); 643 644 /* Jump to x + 16 MB moved to x - 16 MB + 4 */ 645 p = buf + 0x1000000; 646 addr = 0x2000000 + (unsigned long)buf; 647 patch_branch(p, addr, 0); 648 q = buf + 4; 649 translate_branch(&instr, q, p); 650 patch_instruction(q, instr); 651 check(instr_is_branch_to_addr(p, addr)); 652 check(instr_is_branch_to_addr(q, addr)); 653 654 655 /* Conditional branch tests */ 656 657 /* Simple case, branch to self moved a little */ 658 p = buf; 659 addr = (unsigned long)p; 660 create_cond_branch(&instr, p, addr, 0); 661 patch_instruction(p, instr); 662 check(instr_is_branch_to_addr(p, addr)); 663 q = buf + 4; 664 translate_branch(&instr, q, p); 665 patch_instruction(q, instr); 666 check(instr_is_branch_to_addr(q, addr)); 667 668 /* Maximum negative case, move b . to addr + 32 KB */ 669 p = buf; 670 addr = (unsigned long)p; 671 create_cond_branch(&instr, p, addr, 0xFFFFFFFC); 672 patch_instruction(p, instr); 673 q = buf + 0x8000; 674 translate_branch(&instr, q, p); 675 patch_instruction(q, instr); 676 check(instr_is_branch_to_addr(p, addr)); 677 check(instr_is_branch_to_addr(q, addr)); 678 check(ppc_inst_equal(ppc_inst_read(q), ppc_inst(0x43ff8000))); 679 680 /* Maximum positive case, move x to x - 32 KB + 4 */ 681 p = buf + 0x8000; 682 addr = (unsigned long)p; 683 create_cond_branch(&instr, p, addr, 0xFFFFFFFC); 684 patch_instruction(p, instr); 685 q = buf + 4; 686 translate_branch(&instr, q, p); 687 patch_instruction(q, instr); 688 check(instr_is_branch_to_addr(p, addr)); 689 check(instr_is_branch_to_addr(q, addr)); 690 check(ppc_inst_equal(ppc_inst_read(q), ppc_inst(0x43ff7ffc))); 691 692 /* Jump to x + 12 KB moved to x + 20 KB */ 693 p = buf; 694 addr = 0x3000 + (unsigned long)buf; 695 create_cond_branch(&instr, p, addr, BRANCH_SET_LINK); 696 patch_instruction(p, instr); 697 q = buf + 0x5000; 698 translate_branch(&instr, q, p); 699 patch_instruction(q, instr); 700 check(instr_is_branch_to_addr(p, addr)); 701 check(instr_is_branch_to_addr(q, addr)); 702 703 /* Jump to x + 8 KB moved to x - 8 KB + 4 */ 704 p = buf + 0x2000; 705 addr = 0x4000 + (unsigned long)buf; 706 create_cond_branch(&instr, p, addr, 0); 707 patch_instruction(p, instr); 708 q = buf + 4; 709 translate_branch(&instr, q, p); 710 patch_instruction(q, instr); 711 check(instr_is_branch_to_addr(p, addr)); 712 check(instr_is_branch_to_addr(q, addr)); 713 714 /* Free the buffer we were using */ 715 vfree(buf); 716 } 717 718 #ifdef CONFIG_PPC64 719 static void __init test_prefixed_patching(void) 720 { 721 extern unsigned int code_patching_test1[]; 722 extern unsigned int code_patching_test1_expected[]; 723 extern unsigned int end_code_patching_test1[]; 724 725 __patch_instruction(code_patching_test1, 726 ppc_inst_prefix(OP_PREFIX << 26, 0x00000000), 727 code_patching_test1); 728 729 check(!memcmp(code_patching_test1, 730 code_patching_test1_expected, 731 sizeof(unsigned int) * 732 (end_code_patching_test1 - code_patching_test1))); 733 } 734 #else 735 static inline void test_prefixed_patching(void) {} 736 #endif 737 738 static int __init test_code_patching(void) 739 { 740 printk(KERN_DEBUG "Running code patching self-tests ...\n"); 741 742 test_branch_iform(); 743 test_branch_bform(); 744 test_create_function_call(); 745 test_translate_branch(); 746 test_prefixed_patching(); 747 748 return 0; 749 } 750 late_initcall(test_code_patching); 751 752 #endif /* CONFIG_CODE_PATCHING_SELFTEST */ 753