FInal kprobes rollup patches
Quoted 1 line
From
f87fb3155500f85ffbafc01d6f5b8dc2a3f6184cMon Sep 17 00:00:00 2001
From: Harvey Harrison <[email protected]>
Date: Fri, 14 Dec 2007 22:02:51 -0800
Subject: [PATCH] [RFC] x86: kprobes unification
Further unification work. There is a possible behavior change on X86_32 here.
is_IF_modifier(p->opcode)
to
is_IF_modifier(p->ainsn.insn)
Which should be equivalent, but is not purely cosmetic as the rest of the unification so far.
--- arch/x86/kernel/kprobes_32.c | 43 +++++++++++++++++++++-------- arch/x86/kernel/kprobes_64.c | 60 +++++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 22 deletions(-)
arch/x86/kernel/kprobes_32.c +31 -12
@@ -220,15 +220,21 @@ retry:/* * returns non-zero if opcode modifies the interrupt flag. */ -static int __kprobes is_IF_modifier (kprobe_opcode_t opcode) +static int __kprobes is_IF_modifier (kprobe_opcode_t *insn) { -switch (opcode) { +switch (*insn) {case 0xfa :/* cli */ case 0xfb :/* sti */ case 0xcf :/* iret/iretd */ case 0x9d :/* popf/popfd */ return 1 ; } + +#ifdef CONFIG_X86_64 +/* REX prefix */ +if (*insn >=0x40 && *insn <=0x4f && *++insn ==0xcf ) +return 1 ; +#endif return 0 ; }
@@ -370,7 +376,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,__get_cpu_var (current_kprobe) = p; kcb->kprobe_saved_flags = kcb->kprobe_old_flags = (regs->flags & (TF_MASK |IF_MASK )); -if (is_IF_modifier (p->opcode)) +if (is_IF_modifier (p->ainsn.insn)) kcb->kprobe_saved_flags &= ~IF_MASK ; }
@@ -410,10 +416,9 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)void __kprobes arch_prepare_kretprobe (struct kretprobe_instance *ri,struct pt_regs *regs) { -unsigned long *sara = (unsigned long *)®s->sp; +unsigned long *sara = ®s->sp; ri->ret_addr = (kprobe_opcode_t *) *sara; -/* Replace the return addr with trampoline addr */ *sara = (unsigned long ) &kretprobe_trampoline; }
@@ -528,8 +533,9 @@ no_kprobe:* here. When a retprobed function returns, this probe is hit and * trampoline_probe_handler() runs, calling the kretprobe's handler. */ -void __kprobes kretprobe_trampoline_holder (void ) - { +void __kprobes kretprobe_trampoline_holder (void ) +{ +#ifdef CONFIG_X86_32 asmvolatile (".global kretprobe_trampoline\n" "kretprobe_trampoline: \n" " pushf\n"
@@ -563,6 +569,11 @@ no_kprobe:" addl $20, %esp\n" " popf\n" " ret\n"); +#else + asmvolatile (".global kretprobe_trampoline\n" +"kretprobe_trampoline: \n" +"nop\n" ); +#endif }/*
@@ -658,12 +669,20 @@ void *__kprobes trampoline_handler(struct pt_regs *regs)static void __kprobes resume_execution (struct kprobe *p,struct pt_regs *regs,struct kprobe_ctlblk *kcb) { -unsigned long *tos = (unsigned long *)®s->sp; +unsigned long *tos = ®s->sp; +unsigned long next_rip =0 ;unsigned long copy_ip = (unsigned long )p->ainsn.insn;unsigned long orig_ip = (unsigned long )p->addr; +kprobe_opcode_t *insn = p->ainsn.insn; + +#ifdef CONFIG_X86_64 +/*skip the REX prefix*/ +if (*insn >=0x40 && *insn <=0x4f ) + insn++; +#endif regs->flags &= ~TF_MASK ; -switch (p->ainsn.insn[0 ]) { +switch (*insn) {case 0x9c :/* pushfl */ *tos &= ~(TF_MASK |IF_MASK ); *tos |= kcb->kprobe_old_flags;
@@ -684,7 +703,7 @@ static void __kprobes resume_execution(struct kprobe *p, *tos = orig_ip + (*tos - copy_ip); goto no_change;case 0xff : -if ((p->ainsn.insn[1 ] &0x30 ) ==0x10 ) { +if ((insn[1 ] &0x30 ) ==0x10 ) {/* * call absolute, indirect * Fix return addr; ip is correct.
@@ -692,8 +711,8 @@ static void __kprobes resume_execution(struct kprobe *p,*/ *tos = orig_ip + (*tos - copy_ip); goto no_change; - }else if (((p->ainsn.insn[1 ] &0x31 ) ==0x20 ) ||/* jmp near, absolute indirect */ - ((p->ainsn.insn[1 ] &0x31 ) ==0x21 )) {/* jmp far, absolute indirect */ + }else if (((insn[1 ] &0x31 ) ==0x20 ) ||/* jmp near, absolute indirect */ + ((insn[1 ] &0x31 ) ==0x21 )) {/* jmp far, absolute indirect */ /* ip is correct. And this is boostable */ p->ainsn.boostable =1 ; goto no_change;
arch/x86/kernel/kprobes_64.c +50 -10
107 lines not on this page · raw message
Signature · 1 line
1.5.4.rc0.1083.gf568
Quoted 1 line
From
4a048bf0c67558b8170dcde7c8395f6c35592f0bMon Sep 17 00:00:00 2001
From: Harvey Harrison <[email protected]>
Date: Fri, 14 Dec 2007 22:52:44 -0800
Subject: [PATCH] x86: Move some exception fixup logic in kprobes_{32|64}.c
--- arch/x86/kernel/kprobes_32.c | 21 ++++++++++++++++++--- arch/x86/kernel/kprobes_64.c | 21 ++++++++++++++++----- 2 files changed, 34 insertions(+), 8 deletions(-)
arch/x86/kernel/kprobes_32.c +18 -3
@@ -533,7 +533,7 @@ no_kprobe:* here. When a retprobed function returns, this probe is hit and * trampoline_probe_handler() runs, calling the kretprobe's handler. */ -void __kprobes kretprobe_trampoline_holder (void ) +void kretprobe_trampoline_holder (void ) {#ifdef CONFIG_X86_32 asm volatile ( ".global kretprobe_trampoline\n"
@@ -787,6 +787,9 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) {struct kprobe *cur =kprobe_running ();struct kprobe_ctlblk *kcb =get_kprobe_ctlblk (); +#ifdef CONFIG_X86_64 +const struct exception_table_entry *fixup; +#endif switch (kcb->kprobe_status) {case KPROBE_HIT_SS :
@@ -829,11 +832,18 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)* In case the user-specified fault handler returned * zero, try to fix up. */ +#ifdef CONFIG_X86_32 if (fixup_exception (regs))return 1 ; - +#else + fixup =search_exception_tables (regs->ip); +if (fixup) { + regs->ip = fixup->fixup; +return 1 ; + } +#endif /* -* fixup_exception() could not handle it, +* Exception couldn't be fixed up, * Let do_page_fault() fix it. */ break ;
@@ -852,8 +862,13 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,struct die_args *args = (struct die_args *)data;int ret =NOTIFY_DONE ; +#ifdef CONFIG_X86_32 if (args->regs &&user_mode_vm (args->regs))return ret; +#else +if (args->regs &&user_mode (args->regs)) +return ret; +#endif switch (val) {case DIE_INT3 :
arch/x86/kernel/kprobes_64.c +16 -5
@@ -769,7 +769,9 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) {struct kprobe *cur =kprobe_running ();struct kprobe_ctlblk *kcb =get_kprobe_ctlblk (); +#ifdef CONFIG_X86_64 const struct exception_table_entry *fixup; +#endif switch (kcb->kprobe_status) {case KPROBE_HIT_SS :
@@ -812,14 +814,18 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)* In case the user-specified fault handler returned * zero, try to fix up. */ +#ifdef CONFIG_X86_32 +if (fixup_exception (regs)) +return 1 ; +#else fixup =search_exception_tables (regs->ip);if (fixup) { regs->ip = fixup->fixup;return 1 ; } - +#endif /* -* fixup() could not handle it, +* Exception couldn't be fixed up, * Let do_page_fault() fix it. */ break ;
@@ -838,8 +844,13 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,struct die_args *args = (struct die_args *)data;int ret =NOTIFY_DONE ; +#ifdef CONFIG_X86_32 +if (args->regs &&user_mode_vm (args->regs)) +return ret; +#else if (args->regs &&user_mode (args->regs))return ret; +#endif switch (val) {case DIE_INT3 :
@@ -871,7 +882,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)struct kprobe_ctlblk *kcb =get_kprobe_ctlblk (); kcb->jprobe_saved_regs = *regs; - kcb->jprobe_saved_sp = (long *) regs->sp; + kcb->jprobe_saved_sp = ®s->sp; addr = (unsigned long )(kcb->jprobe_saved_sp);/* * As Linus pointed out, gcc assumes that the callee
@@ -916,12 +927,12 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) struct jprobe *jp = container_of(p, struct jprobe, kp);if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { -if ((long *)regs->sp != kcb->jprobe_saved_sp) { +if (®s->sp != kcb->jprobe_saved_sp) {struct pt_regs *saved_regs =container_of (kcb->jprobe_saved_sp, struct pt_regs, sp);printk ("current sp %p does not match saved sp %p\n" , - (long *)regs->sp, kcb->jprobe_saved_sp); + ®s->sp, kcb->jprobe_saved_sp);printk ("Saved registers for jprobe %p\n" , jp);show_registers (saved_regs);printk ("Current registers\n" );
Signature · 1 line
1.5.4.rc0.1083.gf568
Quoted 1 line
From
83fde2864abcc34ef8bc575a22b5f8e76477b64bMon Sep 17 00:00:00 2001
From: Harvey Harrison <[email protected]>
Date: Fri, 14 Dec 2007 22:56:50 -0800
Subject: [PATCH] x86: Duplicate some instruction IP logic
--- arch/x86/kernel/kprobes_32.c | 8 ++++++++ arch/x86/kernel/kprobes_64.c | 22 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletions(-)
arch/x86/kernel/kprobes_32.c +8 -0
@@ -721,6 +721,7 @@ static void __kprobes resume_execution(struct kprobe *p,break ; } +#ifdef CONFIG_X86_32 if (p->ainsn.boostable ==0 ) {if ((regs->ip > copy_ip) && (regs->ip - copy_ip) +5 < (MAX_INSN_SIZE +1 )) {
@@ -739,6 +740,13 @@ static void __kprobes resume_execution(struct kprobe *p, regs->ip = orig_ip + (regs->ip - copy_ip); no_change: +#else +if (next_rip) { + regs->ip = next_rip; + }else { + regs->ip = orig_ip + (regs->ip - copy_ip); + } +#endif restore_btf (); }
arch/x86/kernel/kprobes_64.c +21 -1
@@ -719,12 +719,32 @@ static void __kprobes resume_execution(struct kprobe *p,break ; } +#ifdef CONFIG_X86_32 +if (p->ainsn.boostable ==0 ) { +if ((regs->ip > copy_ip) && + (regs->ip - copy_ip) +5 < (MAX_INSN_SIZE +1 )) { +/* +* These instructions can be executed directly if it +* jumps back to correct address. +*/ +set_jmp_op ((void *)regs->ip, + (void *)orig_ip + (regs->ip - copy_ip)); + p->ainsn.boostable =1 ; + }else { + p->ainsn.boostable =-1 ; + } + } + + regs->ip = orig_ip + (regs->ip - copy_ip); + +no_change: +#elseif (next_rip) { regs->ip = next_rip; }else { regs->ip = orig_ip + (regs->ip - copy_ip); } - +#endif restore_btf (); }
Signature · 1 line
1.5.4.rc0.1083.gf568
Quoted 1 line
From
323525be495dc545158fe43e072523d994253c39Mon Sep 17 00:00:00 2001
From: Harvey Harrison <[email protected]>
Date: Sat, 15 Dec 2007 00:28:58 -0800
Subject: [PATCH] x86: Uglify kprobes_{32|64}.c before final unification
--- arch/x86/kernel/kprobes_32.c | 92 ++++++++++++++++++++++++++------ arch/x86/kernel/kprobes_64.c | 118 ++++++++++++++++++++++++++++++++++------- 2 files changed, 172 insertions(+), 38 deletions(-)
arch/x86/kernel/kprobes_32.c +74 -18
190 lines not on this page · raw message
arch/x86/kernel/kprobes_64.c +98 -20
239 lines not on this page · raw message
Signature · 1 line
1.5.4.rc0.1083.gf568
Quoted 1 line
From
e7fd0efa2e7860012d0a625c1fda3174ae200dc5Mon Sep 17 00:00:00 2001
From: Harvey Harrison <[email protected]>
Date: Sat, 15 Dec 2007 00:36:37 -0800
Subject: [PATCH] x86: Final kprobes_{32|64}.c unification
Sure, it's ugly, but it can only get better from here.
--- arch/x86/kernel/kprobes_32.c | 33 +++++++++++++++++++++++++++++++++ arch/x86/kernel/kprobes_64.c | 18 ++++++++++++++++++ 2 files changed, 51 insertions(+), 0 deletions(-)
arch/x86/kernel/kprobes_32.c +33 -0
@@ -20,10 +20,15 @@#include <linux/kprobes.h> #include <linux/ptrace.h> +#include <linux/string.h> +#include <linux/slab.h> #include <linux/preempt.h> +#include <linux/module.h> #include <linux/kdebug.h> +#include <asm/cacheflush.h> #include <asm/desc.h> +#include <asm/pgtable.h> #include <asm/uaccess.h> #include <asm/alternative.h>
@@ -447,6 +452,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) regs->flags &= ~TF_MASK ; regs->flags |= kcb->kprobe_saved_flags; goto no_kprobe; +#ifdef CONFIG_X86_32 }/* We have reentered the kprobe_handler(), since * another probe was hit while within the handler.
@@ -460,6 +466,33 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)prepare_singlestep (p, regs); kcb->kprobe_status =KPROBE_REENTER ;return 1 ; +#else + }else if (kcb->kprobe_status ==KPROBE_HIT_SSDONE ) { +/* TODO: Provide re-entrancy from +* post_kprobes_handler() and avoid exception +* stack corruption while single-stepping on +* the instruction of the new probe. +*/ +arch_disarm_kprobe (p); + regs->ip = (unsigned long )p->addr; +reset_current_kprobe (); + ret =1 ; + }else { +/* We have reentered the kprobe_handler(), since +* another probe was hit while within the +* handler. We here save the original kprobe +* variables and just single step on instruction +* of the new probe without calling any user +* handlers. +*/ +save_previous_kprobe (kcb); +set_current_kprobe (p, regs, kcb); +kprobes_inc_nmissed_count (p); +prepare_singlestep (p, regs); + kcb->kprobe_status =KPROBE_REENTER ; +return 1 ; + } +#endif }else {if (*addr !=BREAKPOINT_INSTRUCTION ) {/* The breakpoint instruction was removed by
arch/x86/kernel/kprobes_64.c +18 -0
@@ -26,6 +26,8 @@#include <linux/module.h> #include <linux/kdebug.h> +#include <asm/cacheflush.h> +#include <asm/desc.h> #include <asm/pgtable.h> #include <asm/uaccess.h> #include <asm/alternative.h>
@@ -450,6 +452,21 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) regs->flags &= ~TF_MASK ; regs->flags |= kcb->kprobe_saved_flags; goto no_kprobe; +#ifdef CONFIG_X86_32 + } +/* We have reentered the kprobe_handler(), since +* another probe was hit while within the handler. +* We here save the original kprobes variables and +* just single step on the instruction of the new probe +* without calling any user handlers. +*/ +save_previous_kprobe (kcb); +set_current_kprobe (p, regs, kcb); +kprobes_inc_nmissed_count (p); +prepare_singlestep (p, regs); + kcb->kprobe_status =KPROBE_REENTER ; +return 1 ; +#else }else if (kcb->kprobe_status ==KPROBE_HIT_SSDONE ) {/* TODO: Provide re-entrancy from * post_kprobes_handler() and avoid exception
@@ -475,6 +492,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) kcb->kprobe_status =KPROBE_REENTER ; return 1; } +#endif }else {if (*addr !=BREAKPOINT_INSTRUCTION ) {/* The breakpoint instruction was removed by
Signature · 1 line
1.5.4.rc0.1083.gf568
Quoted 1 line
From
7fe6bd404ae0c51ec0bd334ca28a1f17f247a099Mon Sep 17 00:00:00 2001
From: Harvey Harrison <[email protected]>
Date: Sat, 15 Dec 2007 00:39:44 -0800
Subject: [PATCH] x86: Eliminate kprobes_{32|64}.c
Now that the files are the same, unify the makefiles and eliminate the duplicates.
--- arch/x86/kernel/Makefile_32 | 2 +- arch/x86/kernel/Makefile_64 | 2 +- arch/x86/kernel/kprobes.c | 1090 ++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/kprobes_32.c | 1090 ------------------------------------------ arch/x86/kernel/kprobes_64.c | 1090 ------------------------------------------ 5 files changed, 1092 insertions(+), 2182 deletions(-)
arch/x86/kernel/Makefile_32 +1 -1
@@ -35,7 +35,7 @@ obj-$(CONFIG_KEXEC) += machine_kexec_32.o relocate_kernel_32.o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_32.o obj-$(CONFIG_X86_NUMAQ) += numaq_32.o obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o -obj-$(CONFIG_KPROBES) += kprobes_32.o +obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_MODULES) += module_32.o obj-$(CONFIG_ACPI_SRAT) += srat_32.o obj-$(CONFIG_EFI) += efi.o efi_32.o efi_stub_32.o
arch/x86/kernel/Makefile_64 +1 -1
@@ -34,7 +34,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o -obj-$(CONFIG_KPROBES) += kprobes_64.o +obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o obj-$(CONFIG_X86_VSMP) += vsmp_64.o obj-$(CONFIG_K8_NB) += k8.o
arch/x86/kernel/kprobes.c new file +1090 -0
1,090 lines not on this page · raw message
arch/x86/kernel/kprobes_32.c deleted +0 -1090
996 lines not on this page · raw message
arch/x86/kernel/kprobes_64.c deleted +0 -1090
1,090 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
1.5.4.rc0.1083.gf568
Part of the diff is not shown here. View the raw message.
Quoted 11 lines · Harvey Harrison
Further unification work. There is a possible behavior change on
X86_32here.
is_IF_modifier(p->opcode)to
is_IF_modifier(p->ainsn.insn)Which should be equivalent, but is not purely cosmetic as the rest of the unification so far.
hm, could you split this into two, the pure-equivalence and the possibly-modifying patch? (that way any potential breakage becomes bisectable) Same end result, just two commits instead of one.
also, did you manage to run/test kprobes (on 32-bit or 64-bit x86), and it worked fine?
Ingo
Quoted 9 lines · Ingo Molnar
Quoted 7 lines · Harvey Harrison
Further unification work. There is a possible behavior change on
X86_32here.
is_IF_modifier(p->opcode)to
Quoted 9 lines
Quoted 4 lines
is_IF_modifier(p->ainsn.insn)Which should be equivalent, but is not purely cosmetic as the rest of the unification so far.
hm, could you split this into two, the pure-equivalence and the possibly-modifying patch? (that way any potential breakage becomes bisectable) Same end result, just two commits instead of one.
Sure, I'll go back through and see if the series can be cleaned up a bit as well as expand the commit message a little bit.
Quoted 3 lines
also, did you manage to run/test kprobes (on 32-bit or 64-bit x86), and it worked fine?
Sorry, I should have predicated the whole series with RFC. Currently this is compile-tested only. There is only the one patch that has any behavioral change. I believe the series also pointed out an existing bug in the 32-bit version...which I've preserved but will note in the commit messages in the respun series.
In case you're interested, from the patch which unifies the definition of MAX_INSTRUCTION_SIZE:
memcpy(p->ainsn.insn, p->addr, (MAX_INSN_SIZE + 1) * sizeof(kprobe_opcode_t));
If you compare this memcpy from arch_prepare_kprobe in 32/64 bit I'm almost sure the X86_32 version should be
... + sizeof(kprobe_opcode_t)
not
... * sizeof(kprobe_opcode_t)
Cheers,
Harvey
Quoted 8 lines · Harvey Harrison
If you compare this memcpy from
arch_prepare_kprobein 32/64 bit I'm almost sure theX86_32version should be... +
sizeof(kprobe_opcode_t)not
... *
sizeof(kprobe_opcode_t)
good point. I've Cc:-ed the top authors of kprobes.c. Could anyone confirm (or deny) that Harvey found a real kprobes bug here?
Ingo
Hi Harvey and Ingo,
I'm working on another version of patches for unification. Currently cleaning up the patches.
http://sources.redhat.com/ml/systemtap/2007-q4/msg00457.html
I'll cleanup and repost it today.
Quoted 20 lines · Ingo Molnar
Quoted 8 lines · Harvey Harrison
If you compare this memcpy from
arch_prepare_kprobein 32/64 bit I'm almost sure theX86_32version should be... +
sizeof(kprobe_opcode_t)not
... *
sizeof(kprobe_opcode_t)good point. I've Cc:-ed the top authors of
kprobes.c. Could anyone confirm (or deny) that Harvey found a real kprobes bug here?Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected], [email protected]
* Ingo Molnar <[email protected]> [2007-12-15 14:12:04]:
Hi Ingo, Harvey
In file include/asm-x86/kprobes_32.h
typedef u8 kprobe_opcode_t;
hence sizeof(kprobe_opcode_t) turns out to be 1.
Hence
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); is correct.
--
Regards
Srikar
Quoted 22 lines · Harvey Harrison
Quoted 9 lines
If you compare this memcpy from
arch_prepare_kprobein 32/64 bit I'm almost sure theX86_32version should be... +
sizeof(kprobe_opcode_t)not
... *
sizeof(kprobe_opcode_t)good point. I've Cc:-ed the top authors of
kprobes.c. Could anyone confirm (or deny) that Harvey found a real kprobes bug here?Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: Final kprobes rollup patches
In reply to Masami HiramatsuMasami,
Quoted 6 lines · Masami Hiramatsu
Hi Harvey and Ingo,
I'm working on another version of patches for unification. Currently cleaning up the patches.
http://sources.redhat.com/ml/systemtap/2007-q4/msg00457.html
I'll cleanup and repost it today.
cool! Please Cc: lkml and Harvey as well so that there's less overlap in unification work - Harvey spent quite some time unifying and cleaning up the kprobes code during the past week.
So i think we could/should use Harvey's latest series as a base, those are pretty finegrained already. Note that they break 64-bit kprobes though, with such a config:
CONFIG_KPROBES=y
CONFIG_NET_TCPPROBE=y
so it crashes with an int3 in the TCP code. It's probably some trivial typo somewhere, as 32-bit works fine.
the coordinates for x86.git#mm can be found below - that tree already includes Harvey's latest kprobes series. I'll try to bisect the 64-bit breakage now.
Ingo
------------------>
git-clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git linux-2.6.git cd linux-2.6.git
git-branch x86
git-checkout x86
git-pull git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git mm
(do subsequent pulls via "git-pull --force", as we frequently rebase the git tree. NOTE: this might override your own local changes, so do this only if you dont mind about losing thse changes in that tree.)
Hi Ingo, Harvey
In file include/asm-x86/kprobes_32.h
typedef u8 kprobe_opcode_t;
hence sizeof(kprobe_opcode_t) turns out to be 1.
Hence
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); is correct.
--
Regards
Srikar
Quoted 22 lines · Harvey Harrison
Quoted 9 lines
If you compare this memcpy from
arch_prepare_kprobein 32/64 bit I'm almost sure theX86_32version should be... +
sizeof(kprobe_opcode_t)not
... *
sizeof(kprobe_opcode_t)good point. I've Cc:-ed the top authors of
kprobes.c. Could anyone confirm (or deny) that Harvey found a real kprobes bug here?Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: Final kprobes rollup patches
In reply to Ingo MolnarHi Ingo,
Quoted 6 lines · Ingo Molnar
Masami,
Quoted 2 lines · Masami Hiramatsu
Hi Harvey and Ingo,
Quoted 8 lines
Quoted 4 lines
I'm working on another version of patches for unification. Currently cleaning up the patches.
http://sources.redhat.com/ml/systemtap/2007-q4/msg00457.html
I'll cleanup and repost it today.cool! Please Cc: lkml and Harvey as well so that there's less overlap in unification work - Harvey spent quite some time unifying and cleaning up the kprobes code during the past week.
Should I rewrite it based on current git tree?
My patch includes 3 part of patches.
- 2 Bugfix patches (which is not merged yet.)
- 2 booster patches (ditto)
- 2 unification patches (most of this patches are already done by Harvey's patch)
Quoted 28 lines
So i think we could/should use Harvey's latest series as a base, those are pretty finegrained already. Note that they break 64-bit kprobes though, with such a config:
CONFIG_KPROBES=y
CONFIG_NET_TCPPROBE=yso it crashes with an int3 in the TCP code. It's probably some trivial typo somewhere, as 32-bit works fine.
the coordinates for x86.git#mm can be found below - that tree already includes Harvey's latest kprobes series. I'll try to bisect the 64-bit breakage now.
Ingo
------------------>
git-clonegit://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.gitlinux-2.6.git cd linux-2.6.git
git-branch x86
git-checkout x86
git-pullgit://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.gitmm(do subsequent pulls via "git-pull --force", as we frequently rebase the git tree. NOTE: this might override your own local changes, so do this only if you dont mind about losing thse changes in that tree.)
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected], [email protected]
Re: Final kprobes rollup patches
Quoted 9 lines · Masami Hiramatsu
Quoted 3 lines
cool! Please Cc: lkml and Harvey as well so that there's less overlap in unification work - Harvey spent quite some time unifying and cleaning up the kprobes code during the past week.
Should I rewrite it based on current git tree?
My patch includes 3 part of patches.
- 2 Bugfix patches (which is not merged yet.)
- 2 booster patches (ditto)
- 2 unification patches (most of this patches are already done by Harvey's patch)
would it be easier/more robust to first did the unification patches and then get the bugfixes and new features in? That would give us your bugfixes and new features on both 32-bit and 64-bit at the same time.
feel free to do whichever approach you prefer - but it would be nice to preserve the unification and cleanup work done by Harvey.
btw., is any of your bugfixes 2.6.24 material?
Ingo
Re: Final kprobes rollup patches
Hi Ingo,
Quoted 11 lines · Ingo Molnar
Quoted 8 lines · Masami Hiramatsu
Quoted 3 lines
cool! Please Cc: lkml and Harvey as well so that there's less overlap in unification work - Harvey spent quite some time unifying and cleaning up the kprobes code during the past week.
Should I rewrite it based on current git tree?
My patch includes 3 part of patches.
- 2 Bugfix patches (which is not merged yet.)
- 2 booster patches (ditto)
- 2 unification patches (most of this patches are already done by Harvey's patch)
Quoted 3 lines
would it be easier/more robust to first did the unification patches and then get the bugfixes and new features in? That would give us your bugfixes and new features on both 32-bit and 64-bit at the same time.
As far as I can see, my patches have less #ifdefs than Harvey's. However, that patch's granularity may be not so good currently.
Quoted 2 lines
feel free to do whichever approach you prefer - but it would be nice to preserve the unification and cleanup work done by Harvey.
OK, rewriting will take a while, so I sent a series of patches which I have just now.
Quoted 1 line
btw., is any of your bugfixes 2.6.24 material?
Yes, I'd like to fix first two bugs in 2.6.24.
Thank you very much,
Quoted 2 lines
Ingo
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected], [email protected]
Quoted 5 lines · Srikar Dronamraju
* Ingo Molnar <[email protected]> [2007-12-15 14:12:04]:
Hi Ingo, Harvey
Quoted 9 lines
In file
include/asm-x86/kprobes_32.h
typedef u8kprobe_opcode_t;
hencesizeof(kprobe_opcode_t)turns out to be 1.Hence
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); is correct.
OK, but this would be much clearer to adopt the X86_64 way, define MAX_INSN_SIZE one smaller and make this line:
/* Copy original instruction plus space for 1 byte relative jump */ memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE + sizeof(kprobe_opcode_t));
See the first patch of my cleanup work that unified MAX_INSN_SIZE and you'll see why this jumped out.
Harvey
Re: Final kprobes rollup patches
In reply to Ingo MolnarQuoted 12 lines · Ingo Molnar
Quoted 9 lines · Masami Hiramatsu
Quoted 3 lines
cool! Please Cc: lkml and Harvey as well so that there's less overlap in unification work - Harvey spent quite some time unifying and cleaning up the kprobes code during the past week.
Should I rewrite it based on current git tree?
My patch includes 3 part of patches.
- 2 Bugfix patches (which is not merged yet.)
- 2 booster patches (ditto)
- 2 unification patches (most of this patches are already done by Harvey's patch)
Quoted 9 lines
would it be easier/more robust to first did the unification patches and then get the bugfixes and new features in? That would give us your bugfixes and new features on both 32-bit and 64-bit at the same time.
feel free to do whichever approach you prefer - but it would be nice to preserve the unification and cleanup work done by Harvey.
btw., is any of your bugfixes 2.6.24 material?
Well, I'll admit to being a little disappointed if my work doesn't make it in, but there are bugfixes here. I think my cleanup breakout is better in the more-finegrained changes sense. If you decide to keep mine I'll rebase Masami's patches 1-4 on top of that and send it by him for resubmittal. But I'll leave it to Ingo to decide how to procede.
Harvey
Hi Harvey,
Quoted 19 lines · Harvey Harrison
Quoted 5 lines · Srikar Dronamraju
* Ingo Molnar <[email protected]> [2007-12-15 14:12:04]:
Hi Ingo, Harvey
Quoted 9 lines
In file
include/asm-x86/kprobes_32.h
typedef u8kprobe_opcode_t;
hencesizeof(kprobe_opcode_t)turns out to be 1.Hence
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); is correct.OK, but this would be much clearer to adopt the
X86_64way, defineMAX_INSN_SIZEone smaller and make this line:
Quoted 7 lines
/* Copy original instruction plus space for 1 byte relative jump */
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE + sizeof(kprobe_opcode_t));See the first patch of my cleanup work that unified
MAX_INSN_SIZEand you'll see why this jumped out.Harvey
If you mention about a relative jump which is inserted by resume_execution(), I think you might misunderstand that relative jump.
The size of that relative jump, which will be embedded by kprobe-booster, is 5-bytes(not 1 byte). So it needs 5 bytes space.
And we decided not to expand MAX_INSN_SIZE when we developed the booster. The reasons are:
- it is supplemental feature(just accelerating kprobes), if we have no space, we can disable it.
- 5 bytes are big enough compared with 15(=MAX_INSN_SIZE)
- the lengths of most of instructions are less than 10 bytes.
Additionally, MAX_INSN_SIZE is used in kernel/kprobes.c to allocate an instruction buffer which will be assigned to p->ainsn.insn. Since the instruction buffer size is MAX_INSN_SIZE, you can not copy instructions more than MAX_INSN_SIZE.
BTW, in my patch, I unified MAX_INSN_SIZE to bigger one(16). I think it is enough for us.
Thanks,
Best Regards,
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected], [email protected]
Quoted 13 lines · Masami Hiramatsu
Hi Harvey,
If you mention about a relative jump which is inserted byresume_execution(), I think you might misunderstand that relative jump.The size of that relative jump, which will be embedded by kprobe-booster, is 5-bytes(not 1 byte). So it needs 5 bytes space.
And we decided not to expandMAX_INSN_SIZEwhen we developed the booster. The reasons are:
- it is supplemental feature(just accelerating kprobes), if we have no space, we can disable it.
- 5 bytes are big enough compared with 15(=MAX_INSN_SIZE)
- the lengths of most of instructions are less than 10 bytes.
Quoted 8 lines
Additionally,
MAX_INSN_SIZEis used inkernel/kprobes.cto allocate an instruction buffer which will be assigned top->ainsn.insn. Since the instruction buffer size isMAX_INSN_SIZE, you can not copy instructions more thanMAX_INSN_SIZE.BTW, in my patch, I unified
MAX_INSN_SIZEto bigger one(16). I think it is enough for us.
I went with 15 in mine, I thought it made the code a little more readable, but I will defer if you think 16 is better. If you want me to send the whole series to you, let me know.
I just sent out a series of 4 patches equivalent to your patches 1-4/6 but based on my already unified kprobes.c/h, You may want to check your handling of restored registers in trampoline_probe_handler which I found when rebasing yours on top of my cleanups. Not sure if this is important, but it was a difference I found.
X86_32:regs->cs = __KERNEL_CS | get_kernel_rpl();
yours:regs->cs = __KERNEL_CS;
Harvey
Hi Harvey,
Quoted 19 lines · Harvey Harrison
Quoted 18 lines · Masami Hiramatsu
Hi Harvey,
If you mention about a relative jump which is inserted byresume_execution(), I think you might misunderstand that relative jump.The size of that relative jump, which will be embedded by kprobe-booster, is 5-bytes(not 1 byte). So it needs 5 bytes space.
And we decided not to expandMAX_INSN_SIZEwhen we developed the booster. The reasons are:
- it is supplemental feature(just accelerating kprobes), if we have no space, we can disable it.
- 5 bytes are big enough compared with 15(=MAX_INSN_SIZE)
- the lengths of most of instructions are less than 10 bytes.Additionally,
MAX_INSN_SIZEis used inkernel/kprobes.cto allocate an instruction buffer which will be assigned top->ainsn.insn. Since the instruction buffer size isMAX_INSN_SIZE, you can not copy instructions more thanMAX_INSN_SIZE.
Quoted 7 lines
Quoted 3 lines
BTW, in my patch, I unified
MAX_INSN_SIZEto bigger one(16). I think it is enough for us.I went with 15 in mine, I thought it made the code a little more readable, but I will defer if you think 16 is better. If you want me to send the whole series to you, let me know.
Before porting, could you tell me what differences are important to you? We can discuss about it.
Quoted 11 lines
I just sent out a series of 4 patches equivalent to your patches 1-4/6 but based on my already unified kprobes.c/h, You may want to check your handling of restored registers in
trampoline_probe_handlerwhich I found when rebasing yours on top of my cleanups. Not sure if this is important, but it was a difference I found.
X86_32:regs->cs=__KERNEL_CS|get_kernel_rpl();yours:
regs->cs=__KERNEL_CS;
Because of kretprobe's compatibility, on x86-32 cs should be set rpl(). But get_kernel_rpl() does not exist on x86-64.
Thanks,
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected], [email protected]
Quoted 10 lines · Masami Hiramatsu
Hi Harvey,
Before porting, could you tell me what differences are important to you? We can discuss about it.Quoted 6 lines
I just sent out a series of 4 patches equivalent to your patches 1-4/6 but based on my already unified kprobes.c/h, You may want to check your handling of restored registers in
trampoline_probe_handlerwhich I found when rebasing yours on top of my cleanups. Not sure if this is important, but it was a difference I found.
Quoted 9 lines
Quoted 5 lines
X86_32:regs->cs=__KERNEL_CS|get_kernel_rpl();yours:
regs->cs=__KERNEL_CS;Because of kretprobe's compatibility, on x86-32 cs should be set
rpl(). Butget_kernel_rpl()does not exist on x86-64.
I've already ported it and sent it to you. It's not really important to me I just think my fine-grained patches may be of some use to see where the differences between X86_32/64 ended up being. Your patches end up being just about entirely removal of ifdefs when rebased onto my patches, so it's at least a good secondary check of your patches even if mine don't go in. Your patches end up being much smaller against my version too.
I like my version slightly better because the remaining ifdefs (wrmsr, etc) and others could be done in a few more small patches that are more easily reviewable than your large final unification patch.
But, you know the code better than I....
Harvey
Hi Harvey,
Quoted 20 lines · Harvey Harrison
Quoted 10 lines · Masami Hiramatsu
Hi Harvey,
Before porting, could you tell me what differences are important to you? We can discuss about it.Quoted 6 lines
I just sent out a series of 4 patches equivalent to your patches 1-4/6 but based on my already unified kprobes.c/h, You may want to check your handling of restored registers in
trampoline_probe_handlerwhich I found when rebasing yours on top of my cleanups. Not sure if this is important, but it was a difference I found.Quoted 8 lines
Quoted 5 lines
X86_32:regs->cs=__KERNEL_CS|get_kernel_rpl();yours:
regs->cs=__KERNEL_CS;Because of kretprobe's compatibility, on x86-32 cs should be set
rpl(). Butget_kernel_rpl()does not exist on x86-64.
Quoted 7 lines
I've already ported it and sent it to you. It's not really important to me I just think my fine-grained patches may be of some use to see where the differences between X86_32/64 ended up being. Your patches end up being just about entirely removal of ifdefs when rebased onto my patches, so it's at least a good secondary check of your patches even if mine don't go in. Your patches end up being much smaller against my version too.
OK, I'll review that.
Quoted 4 lines
I like my version slightly better because the remaining ifdefs (wrmsr, etc) and others could be done in a few more small patches that are more easily reviewable than your large final unification patch.
I agreed that your patches are including some goodness. So let us merge it into one.
Quoted 5 lines
But, you know the code better than I....
Harvey
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected], [email protected]
Quoted 19 lines · Masami Hiramatsu
Hi Harvey,
Quoted 5 lines · Harvey Harrison
Quoted 3 lines · Masami Hiramatsu
Hi Harvey,
Before porting, could you tell me what differences are important to you? We can discuss about it.Quoted 7 lines
I've already ported it and sent it to you. It's not really important to me I just think my fine-grained patches may be of some use to see where the differences between X86_32/64 ended up being. Your patches end up being just about entirely removal of ifdefs when rebased onto my patches, so it's at least a good secondary check of your patches even if mine don't go in. Your patches end up being much smaller against my version too.
OK, I'll review that.
Quoted 1 line
Quoted 8 lines
Quoted 3 lines
I like my version slightly better because the remaining ifdefs (wrmsr, etc) and others could be done in a few more small patches that are more easily reviewable than your large final unification patch.
I agreed that your patches are including some goodness. So let us merge it into one.
OK, I'll take the last bits of your patches 5/6 that aren't already cleaned up and send out a unified patchset for you to add your acked/signed off by/reviewed by as appropriate.
These are:
-add stack_addr() macro
-I prefer the table defintion macros in mine as it avoids the need to cast the pointer passed to test_bit, but if you want them
to be u32 as in your patch, I can change it.
-wrmsr/wrmsrl - use wrmsr() for both
-call is_IF_modifier with p->ainsn.insn in both
-check casting of jprobe_saved_sp, I get some compile warnings currently with pointer comparisons to signed/unsigned types.
That will eliminate nearly all of the remaining ifdefs in my version, let me work through this and I'll send out a set for review.
CHeers,
Harvey
Hi Harvey,
Quoted 20 lines · Harvey Harrison
Quoted 19 lines · Masami Hiramatsu
Hi Harvey,
Quoted 11 lines · Harvey Harrison
Quoted 3 lines · Masami Hiramatsu
Hi Harvey,
Before porting, could you tell me what differences are important to you? We can discuss about it.I've already ported it and sent it to you. It's not really important to me I just think my fine-grained patches may be of some use to see where the differences between X86_32/64 ended up being. Your patches end up being just about entirely removal of ifdefs when rebased onto my patches, so it's at least a good secondary check of your patches even if mine don't go in. Your patches end up being much smaller against my version too.
OK, I'll review that.
Quoted 3 lines
I like my version slightly better because the remaining ifdefs (wrmsr, etc) and others could be done in a few more small patches that are more easily reviewable than your large final unification patch.
Quoted 8 lines
Quoted 4 lines
I agreed that your patches are including some goodness. So let us merge it into one.
OK, I'll take the last bits of your patches 5/6 that aren't already cleaned up and send out a unified patchset for you to add your acked/signed off by/reviewed by as appropriate.
Sure, I'll review it. It is very helpful to me. Please Cc: or To: the parsons who are listed in this mail. Jim, if you can review the fixes which you've suggested, could you give him your signed-off?
Quoted 7 lines
These are:
(quoted diff) +0
-2-add stack_addr() macro -I prefer the table defintion macros in mine as it avoids the need tocast the pointer passed to
test_bit, but if you want them to be u32 as in your patch, I can change it.
please do so. we'd like to reduce ifdefs as less as possible:-)
Quoted 4 lines
(quoted diff) +0
-3-wrmsr/wrmsrl - use wrmsr() for both -call is_IF_modifier with p->ainsn.insn in both -check casting of jprobe_saved_sp, I get some compile warnings currentlywith pointer comparisons to signed/unsigned types.
Could you also add below?
- fix some comments (it clarifies the meanings of the code)
- add fix_riprel(). this useful to reduce ifdefs.
- expand reenter_kprobe(). I think it treat above two blocks.
- reassignment of regs->ip in kprobe_handler can be unified to "regs->ip = (unsigned long)addr;"
Quoted 9 lines
That will eliminate nearly all of the remaining ifdefs in my version, let me work through this and I'll send out a set for review.
CHeers,
Harvey
Best Regards,
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected], [email protected]
Quoted 9 lines · Masami Hiramatsu
Quoted 6 lines
These are:
(quoted diff) +0
-2-add stack_addr() macro -I prefer the table defintion macros in mine as it avoids the need tocast the pointer passed to
test_bit, but if you want them to be u32 as in your patch, I can change it.please do so. we'd like to reduce ifdefs as less as possible:-)
Quoted 11 lines
Quoted 4 lines
(quoted diff) +0
-3-wrmsr/wrmsrl - use wrmsr() for both -call is_IF_modifier with p->ainsn.insn in both -check casting of jprobe_saved_sp, I get some compile warnings currentlywith pointer comparisons to signed/unsigned types.
Could you also add below?
- fix some comments (it clarifies the meanings of the code)
- addfix_riprel(). this useful to reduce ifdefs.
- expandreenter_kprobe(). I think it treat above two blocks.
- reassignment ofregs->ipinkprobe_handlercan be unified to "regs->ip= (unsigned long)addr;"
Oh, I forgot to point out important thing.
- please make bugfix patches first. I think my bugfix patches need to go upstream before unification. It would cause some crashes.
Thank you.
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected], [email protected]
Quoted 24 lines · Masami Hiramatsu
Quoted 4 lines · Masami Hiramatsu
Review
Quoted 4 lines
These are:
(quoted diff) +0
-2-add stack_addr() macro -I prefer the table defintion macros in mine as it avoids the needto
Quoted 8 lines
Quoted 2 lines
cast the pointer passed to
test_bit, but if you want them to be u32 as in your patch, I can change it.please do so. we'd like to reduce ifdefs as less as possible:-)
Review
Quoted 3 lines
(quoted diff) +0
-3-wrmsr/wrmsrl - use wrmsr() for both -call is_IF_modifier with p->ainsn.insn in both -check casting of jprobe_saved_sp, I get some compile warningscurrently
Quoted 8 lines
Quoted 1 line
with pointer comparisons to signed/unsigned types.
Could you also add below?
- fix some comments (it clarifies the meanings of the code)
- addfix_riprel(). this useful to reduce ifdefs.
- expandreenter_kprobe(). I think it treat above two blocks.
- reassignment ofregs->ipinkprobe_handlercan be unified to "regs->ip= (unsigned long)addr;"
Quoted 5 lines
Oh, I forgot to point out important thing.
- please make bugfix patches first. I think my bugfix patches need to go upstream before unification. It would cause some crashes.
It's pretty hard to move those bugfixes to the head of the queue.
Attached is an mbox of my unification work. Maybe you could get your two bugfixes applied to mainline kprobes_32/64.c, then my series could go in as a merge later on. Most of my stuff is in kprobes.c post-unify so the merge would be trivial later.
Ingo, what do you think? This rollup replaces all of my kprobes patches to date. So you could apply patched 1,2/6 from Masami into 2.6.24 and let mine come in during 2.6.25 as a merge, which would avoid the conflicts in kprobes_32|64.c?
Harvey
PATCH 1/1 x86: kprobes use stack_addr() macro
In reply to Masami Hiramatsu---
Replacement for the last patch in the kprobes series I just sent.
arch/x86/kernel/kprobes.c | 45 +++++++++++++++++++++------------------------ 1 files changed, 21 insertions(+), 24 deletions(-)
arch/x86/kernel/kprobes.c +21 -24
@@ -44,6 +44,20 @@ struct kretprobe_blackpoint kretprobe_blacklist[] = { };const int kretprobe_blacklist_size =ARRAY_SIZE (kretprobe_blacklist); +/* +* "®s->sp" looks wrong, but it's correct for x86_32. x86_32 CPUs +* don't save the ss and esp registers if the CPU is already in kernel +* mode when it traps. So for kprobes, regs->sp and regs->ss are not +* the [nonexistent] saved stack pointer and ss register, but rather +* the top 8 bytes of the pre-int3 stack. So ®s->sp happens to +* point to the top of the pre-int3 stack. +*/ +#ifdef CONFIG_X86_32 +# define stack_addr (regs) ((unsigned long *)®s->sp) +#else +# define stack_addr (regs) ((unsigned long *)regs->sp) +#endif +#define W (r, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf) \ (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \
@@ -409,11 +423,8 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)void __kprobes arch_prepare_kretprobe (struct kretprobe_instance *ri,struct pt_regs *regs) { -#ifdef CONFIG_X86_32 -unsigned long *sara = (unsigned long *)®s->sp; -#else -unsigned long *sara = (unsigned long *)regs->sp; -#endif +unsigned long *sara =stack_addr (regs); + ri->ret_addr = (kprobe_opcode_t *) *sara;/* Replace the return addr with trampoline addr */ *sara = (unsigned long ) &kretprobe_trampoline;
@@ -751,11 +762,8 @@ void *__kprobes trampoline_handler(struct pt_regs *regs)static void __kprobes resume_execution (struct kprobe *p,struct pt_regs *regs,struct kprobe_ctlblk *kcb) { -#ifdef CONFIG_X86_32 -unsigned long *tos = (unsigned long *)®s->sp; -#else -unsigned long *tos = (unsigned long *)regs->sp; -#endif + +unsigned long *tos =stack_addr (regs);unsigned long copy_ip = (unsigned long )p->ainsn.insn;unsigned long orig_ip = (unsigned long )p->addr;kprobe_opcode_t *insn = p->ainsn.insn;
@@ -984,11 +992,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)struct kprobe_ctlblk *kcb =get_kprobe_ctlblk (); kcb->jprobe_saved_regs = *regs; -#ifdef CONFIG_X86_32 - kcb->jprobe_saved_sp = ®s->sp; -#else - kcb->jprobe_saved_sp = (long *) regs->sp; -#endif + kcb->jprobe_saved_sp = (long *)stack_addr (regs); addr = (unsigned long )(kcb->jprobe_saved_sp);/* * As Linus pointed out, gcc assumes that the callee
@@ -1033,17 +1037,10 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) struct jprobe *jp = container_of(p, struct jprobe, kp);if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { -#ifdef CONFIG_X86_32 -if (®s->sp != kcb->jprobe_saved_sp) { +if (stack_addr (regs) != kcb->jprobe_saved_sp) {struct pt_regs *saved_regs = &kcb->jprobe_saved_sp;printk ("current sp %p does not match saved sp %p\n" , - ®s->sp, kcb->jprobe_saved_sp); -#else -if ((long *)regs->sp != kcb->jprobe_saved_sp) { -struct pt_regs *saved_regs = &kcb->jprobe_saved_sp; -printk ("current sp %p does not match saved sp %p\n" , - (long *)regs->sp, kcb->jprobe_saved_sp); -#endif +stack_addr (regs), kcb->jprobe_saved_sp);printk ("Saved registers for jprobe %p\n" , jp);show_registers (saved_regs);printk ("Current registers\n" );
Signature · 1 line
1.5.4.rc0.1083.gf568