aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-06-05 10:35:30 -0400
committerIngo Molnar <mingo@kernel.org>2014-06-05 10:35:30 -0400
commit8c6e549a447c51f4f8c0ba7f1e444469f75a354a (patch)
treeb3b423b8eb711732cad912d9340d08cea0f132bc /arch
parent3e39db4ae2a92ae9e338e8066411b694b0edcb31 (diff)
parent5cdb76d6f0b657c1140de74ed5af7cc8c5ed5faf (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.h2
-rw-r--r--arch/x86/kernel/uprobes.c37
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)
398static inline unsigned long * 398static inline unsigned long *
399scratch_reg(struct arch_uprobe *auprobe, struct pt_regs *regs) 399scratch_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 &regs->si; 402 return &regs->si;
403 if (auprobe->def.fixups & UPROBE_FIX_RIP_DI) 403 if (auprobe->defparam.fixups & UPROBE_FIX_RIP_DI)
404 return &regs->di; 404 return &regs->di;
405 return &regs->bx; 405 return &regs->bx;
406} 406}
@@ -411,18 +411,18 @@ scratch_reg(struct arch_uprobe *auprobe, struct pt_regs *regs)
411 */ 411 */
412static void riprel_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 412static 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
423static void riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) 423static 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;