| .. | .. |
|---|
| 15 | 15 | #include <linux/extable.h> |
|---|
| 16 | 16 | #include <linux/kdebug.h> |
|---|
| 17 | 17 | #include <linux/kallsyms.h> |
|---|
| 18 | +#include <linux/kgdb.h> |
|---|
| 18 | 19 | #include <linux/ftrace.h> |
|---|
| 19 | 20 | #include <linux/objtool.h> |
|---|
| 20 | 21 | #include <linux/pgtable.h> |
|---|
| .. | .. |
|---|
| 45 | 46 | /* This function only handles jump-optimized kprobe */ |
|---|
| 46 | 47 | if (kp && kprobe_optimized(kp)) { |
|---|
| 47 | 48 | op = container_of(kp, struct optimized_kprobe, kp); |
|---|
| 48 | | - /* If op->list is not empty, op is under optimizing */ |
|---|
| 49 | | - if (list_empty(&op->list)) |
|---|
| 49 | + /* If op is optimized or under unoptimizing */ |
|---|
| 50 | + if (list_empty(&op->list) || optprobe_queued_unopt(op)) |
|---|
| 50 | 51 | goto found; |
|---|
| 51 | 52 | } |
|---|
| 52 | 53 | } |
|---|
| .. | .. |
|---|
| 277 | 278 | return ret; |
|---|
| 278 | 279 | } |
|---|
| 279 | 280 | |
|---|
| 280 | | -static bool is_padding_int3(unsigned long addr, unsigned long eaddr) |
|---|
| 281 | | -{ |
|---|
| 282 | | - unsigned char ops; |
|---|
| 283 | | - |
|---|
| 284 | | - for (; addr < eaddr; addr++) { |
|---|
| 285 | | - if (get_kernel_nofault(ops, (void *)addr) < 0 || |
|---|
| 286 | | - ops != INT3_INSN_OPCODE) |
|---|
| 287 | | - return false; |
|---|
| 288 | | - } |
|---|
| 289 | | - |
|---|
| 290 | | - return true; |
|---|
| 291 | | -} |
|---|
| 292 | | - |
|---|
| 293 | 281 | /* Decode whole function to ensure any instructions don't jump into target */ |
|---|
| 294 | 282 | static int can_optimize(unsigned long paddr) |
|---|
| 295 | 283 | { |
|---|
| .. | .. |
|---|
| 317 | 305 | addr = paddr - offset; |
|---|
| 318 | 306 | while (addr < paddr - offset + size) { /* Decode until function end */ |
|---|
| 319 | 307 | unsigned long recovered_insn; |
|---|
| 308 | + int ret; |
|---|
| 309 | + |
|---|
| 320 | 310 | if (search_exception_tables(addr)) |
|---|
| 321 | 311 | /* |
|---|
| 322 | 312 | * Since some fixup code will jumps into this function, |
|---|
| .. | .. |
|---|
| 326 | 316 | recovered_insn = recover_probed_instruction(buf, addr); |
|---|
| 327 | 317 | if (!recovered_insn) |
|---|
| 328 | 318 | return 0; |
|---|
| 329 | | - kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE); |
|---|
| 330 | | - insn_get_length(&insn); |
|---|
| 331 | | - /* |
|---|
| 332 | | - * In the case of detecting unknown breakpoint, this could be |
|---|
| 333 | | - * a padding INT3 between functions. Let's check that all the |
|---|
| 334 | | - * rest of the bytes are also INT3. |
|---|
| 335 | | - */ |
|---|
| 336 | | - if (insn.opcode.bytes[0] == INT3_INSN_OPCODE) |
|---|
| 337 | | - return is_padding_int3(addr, paddr - offset + size) ? 1 : 0; |
|---|
| 338 | 319 | |
|---|
| 320 | + ret = insn_decode(&insn, (void *)recovered_insn, MAX_INSN_SIZE, INSN_MODE_KERN); |
|---|
| 321 | + if (ret < 0) |
|---|
| 322 | + return 0; |
|---|
| 323 | +#ifdef CONFIG_KGDB |
|---|
| 324 | + /* |
|---|
| 325 | + * If there is a dynamically installed kgdb sw breakpoint, |
|---|
| 326 | + * this function should not be probed. |
|---|
| 327 | + */ |
|---|
| 328 | + if (insn.opcode.bytes[0] == INT3_INSN_OPCODE && |
|---|
| 329 | + kgdb_has_hit_break(addr)) |
|---|
| 330 | + return 0; |
|---|
| 331 | +#endif |
|---|
| 339 | 332 | /* Recover address */ |
|---|
| 340 | 333 | insn.kaddr = (void *)addr; |
|---|
| 341 | 334 | insn.next_byte = (void *)(addr + insn.length); |
|---|
| .. | .. |
|---|
| 358 | 351 | |
|---|
| 359 | 352 | for (i = 1; i < op->optinsn.size; i++) { |
|---|
| 360 | 353 | p = get_kprobe(op->kp.addr + i); |
|---|
| 361 | | - if (p && !kprobe_disabled(p)) |
|---|
| 354 | + if (p && !kprobe_disarmed(p)) |
|---|
| 362 | 355 | return -EEXIST; |
|---|
| 363 | 356 | } |
|---|
| 364 | 357 | |
|---|