1 /* 2 * Copyright 2008 Michael Ellerman, IBM Corporation. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/kprobes.h> 12 #include <linux/vmalloc.h> 13 #include <linux/init.h> 14 #include <linux/mm.h> 15 #include <asm/page.h> 16 #include <asm/code-patching.h> 17 #include <linux/uaccess.h> 18 #include <linux/kprobes.h> 19 20 21 int patch_instruction(unsigned int *addr, unsigned int instr) 22 { 23 int err; 24 25 __put_user_size(instr, addr, 4, err); 26 if (err) 27 return err; 28 asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr)); 29 return 0; 30 } 31 32 int patch_branch(unsigned int *addr, unsigned long target, int flags) 33 { 34 return patch_instruction(addr, create_branch(addr, target, flags)); 35 } 36 37 bool is_offset_in_branch_range(long offset) 38 { 39 /* 40 * Powerpc branch instruction is : 41 * 42 * 0 6 30 31 43 * +---------+----------------+---+---+ 44 * | opcode | LI |AA |LK | 45 * +---------+----------------+---+---+ 46 * Where AA = 0 and LK = 0 47 * 48 * LI is a signed 24 bits integer. The real branch offset is computed 49 * by: imm32 = SignExtend(LI:'0b00', 32); 50 * 51 * So the maximum forward branch should be: 52 * (0x007fffff << 2) = 0x01fffffc = 0x1fffffc 53 * The maximum backward branch should be: 54 * (0xff800000 << 2) = 0xfe000000 = -0x2000000 55 */ 56 return (offset >= -0x2000000 && offset <= 0x1fffffc && !(offset & 0x3)); 57 } 58 59 /* 60 * Helper to check if a given instruction is a conditional branch 61 * Derived from the conditional checks in analyse_instr() 62 */ 63 bool is_conditional_branch(unsigned int instr) 64 { 65 unsigned int opcode = instr >> 26; 66 67 if (opcode == 16) /* bc, bca, bcl, bcla */ 68 return true; 69 if (opcode == 19) { 70 switch ((instr >> 1) & 0x3ff) { 71 case 16: /* bclr, bclrl */ 72 case 528: /* bcctr, bcctrl */ 73 case 560: /* bctar, bctarl */ 74 return true; 75 } 76 } 77 return false; 78 } 79 NOKPROBE_SYMBOL(is_conditional_branch); 80 81 unsigned int create_branch(const unsigned int *addr, 82 unsigned long target, int flags) 83 { 84 unsigned int instruction; 85 long offset; 86 87 offset = target; 88 if (! (flags & BRANCH_ABSOLUTE)) 89 offset = offset - (unsigned long)addr; 90 91 /* Check we can represent the target in the instruction format */ 92 if (!is_offset_in_branch_range(offset)) 93 return 0; 94 95 /* Mask out the flags and target, so they don't step on each other. */ 96 instruction = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC); 97 98 return instruction; 99 } 100 101 unsigned int create_cond_branch(const unsigned int *addr, 102 unsigned long target, int flags) 103 { 104 unsigned int instruction; 105 long offset; 106 107 offset = target; 108 if (! (flags & BRANCH_ABSOLUTE)) 109 offset = offset - (unsigned long)addr; 110 111 /* Check we can represent the target in the instruction format */ 112 if (offset < -0x8000 || offset > 0x7FFF || offset & 0x3) 113 return 0; 114 115 /* Mask out the flags and target, so they don't step on each other. */ 116 instruction = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC); 117 118 return instruction; 119 } 120 121 static unsigned int branch_opcode(unsigned int instr) 122 { 123 return (instr >> 26) & 0x3F; 124 } 125 126 static int instr_is_branch_iform(unsigned int instr) 127 { 128 return branch_opcode(instr) == 18; 129 } 130 131 static int instr_is_branch_bform(unsigned int instr) 132 { 133 return branch_opcode(instr) == 16; 134 } 135 136 int instr_is_relative_branch(unsigned int instr) 137 { 138 if (instr & BRANCH_ABSOLUTE) 139 return 0; 140 141 return instr_is_branch_iform(instr) || instr_is_branch_bform(instr); 142 } 143 144 static unsigned long branch_iform_target(const unsigned int *instr) 145 { 146 signed long imm; 147 148 imm = *instr & 0x3FFFFFC; 149 150 /* If the top bit of the immediate value is set this is negative */ 151 if (imm & 0x2000000) 152 imm -= 0x4000000; 153 154 if ((*instr & BRANCH_ABSOLUTE) == 0) 155 imm += (unsigned long)instr; 156 157 return (unsigned long)imm; 158 } 159 160 static unsigned long branch_bform_target(const unsigned int *instr) 161 { 162 signed long imm; 163 164 imm = *instr & 0xFFFC; 165 166 /* If the top bit of the immediate value is set this is negative */ 167 if (imm & 0x8000) 168 imm -= 0x10000; 169 170 if ((*instr & BRANCH_ABSOLUTE) == 0) 171 imm += (unsigned long)instr; 172 173 return (unsigned long)imm; 174 } 175 176 unsigned long branch_target(const unsigned int *instr) 177 { 178 if (instr_is_branch_iform(*instr)) 179 return branch_iform_target(instr); 180 else if (instr_is_branch_bform(*instr)) 181 return branch_bform_target(instr); 182 183 return 0; 184 } 185 186 int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr) 187 { 188 if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr)) 189 return branch_target(instr) == addr; 190 191 return 0; 192 } 193 194 unsigned int translate_branch(const unsigned int *dest, const unsigned int *src) 195 { 196 unsigned long target; 197 198 target = branch_target(src); 199 200 if (instr_is_branch_iform(*src)) 201 return create_branch(dest, target, *src); 202 else if (instr_is_branch_bform(*src)) 203 return create_cond_branch(dest, target, *src); 204 205 return 0; 206 } 207 208 #ifdef CONFIG_PPC_BOOK3E_64 209 void __patch_exception(int exc, unsigned long addr) 210 { 211 extern unsigned int interrupt_base_book3e; 212 unsigned int *ibase = &interrupt_base_book3e; 213 214 /* Our exceptions vectors start with a NOP and -then- a branch 215 * to deal with single stepping from userspace which stops on 216 * the second instruction. Thus we need to patch the second 217 * instruction of the exception, not the first one 218 */ 219 220 patch_branch(ibase + (exc / 4) + 1, addr, 0); 221 } 222 #endif 223 224 #ifdef CONFIG_CODE_PATCHING_SELFTEST 225 226 static void __init test_trampoline(void) 227 { 228 asm ("nop;\n"); 229 } 230 231 #define check(x) \ 232 if (!(x)) printk("code-patching: test failed at line %d\n", __LINE__); 233 234 static void __init test_branch_iform(void) 235 { 236 unsigned int instr; 237 unsigned long addr; 238 239 addr = (unsigned long)&instr; 240 241 /* The simplest case, branch to self, no flags */ 242 check(instr_is_branch_iform(0x48000000)); 243 /* All bits of target set, and flags */ 244 check(instr_is_branch_iform(0x4bffffff)); 245 /* High bit of opcode set, which is wrong */ 246 check(!instr_is_branch_iform(0xcbffffff)); 247 /* Middle bits of opcode set, which is wrong */ 248 check(!instr_is_branch_iform(0x7bffffff)); 249 250 /* Simplest case, branch to self with link */ 251 check(instr_is_branch_iform(0x48000001)); 252 /* All bits of targets set */ 253 check(instr_is_branch_iform(0x4bfffffd)); 254 /* Some bits of targets set */ 255 check(instr_is_branch_iform(0x4bff00fd)); 256 /* Must be a valid branch to start with */ 257 check(!instr_is_branch_iform(0x7bfffffd)); 258 259 /* Absolute branch to 0x100 */ 260 instr = 0x48000103; 261 check(instr_is_branch_to_addr(&instr, 0x100)); 262 /* Absolute branch to 0x420fc */ 263 instr = 0x480420ff; 264 check(instr_is_branch_to_addr(&instr, 0x420fc)); 265 /* Maximum positive relative branch, + 20MB - 4B */ 266 instr = 0x49fffffc; 267 check(instr_is_branch_to_addr(&instr, addr + 0x1FFFFFC)); 268 /* Smallest negative relative branch, - 4B */ 269 instr = 0x4bfffffc; 270 check(instr_is_branch_to_addr(&instr, addr - 4)); 271 /* Largest negative relative branch, - 32 MB */ 272 instr = 0x4a000000; 273 check(instr_is_branch_to_addr(&instr, addr - 0x2000000)); 274 275 /* Branch to self, with link */ 276 instr = create_branch(&instr, addr, BRANCH_SET_LINK); 277 check(instr_is_branch_to_addr(&instr, addr)); 278 279 /* Branch to self - 0x100, with link */ 280 instr = create_branch(&instr, addr - 0x100, BRANCH_SET_LINK); 281 check(instr_is_branch_to_addr(&instr, addr - 0x100)); 282 283 /* Branch to self + 0x100, no link */ 284 instr = create_branch(&instr, addr + 0x100, 0); 285 check(instr_is_branch_to_addr(&instr, addr + 0x100)); 286 287 /* Maximum relative negative offset, - 32 MB */ 288 instr = create_branch(&instr, addr - 0x2000000, BRANCH_SET_LINK); 289 check(instr_is_branch_to_addr(&instr, addr - 0x2000000)); 290 291 /* Out of range relative negative offset, - 32 MB + 4*/ 292 instr = create_branch(&instr, addr - 0x2000004, BRANCH_SET_LINK); 293 check(instr == 0); 294 295 /* Out of range relative positive offset, + 32 MB */ 296 instr = create_branch(&instr, addr + 0x2000000, BRANCH_SET_LINK); 297 check(instr == 0); 298 299 /* Unaligned target */ 300 instr = create_branch(&instr, addr + 3, BRANCH_SET_LINK); 301 check(instr == 0); 302 303 /* Check flags are masked correctly */ 304 instr = create_branch(&instr, addr, 0xFFFFFFFC); 305 check(instr_is_branch_to_addr(&instr, addr)); 306 check(instr == 0x48000000); 307 } 308 309 static void __init test_create_function_call(void) 310 { 311 unsigned int *iptr; 312 unsigned long dest; 313 314 /* Check we can create a function call */ 315 iptr = (unsigned int *)ppc_function_entry(test_trampoline); 316 dest = ppc_function_entry(test_create_function_call); 317 patch_instruction(iptr, create_branch(iptr, dest, BRANCH_SET_LINK)); 318 check(instr_is_branch_to_addr(iptr, dest)); 319 } 320 321 static void __init test_branch_bform(void) 322 { 323 unsigned long addr; 324 unsigned int *iptr, instr, flags; 325 326 iptr = &instr; 327 addr = (unsigned long)iptr; 328 329 /* The simplest case, branch to self, no flags */ 330 check(instr_is_branch_bform(0x40000000)); 331 /* All bits of target set, and flags */ 332 check(instr_is_branch_bform(0x43ffffff)); 333 /* High bit of opcode set, which is wrong */ 334 check(!instr_is_branch_bform(0xc3ffffff)); 335 /* Middle bits of opcode set, which is wrong */ 336 check(!instr_is_branch_bform(0x7bffffff)); 337 338 /* Absolute conditional branch to 0x100 */ 339 instr = 0x43ff0103; 340 check(instr_is_branch_to_addr(&instr, 0x100)); 341 /* Absolute conditional branch to 0x20fc */ 342 instr = 0x43ff20ff; 343 check(instr_is_branch_to_addr(&instr, 0x20fc)); 344 /* Maximum positive relative conditional branch, + 32 KB - 4B */ 345 instr = 0x43ff7ffc; 346 check(instr_is_branch_to_addr(&instr, addr + 0x7FFC)); 347 /* Smallest negative relative conditional branch, - 4B */ 348 instr = 0x43fffffc; 349 check(instr_is_branch_to_addr(&instr, addr - 4)); 350 /* Largest negative relative conditional branch, - 32 KB */ 351 instr = 0x43ff8000; 352 check(instr_is_branch_to_addr(&instr, addr - 0x8000)); 353 354 /* All condition code bits set & link */ 355 flags = 0x3ff000 | BRANCH_SET_LINK; 356 357 /* Branch to self */ 358 instr = create_cond_branch(iptr, addr, flags); 359 check(instr_is_branch_to_addr(&instr, addr)); 360 361 /* Branch to self - 0x100 */ 362 instr = create_cond_branch(iptr, addr - 0x100, flags); 363 check(instr_is_branch_to_addr(&instr, addr - 0x100)); 364 365 /* Branch to self + 0x100 */ 366 instr = create_cond_branch(iptr, addr + 0x100, flags); 367 check(instr_is_branch_to_addr(&instr, addr + 0x100)); 368 369 /* Maximum relative negative offset, - 32 KB */ 370 instr = create_cond_branch(iptr, addr - 0x8000, flags); 371 check(instr_is_branch_to_addr(&instr, addr - 0x8000)); 372 373 /* Out of range relative negative offset, - 32 KB + 4*/ 374 instr = create_cond_branch(iptr, addr - 0x8004, flags); 375 check(instr == 0); 376 377 /* Out of range relative positive offset, + 32 KB */ 378 instr = create_cond_branch(iptr, addr + 0x8000, flags); 379 check(instr == 0); 380 381 /* Unaligned target */ 382 instr = create_cond_branch(iptr, addr + 3, flags); 383 check(instr == 0); 384 385 /* Check flags are masked correctly */ 386 instr = create_cond_branch(iptr, addr, 0xFFFFFFFC); 387 check(instr_is_branch_to_addr(&instr, addr)); 388 check(instr == 0x43FF0000); 389 } 390 391 static void __init test_translate_branch(void) 392 { 393 unsigned long addr; 394 unsigned int *p, *q; 395 void *buf; 396 397 buf = vmalloc(PAGE_ALIGN(0x2000000 + 1)); 398 check(buf); 399 if (!buf) 400 return; 401 402 /* Simple case, branch to self moved a little */ 403 p = buf; 404 addr = (unsigned long)p; 405 patch_branch(p, addr, 0); 406 check(instr_is_branch_to_addr(p, addr)); 407 q = p + 1; 408 patch_instruction(q, translate_branch(q, p)); 409 check(instr_is_branch_to_addr(q, addr)); 410 411 /* Maximum negative case, move b . to addr + 32 MB */ 412 p = buf; 413 addr = (unsigned long)p; 414 patch_branch(p, addr, 0); 415 q = buf + 0x2000000; 416 patch_instruction(q, translate_branch(q, p)); 417 check(instr_is_branch_to_addr(p, addr)); 418 check(instr_is_branch_to_addr(q, addr)); 419 check(*q == 0x4a000000); 420 421 /* Maximum positive case, move x to x - 32 MB + 4 */ 422 p = buf + 0x2000000; 423 addr = (unsigned long)p; 424 patch_branch(p, addr, 0); 425 q = buf + 4; 426 patch_instruction(q, translate_branch(q, p)); 427 check(instr_is_branch_to_addr(p, addr)); 428 check(instr_is_branch_to_addr(q, addr)); 429 check(*q == 0x49fffffc); 430 431 /* Jump to x + 16 MB moved to x + 20 MB */ 432 p = buf; 433 addr = 0x1000000 + (unsigned long)buf; 434 patch_branch(p, addr, BRANCH_SET_LINK); 435 q = buf + 0x1400000; 436 patch_instruction(q, translate_branch(q, p)); 437 check(instr_is_branch_to_addr(p, addr)); 438 check(instr_is_branch_to_addr(q, addr)); 439 440 /* Jump to x + 16 MB moved to x - 16 MB + 4 */ 441 p = buf + 0x1000000; 442 addr = 0x2000000 + (unsigned long)buf; 443 patch_branch(p, addr, 0); 444 q = buf + 4; 445 patch_instruction(q, translate_branch(q, p)); 446 check(instr_is_branch_to_addr(p, addr)); 447 check(instr_is_branch_to_addr(q, addr)); 448 449 450 /* Conditional branch tests */ 451 452 /* Simple case, branch to self moved a little */ 453 p = buf; 454 addr = (unsigned long)p; 455 patch_instruction(p, create_cond_branch(p, addr, 0)); 456 check(instr_is_branch_to_addr(p, addr)); 457 q = p + 1; 458 patch_instruction(q, translate_branch(q, p)); 459 check(instr_is_branch_to_addr(q, addr)); 460 461 /* Maximum negative case, move b . to addr + 32 KB */ 462 p = buf; 463 addr = (unsigned long)p; 464 patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC)); 465 q = buf + 0x8000; 466 patch_instruction(q, translate_branch(q, p)); 467 check(instr_is_branch_to_addr(p, addr)); 468 check(instr_is_branch_to_addr(q, addr)); 469 check(*q == 0x43ff8000); 470 471 /* Maximum positive case, move x to x - 32 KB + 4 */ 472 p = buf + 0x8000; 473 addr = (unsigned long)p; 474 patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC)); 475 q = buf + 4; 476 patch_instruction(q, translate_branch(q, p)); 477 check(instr_is_branch_to_addr(p, addr)); 478 check(instr_is_branch_to_addr(q, addr)); 479 check(*q == 0x43ff7ffc); 480 481 /* Jump to x + 12 KB moved to x + 20 KB */ 482 p = buf; 483 addr = 0x3000 + (unsigned long)buf; 484 patch_instruction(p, create_cond_branch(p, addr, BRANCH_SET_LINK)); 485 q = buf + 0x5000; 486 patch_instruction(q, translate_branch(q, p)); 487 check(instr_is_branch_to_addr(p, addr)); 488 check(instr_is_branch_to_addr(q, addr)); 489 490 /* Jump to x + 8 KB moved to x - 8 KB + 4 */ 491 p = buf + 0x2000; 492 addr = 0x4000 + (unsigned long)buf; 493 patch_instruction(p, create_cond_branch(p, addr, 0)); 494 q = buf + 4; 495 patch_instruction(q, translate_branch(q, p)); 496 check(instr_is_branch_to_addr(p, addr)); 497 check(instr_is_branch_to_addr(q, addr)); 498 499 /* Free the buffer we were using */ 500 vfree(buf); 501 } 502 503 static int __init test_code_patching(void) 504 { 505 printk(KERN_DEBUG "Running code patching self-tests ...\n"); 506 507 test_branch_iform(); 508 test_branch_bform(); 509 test_create_function_call(); 510 test_translate_branch(); 511 512 return 0; 513 } 514 late_initcall(test_code_patching); 515 516 #endif /* CONFIG_CODE_PATCHING_SELFTEST */ 517