at v5.14 21 kB view raw
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 21static 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 38failed: 39 return -EFAULT; 40} 41 42int 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 48static DEFINE_PER_CPU(struct vm_struct *, text_poke_area); 49 50static 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 65static 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 */ 76void __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 */ 86static 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 105static 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 144static 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 176out: 177 local_irq_restore(flags); 178 179 return err; 180} 181#else /* !CONFIG_STRICT_KERNEL_RWX */ 182 183static 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 190int 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} 199NOKPROBE_SYMBOL(patch_instruction); 200 201int 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 209bool 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 */ 235bool 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} 251NOKPROBE_SYMBOL(is_conditional_branch); 252 253int 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 273int 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 292static unsigned int branch_opcode(struct ppc_inst instr) 293{ 294 return ppc_inst_primary_opcode(instr) & 0x3F; 295} 296 297static int instr_is_branch_iform(struct ppc_inst instr) 298{ 299 return branch_opcode(instr) == 18; 300} 301 302static int instr_is_branch_bform(struct ppc_inst instr) 303{ 304 return branch_opcode(instr) == 16; 305} 306 307int 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 315int 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 320static 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 336static 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 352unsigned 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 362int 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 378void __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 395static 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 404static 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 412static 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 493static 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 507static 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 585static 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 714static 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 730static inline void test_prefixed_patching(void) {} 731#endif 732 733static 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} 745late_initcall(test_code_patching); 746 747#endif /* CONFIG_CODE_PATCHING_SELFTEST */