diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-06-05 10:35:30 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-06-05 10:35:30 -0400 |
commit | 8c6e549a447c51f4f8c0ba7f1e444469f75a354a (patch) | |
tree | b3b423b8eb711732cad912d9340d08cea0f132bc /arch | |
parent | 3e39db4ae2a92ae9e338e8066411b694b0edcb31 (diff) | |
parent | 5cdb76d6f0b657c1140de74ed5af7cc8c5ed5faf (diff) |
Merge branch 'uprobes/core' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg/misc into perf/core
Pull uprobes tmpfs support patches from Oleg Nesterov.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/uprobes.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/uprobes.c | 37 |
2 files changed, 19 insertions, 20 deletions
diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h index 7be3c079e389..74f4c2ff6427 100644 --- a/arch/x86/include/asm/uprobes.h +++ b/arch/x86/include/asm/uprobes.h | |||
@@ -52,7 +52,7 @@ struct arch_uprobe { | |||
52 | struct { | 52 | struct { |
53 | u8 fixups; | 53 | u8 fixups; |
54 | u8 ilen; | 54 | u8 ilen; |
55 | } def; | 55 | } defparam; |
56 | }; | 56 | }; |
57 | }; | 57 | }; |
58 | 58 | ||
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 159ca520ef5b..5d1cbfe4ae58 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c | |||
@@ -254,7 +254,7 @@ static inline bool is_64bit_mm(struct mm_struct *mm) | |||
254 | * If arch_uprobe->insn doesn't use rip-relative addressing, return | 254 | * If arch_uprobe->insn doesn't use rip-relative addressing, return |
255 | * immediately. Otherwise, rewrite the instruction so that it accesses | 255 | * immediately. Otherwise, rewrite the instruction so that it accesses |
256 | * its memory operand indirectly through a scratch register. Set | 256 | * its memory operand indirectly through a scratch register. Set |
257 | * def->fixups accordingly. (The contents of the scratch register | 257 | * defparam->fixups accordingly. (The contents of the scratch register |
258 | * will be saved before we single-step the modified instruction, | 258 | * will be saved before we single-step the modified instruction, |
259 | * and restored afterward). | 259 | * and restored afterward). |
260 | * | 260 | * |
@@ -372,14 +372,14 @@ static void riprel_analyze(struct arch_uprobe *auprobe, struct insn *insn) | |||
372 | */ | 372 | */ |
373 | if (reg != 6 && reg2 != 6) { | 373 | if (reg != 6 && reg2 != 6) { |
374 | reg2 = 6; | 374 | reg2 = 6; |
375 | auprobe->def.fixups |= UPROBE_FIX_RIP_SI; | 375 | auprobe->defparam.fixups |= UPROBE_FIX_RIP_SI; |
376 | } else if (reg != 7 && reg2 != 7) { | 376 | } else if (reg != 7 && reg2 != 7) { |
377 | reg2 = 7; | 377 | reg2 = 7; |
378 | auprobe->def.fixups |= UPROBE_FIX_RIP_DI; | 378 | auprobe->defparam.fixups |= UPROBE_FIX_RIP_DI; |
379 | /* TODO (paranoia): force maskmovq to not use di */ | 379 | /* TODO (paranoia): force maskmovq to not use di */ |
380 | } else { | 380 | } else { |
381 | reg2 = 3; | 381 | reg2 = 3; |
382 | auprobe->def.fixups |= UPROBE_FIX_RIP_BX; | 382 | auprobe->defparam.fixups |= UPROBE_FIX_RIP_BX; |
383 | } | 383 | } |
384 | /* | 384 | /* |
385 | * Point cursor at the modrm byte. The next 4 bytes are the | 385 | * Point cursor at the modrm byte. The next 4 bytes are the |
@@ -398,9 +398,9 @@ static void riprel_analyze(struct arch_uprobe *auprobe, struct insn *insn) | |||
398 | static inline unsigned long * | 398 | static inline unsigned long * |
399 | scratch_reg(struct arch_uprobe *auprobe, struct pt_regs *regs) | 399 | scratch_reg(struct arch_uprobe *auprobe, struct pt_regs *regs) |
400 | { | 400 | { |
401 | if (auprobe->def.fixups & UPROBE_FIX_RIP_SI) | 401 | if (auprobe->defparam.fixups & UPROBE_FIX_RIP_SI) |
402 | return ®s->si; | 402 | return ®s->si; |
403 | if (auprobe->def.fixups & UPROBE_FIX_RIP_DI) | 403 | if (auprobe->defparam.fixups & UPROBE_FIX_RIP_DI) |
404 | return ®s->di; | 404 | return ®s->di; |
405 | return ®s->bx; | 405 | return ®s->bx; |
406 | } | 406 | } |
@@ -411,18 +411,18 @@ scratch_reg(struct arch_uprobe *auprobe, struct pt_regs *regs) | |||
411 | */ | 411 | */ |
412 | static void riprel_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) | 412 | static void riprel_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) |
413 | { | 413 | { |
414 | if (auprobe->def.fixups & UPROBE_FIX_RIP_MASK) { | 414 | if (auprobe->defparam.fixups & UPROBE_FIX_RIP_MASK) { |
415 | struct uprobe_task *utask = current->utask; | 415 | struct uprobe_task *utask = current->utask; |
416 | unsigned long *sr = scratch_reg(auprobe, regs); | 416 | unsigned long *sr = scratch_reg(auprobe, regs); |
417 | 417 | ||
418 | utask->autask.saved_scratch_register = *sr; | 418 | utask->autask.saved_scratch_register = *sr; |
419 | *sr = utask->vaddr + auprobe->def.ilen; | 419 | *sr = utask->vaddr + auprobe->defparam.ilen; |
420 | } | 420 | } |
421 | } | 421 | } |
422 | 422 | ||
423 | static void riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) | 423 | static void riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) |
424 | { | 424 | { |
425 | if (auprobe->def.fixups & UPROBE_FIX_RIP_MASK) { | 425 | if (auprobe->defparam.fixups & UPROBE_FIX_RIP_MASK) { |
426 | struct uprobe_task *utask = current->utask; | 426 | struct uprobe_task *utask = current->utask; |
427 | unsigned long *sr = scratch_reg(auprobe, regs); | 427 | unsigned long *sr = scratch_reg(auprobe, regs); |
428 | 428 | ||
@@ -499,16 +499,16 @@ static int default_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs | |||
499 | struct uprobe_task *utask = current->utask; | 499 | struct uprobe_task *utask = current->utask; |
500 | 500 | ||
501 | riprel_post_xol(auprobe, regs); | 501 | riprel_post_xol(auprobe, regs); |
502 | if (auprobe->def.fixups & UPROBE_FIX_IP) { | 502 | if (auprobe->defparam.fixups & UPROBE_FIX_IP) { |
503 | long correction = utask->vaddr - utask->xol_vaddr; | 503 | long correction = utask->vaddr - utask->xol_vaddr; |
504 | regs->ip += correction; | 504 | regs->ip += correction; |
505 | } else if (auprobe->def.fixups & UPROBE_FIX_CALL) { | 505 | } else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) { |
506 | regs->sp += sizeof_long(); | 506 | regs->sp += sizeof_long(); /* Pop incorrect return address */ |
507 | if (push_ret_address(regs, utask->vaddr + auprobe->def.ilen)) | 507 | if (push_ret_address(regs, utask->vaddr + auprobe->defparam.ilen)) |
508 | return -ERESTART; | 508 | return -ERESTART; |
509 | } | 509 | } |
510 | /* popf; tell the caller to not touch TF */ | 510 | /* popf; tell the caller to not touch TF */ |
511 | if (auprobe->def.fixups & UPROBE_FIX_SETF) | 511 | if (auprobe->defparam.fixups & UPROBE_FIX_SETF) |
512 | utask->autask.saved_tf = true; | 512 | utask->autask.saved_tf = true; |
513 | 513 | ||
514 | return 0; | 514 | return 0; |
@@ -711,12 +711,11 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, | |||
711 | 711 | ||
712 | /* | 712 | /* |
713 | * Figure out which fixups default_post_xol_op() will need to perform, | 713 | * Figure out which fixups default_post_xol_op() will need to perform, |
714 | * and annotate def->fixups accordingly. To start with, ->fixups is | 714 | * and annotate defparam->fixups accordingly. |
715 | * either zero or it reflects rip-related fixups. | ||
716 | */ | 715 | */ |
717 | switch (OPCODE1(&insn)) { | 716 | switch (OPCODE1(&insn)) { |
718 | case 0x9d: /* popf */ | 717 | case 0x9d: /* popf */ |
719 | auprobe->def.fixups |= UPROBE_FIX_SETF; | 718 | auprobe->defparam.fixups |= UPROBE_FIX_SETF; |
720 | break; | 719 | break; |
721 | case 0xc3: /* ret or lret -- ip is correct */ | 720 | case 0xc3: /* ret or lret -- ip is correct */ |
722 | case 0xcb: | 721 | case 0xcb: |
@@ -742,8 +741,8 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, | |||
742 | riprel_analyze(auprobe, &insn); | 741 | riprel_analyze(auprobe, &insn); |
743 | } | 742 | } |
744 | 743 | ||
745 | auprobe->def.ilen = insn.length; | 744 | auprobe->defparam.ilen = insn.length; |
746 | auprobe->def.fixups |= fix_ip_or_call; | 745 | auprobe->defparam.fixups |= fix_ip_or_call; |
747 | 746 | ||
748 | auprobe->ops = &default_xol_ops; | 747 | auprobe->ops = &default_xol_ops; |
749 | return 0; | 748 | return 0; |