diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-06-05 16:35:30 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-06-05 16:35:30 +0200 |
commit | 8c6e549a447c51f4f8c0ba7f1e444469f75a354a (patch) | |
tree | b3b423b8eb711732cad912d9340d08cea0f132bc /arch/x86 | |
parent | 3e39db4ae2a92ae9e338e8066411b694b0edcb31 (diff) | |
parent | 5cdb76d6f0b657c1140de74ed5af7cc8c5ed5faf (diff) | |
download | linux-8c6e549a447c51f4f8c0ba7f1e444469f75a354a.tar.bz2 |
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/x86')
-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 { struct { u8 fixups; u8 ilen; - } def; + } defparam; }; }; 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) * If arch_uprobe->insn doesn't use rip-relative addressing, return * immediately. Otherwise, rewrite the instruction so that it accesses * its memory operand indirectly through a scratch register. Set - * def->fixups accordingly. (The contents of the scratch register + * defparam->fixups accordingly. (The contents of the scratch register * will be saved before we single-step the modified instruction, * and restored afterward). * @@ -372,14 +372,14 @@ static void riprel_analyze(struct arch_uprobe *auprobe, struct insn *insn) */ if (reg != 6 && reg2 != 6) { reg2 = 6; - auprobe->def.fixups |= UPROBE_FIX_RIP_SI; + auprobe->defparam.fixups |= UPROBE_FIX_RIP_SI; } else if (reg != 7 && reg2 != 7) { reg2 = 7; - auprobe->def.fixups |= UPROBE_FIX_RIP_DI; + auprobe->defparam.fixups |= UPROBE_FIX_RIP_DI; /* TODO (paranoia): force maskmovq to not use di */ } else { reg2 = 3; - auprobe->def.fixups |= UPROBE_FIX_RIP_BX; + auprobe->defparam.fixups |= UPROBE_FIX_RIP_BX; } /* * 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) static inline unsigned long * scratch_reg(struct arch_uprobe *auprobe, struct pt_regs *regs) { - if (auprobe->def.fixups & UPROBE_FIX_RIP_SI) + if (auprobe->defparam.fixups & UPROBE_FIX_RIP_SI) return ®s->si; - if (auprobe->def.fixups & UPROBE_FIX_RIP_DI) + if (auprobe->defparam.fixups & UPROBE_FIX_RIP_DI) return ®s->di; return ®s->bx; } @@ -411,18 +411,18 @@ scratch_reg(struct arch_uprobe *auprobe, struct pt_regs *regs) */ static void riprel_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) { - if (auprobe->def.fixups & UPROBE_FIX_RIP_MASK) { + if (auprobe->defparam.fixups & UPROBE_FIX_RIP_MASK) { struct uprobe_task *utask = current->utask; unsigned long *sr = scratch_reg(auprobe, regs); utask->autask.saved_scratch_register = *sr; - *sr = utask->vaddr + auprobe->def.ilen; + *sr = utask->vaddr + auprobe->defparam.ilen; } } static void riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) { - if (auprobe->def.fixups & UPROBE_FIX_RIP_MASK) { + if (auprobe->defparam.fixups & UPROBE_FIX_RIP_MASK) { struct uprobe_task *utask = current->utask; unsigned long *sr = scratch_reg(auprobe, regs); @@ -499,16 +499,16 @@ static int default_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs struct uprobe_task *utask = current->utask; riprel_post_xol(auprobe, regs); - if (auprobe->def.fixups & UPROBE_FIX_IP) { + if (auprobe->defparam.fixups & UPROBE_FIX_IP) { long correction = utask->vaddr - utask->xol_vaddr; regs->ip += correction; - } else if (auprobe->def.fixups & UPROBE_FIX_CALL) { - regs->sp += sizeof_long(); - if (push_ret_address(regs, utask->vaddr + auprobe->def.ilen)) + } else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) { + regs->sp += sizeof_long(); /* Pop incorrect return address */ + if (push_ret_address(regs, utask->vaddr + auprobe->defparam.ilen)) return -ERESTART; } /* popf; tell the caller to not touch TF */ - if (auprobe->def.fixups & UPROBE_FIX_SETF) + if (auprobe->defparam.fixups & UPROBE_FIX_SETF) utask->autask.saved_tf = true; return 0; @@ -711,12 +711,11 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, /* * Figure out which fixups default_post_xol_op() will need to perform, - * and annotate def->fixups accordingly. To start with, ->fixups is - * either zero or it reflects rip-related fixups. + * and annotate defparam->fixups accordingly. */ switch (OPCODE1(&insn)) { case 0x9d: /* popf */ - auprobe->def.fixups |= UPROBE_FIX_SETF; + auprobe->defparam.fixups |= UPROBE_FIX_SETF; break; case 0xc3: /* ret or lret -- ip is correct */ case 0xcb: @@ -742,8 +741,8 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, riprel_analyze(auprobe, &insn); } - auprobe->def.ilen = insn.length; - auprobe->def.fixups |= fix_ip_or_call; + auprobe->defparam.ilen = insn.length; + auprobe->defparam.fixups |= fix_ip_or_call; auprobe->ops = &default_xol_ops; return 0; |