.. | .. |
---|
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 | |
---|