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