public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* [1/5 PATCH] Kprobes fix for broken fault handling for i386
@ 2006-03-07 13:37 Prasanna S Panchamukhi
  2006-03-07 13:40 ` [2/5 PATCH] Kprobes fix for broken fault handling for x86_64 Prasanna S Panchamukhi
  2006-03-07 21:26 ` [1/5 PATCH] Kprobes fix for broken fault handling for i386 Keshavamurthy Anil S
  0 siblings, 2 replies; 10+ messages in thread
From: Prasanna S Panchamukhi @ 2006-03-07 13:37 UTC (permalink / raw)
  To: systemtap

Hi,

Below is the set of patches to fix broken fault handling
for i386, x86_64, ppc64, ia64 and sparc64 architectures
against 2.6.16-rc5-mm2.

These patches are tested for i386 and x86_64 architectures.
Could you please test it for ia64 and ppc64.

Thanks
Prasanna


This patch provides proper kprobes fault handling, if a user-specified
pre/post handlers tries to access user address space, through
copy_from_user(), get_user() etc. The user-specified fault handler
gets called only if the fault occurs while executing user-specified
handlers. In such a case user-specified handler is allowed to fix it
first, later if the user-specifed fault handler does not fix it, we
try to fix it by calling fix_exception(). The user-specified handler
will not be called if the fault happens when single stepping the
original instruction, instead we reset the current probe and allow the
system page fault handler to fix it up.

Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>


 arch/i386/kernel/kprobes.c |   57 +++++++++++++++++++++++++++++++++++++++------
 1 files changed, 50 insertions(+), 7 deletions(-)

diff -puN arch/i386/kernel/kprobes.c~kprobes-i386-pagefault-handling arch/i386/kernel/kprobes.c
--- linux-2.6.16-rc5-mm2/arch/i386/kernel/kprobes.c~kprobes-i386-pagefault-handling	2006-03-07 11:18:14.000000000 +0530
+++ linux-2.6.16-rc5-mm2-prasanna/arch/i386/kernel/kprobes.c	2006-03-07 11:18:14.000000000 +0530
@@ -35,6 +35,7 @@
 #include <asm/cacheflush.h>
 #include <asm/kdebug.h>
 #include <asm/desc.h>
+#include <asm/uaccess.h>
 
 void jprobe_return_end(void);
 
@@ -545,15 +546,57 @@ static inline int kprobe_fault_handler(s
 	struct kprobe *cur = kprobe_running();
 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-		return 1;
-
-	if (kcb->kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(cur, regs, kcb);
+	switch(kcb->kprobe_status) {
+	case KPROBE_HIT_SS:
+	case KPROBE_REENTER:
+		/*
+		 * We are here because the instruction being single
+		 * stepped caused a page fault. We reset the current
+		 * kprobe and the eip points back to the probe address
+		 * and allow the page fault handler to continue as a
+		 * normal page fault.
+		 */
+		regs->eip = (unsigned long)cur->addr;
 		regs->eflags |= kcb->kprobe_old_eflags;
-
-		reset_current_kprobe();
+		if (kcb->kprobe_status == KPROBE_REENTER)
+			restore_previous_kprobe(kcb);
+		else
+			reset_current_kprobe();
 		preempt_enable_no_resched();
+		break;
+	case KPROBE_HIT_ACTIVE:
+	case KPROBE_HIT_SSDONE:
+		/*
+		 * We increment the nmissed count for accounting,
+		 * we can also use npre/npostfault count for accouting
+		 * these specific fault cases.
+		 */
+		kprobes_inc_nmissed_count(cur);
+
+		/*
+		 * We come here because instructions in the pre/post
+		 * handler caused the page_fault, this could happen
+		 * if handler tries to access user space by
+		 * copy_from_user(), get_user() etc. Let the
+		 * user-specified handler try to fix it first.
+		 */
+		if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+			return 1;
+
+		/*
+		 * In case the user-specified fault handler returned
+		 * zero, try to fix up.
+		 */
+		if (fixup_exception(regs))
+			return 1;
+
+		/*
+		 * fixup_exception() could not handle it,
+		 * Let do_page_fault() fix it.
+		 */
+		break;
+	default:
+		break;
 	}
 	return 0;
 }

_
-- 
Prasanna S Panchamukhi
Linux Technology Center
India Software Labs, IBM Bangalore
Email: prasanna@in.ibm.com
Ph: 91-80-51776329

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [3/5 PATCH] Kprobes fix for broken fault handling for ppc64
  2006-03-07 13:40 ` [2/5 PATCH] Kprobes fix for broken fault handling for x86_64 Prasanna S Panchamukhi
@ 2006-03-07 13:39   ` Prasanna S Panchamukhi
  2006-03-07 13:40     ` [4/5 PATCH] Kprobes fix for broken fault handling for ia64 Prasanna S Panchamukhi
  0 siblings, 1 reply; 10+ messages in thread
From: Prasanna S Panchamukhi @ 2006-03-07 13:39 UTC (permalink / raw)
  To: systemtap


This patch fixes the broken kprobes fault handling similar
to i386 architecture.

Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>


 arch/powerpc/kernel/kprobes.c |   61 +++++++++++++++++++++++++++++++++++++-----
 1 files changed, 54 insertions(+), 7 deletions(-)

diff -puN arch/powerpc/kernel/kprobes.c~kprobes-powerpc-pagefault-handling arch/powerpc/kernel/kprobes.c
--- linux-2.6.16-rc5-mm2/arch/powerpc/kernel/kprobes.c~kprobes-powerpc-pagefault-handling	2006-03-07 12:34:49.000000000 +0530
+++ linux-2.6.16-rc5-mm2-prasanna/arch/powerpc/kernel/kprobes.c	2006-03-07 12:34:49.000000000 +0530
@@ -30,9 +30,11 @@
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
 #include <linux/preempt.h>
+#include <linux/module.h>
 #include <asm/cacheflush.h>
 #include <asm/kdebug.h>
 #include <asm/sstep.h>
+#include <asm/uaccess.h>
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
@@ -372,17 +374,62 @@ static inline int kprobe_fault_handler(s
 {
 	struct kprobe *cur = kprobe_running();
 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+	const struct exception_table_entry *entry;
 
-	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-		return 1;
-
-	if (kcb->kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(cur, regs);
+	switch(kcb->kprobe_status) {
+	case KPROBE_HIT_SS:
+	case KPROBE_REENTER:
+		/*
+		 * We are here because the instruction being single
+		 * stepped caused a page fault. We reset the current
+		 * kprobe and the nip points back to the probe address
+		 * and allow the page fault handler to continue as a
+		 * normal page fault.
+		 */
+		regs->nip = (unsigned long)cur->addr;
 		regs->msr &= ~MSR_SE;
 		regs->msr |= kcb->kprobe_saved_msr;
-
-		reset_current_kprobe();
+		if (kcb->kprobe_status == KPROBE_REENTER)
+			restore_previous_kprobe(kcb);
+		else
+			reset_current_kprobe();
 		preempt_enable_no_resched();
+		break;
+	case KPROBE_HIT_ACTIVE:
+	case KPROBE_HIT_SSDONE:
+		/*
+		 * We increment the nmissed count for accounting,
+		 * we can also use npre/npostfault count for accouting
+		 * these specific fault cases.
+		 */
+		kprobes_inc_nmissed_count(cur);
+
+		/*
+		 * We come here because instructions in the pre/post
+		 * handler caused the page_fault, this could happen
+		 * if handler tries to access user space by
+		 * copy_from_user(), get_user() etc. Let the
+		 * user-specified handler try to fix it first.
+		 */
+		if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+			return 1;
+
+		/*
+		 * In case the user-specified fault handler returned
+		 * zero, try to fix up.
+		 */
+		if ((entry = search_exception_tables(regs->nip)) != NULL) {
+			regs->nip = entry->fixup;
+			return 1;
+		}
+
+		/*
+		 * fixup_exception() could not handle it,
+		 * Let do_page_fault() fix it.
+		 */
+		break;
+	default:
+		break;
 	}
 	return 0;
 }

_
-- 
Prasanna S Panchamukhi
Linux Technology Center
India Software Labs, IBM Bangalore
Email: prasanna@in.ibm.com
Ph: 91-80-51776329

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [2/5 PATCH] Kprobes fix for broken fault handling for x86_64
  2006-03-07 13:37 [1/5 PATCH] Kprobes fix for broken fault handling for i386 Prasanna S Panchamukhi
@ 2006-03-07 13:40 ` Prasanna S Panchamukhi
  2006-03-07 13:39   ` [3/5 PATCH] Kprobes fix for broken fault handling for ppc64 Prasanna S Panchamukhi
  2006-03-07 21:26 ` [1/5 PATCH] Kprobes fix for broken fault handling for i386 Keshavamurthy Anil S
  1 sibling, 1 reply; 10+ messages in thread
From: Prasanna S Panchamukhi @ 2006-03-07 13:40 UTC (permalink / raw)
  To: systemtap


This patch fixes the broken kprobes fault handling similar
to i386 architecture.

Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>


 arch/x86_64/kernel/kprobes.c |   62 ++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 55 insertions(+), 7 deletions(-)

diff -puN arch/x86_64/kernel/kprobes.c~kprobes-x86_64-pagefault-handling arch/x86_64/kernel/kprobes.c
--- linux-2.6.16-rc5-mm2/arch/x86_64/kernel/kprobes.c~kprobes-x86_64-pagefault-handling	2006-03-07 11:25:02.000000000 +0530
+++ linux-2.6.16-rc5-mm2-prasanna/arch/x86_64/kernel/kprobes.c	2006-03-07 11:25:33.000000000 +0530
@@ -37,10 +37,12 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/preempt.h>
+#include <linux/module.h>
 
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
 #include <asm/kdebug.h>
+#include <asm/uaccess.h>
 
 void jprobe_return_end(void);
 static void __kprobes arch_copy_kprobe(struct kprobe *p);
@@ -578,16 +580,62 @@ int __kprobes kprobe_fault_handler(struc
 {
 	struct kprobe *cur = kprobe_running();
 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+	const struct exception_table_entry *fixup;
 
-	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-		return 1;
-
-	if (kcb->kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(cur, regs, kcb);
+	switch(kcb->kprobe_status) {
+	case KPROBE_HIT_SS:
+	case KPROBE_REENTER:
+		/*
+		 * We are here because the instruction being single
+		 * stepped caused a page fault. We reset the current
+		 * kprobe and the rip points back to the probe address
+		 * and allow the page fault handler to continue as a
+		 * normal page fault.
+		 */
+		regs->rip = (unsigned long)cur->addr;
 		regs->eflags |= kcb->kprobe_old_rflags;
-
-		reset_current_kprobe();
+		if (kcb->kprobe_status == KPROBE_REENTER)
+			restore_previous_kprobe(kcb);
+		else
+			reset_current_kprobe();
 		preempt_enable_no_resched();
+		break;
+	case KPROBE_HIT_ACTIVE:
+	case KPROBE_HIT_SSDONE:
+		/*
+		 * We increment the nmissed count for accounting,
+		 * we can also use npre/npostfault count for accouting
+		 * these specific fault cases.
+		 */
+		kprobes_inc_nmissed_count(cur);
+
+		/*
+		 * We come here because instructions in the pre/post
+		 * handler caused the page_fault, this could happen
+		 * if handler tries to access user space by
+		 * copy_from_user(), get_user() etc. Let the
+		 * user-specified handler try to fix it first.
+		 */
+		if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+			return 1;
+
+		/*
+		 * In case the user-specified fault handler returned
+		 * zero, try to fix up.
+		 */
+		fixup = search_exception_tables(regs->rip);
+		if (fixup) {
+			regs->rip = fixup->fixup;
+			return 1;
+		}
+
+		/*
+		 * fixup() could not handle it,
+		 * Let do_page_fault() fix it.
+		 */
+		break;
+	default:
+		break;
 	}
 	return 0;
 }

_
-- 
Prasanna S Panchamukhi
Linux Technology Center
India Software Labs, IBM Bangalore
Email: prasanna@in.ibm.com
Ph: 91-80-51776329

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [4/5 PATCH] Kprobes fix for broken fault handling for ia64
  2006-03-07 13:39   ` [3/5 PATCH] Kprobes fix for broken fault handling for ppc64 Prasanna S Panchamukhi
@ 2006-03-07 13:40     ` Prasanna S Panchamukhi
  2006-03-07 13:41       ` [5/5 PATCH] Kprobes fix for broken fault handling for sparc64 Prasanna S Panchamukhi
  2006-03-08  8:13       ` [4/5 PATCH] Kprobes fix for broken fault handling for ia64 bibo,mao
  0 siblings, 2 replies; 10+ messages in thread
From: Prasanna S Panchamukhi @ 2006-03-07 13:40 UTC (permalink / raw)
  To: systemtap


This patch fixes the broken kprobes fault handling similar
to i386 architecture.

Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>
Acked-by: Anil S Keshavamurthy<anil.s.keshavamurthy@intel.com>


 arch/ia64/kernel/kprobes.c |   55 ++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 50 insertions(+), 5 deletions(-)

diff -puN arch/ia64/kernel/kprobes.c~kprobes-ia64-pagefault-handling arch/ia64/kernel/kprobes.c
--- linux-2.6.16-rc5-mm2/arch/ia64/kernel/kprobes.c~kprobes-ia64-pagefault-handling	2006-03-07 11:18:46.000000000 +0530
+++ linux-2.6.16-rc5-mm2-prasanna/arch/ia64/kernel/kprobes.c	2006-03-07 11:21:12.000000000 +0530
@@ -34,6 +34,7 @@
 #include <asm/pgtable.h>
 #include <asm/kdebug.h>
 #include <asm/sections.h>
+#include <asm/uaccess.h>
 
 extern void jprobe_inst_return(void);
 
@@ -722,13 +723,57 @@ static int __kprobes kprobes_fault_handl
 	struct kprobe *cur = kprobe_running();
 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-		return 1;
 
-	if (kcb->kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(cur, regs);
-		reset_current_kprobe();
+	switch(kcb->kprobe_status) {
+	case KPROBE_HIT_SS:
+	case KPROBE_REENTER:
+		/*
+		 * We are here because the instruction being single
+		 * stepped caused a page fault. We reset the current
+		 * kprobe and the instruction pointer points back to
+		 * the probe address and allow the page fault handler
+		 * to continue as a normal page fault.
+		 */
+		regs->cr_iip = ((unsigned long)cur->addr) & ~0xFULL;
+		ia64_psr(regs) = ((unsigned long)cur->addr) & 0xf;
+		if (kcb->kprobe_status == KPROBE_REENTER)
+			restore_previous_kprobe(kcb);
+		else
+			reset_current_kprobe();
 		preempt_enable_no_resched();
+		break;
+	case KPROBE_HIT_ACTIVE:
+	case KPROBE_HIT_SSDONE:
+		/*
+		 * We increment the nmissed count for accounting,
+		 * we can also use npre/npostfault count for accouting
+		 * these specific fault cases.
+		 */
+		kprobes_inc_nmissed_count(cur);
+
+		/*
+		 * We come here because instructions in the pre/post
+		 * handler caused the page_fault, this could happen
+		 * if handler tries to access user space by
+		 * copy_from_user(), get_user() etc. Let the
+		 * user-specified handler try to fix it first.
+		 */
+		if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+			return 1;
+
+		/*
+		 * In case the user-specified fault handler returned
+		 * zero, try to fix up.
+		 */
+		if (ia64_done_with_exception(regs))
+			return 1;
+		/*
+		 * ia64_done_with_exception() could not handle it,
+		 * Let ia64_do_page_fault() fix it.
+		 */
+		break;
+	default:
+		break;
 	}
 
 	return 0;

_
-- 
Prasanna S Panchamukhi
Linux Technology Center
India Software Labs, IBM Bangalore
Email: prasanna@in.ibm.com
Ph: 91-80-51776329

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [5/5 PATCH] Kprobes fix for broken fault handling for sparc64
  2006-03-07 13:40     ` [4/5 PATCH] Kprobes fix for broken fault handling for ia64 Prasanna S Panchamukhi
@ 2006-03-07 13:41       ` Prasanna S Panchamukhi
  2006-03-08  8:13       ` [4/5 PATCH] Kprobes fix for broken fault handling for ia64 bibo,mao
  1 sibling, 0 replies; 10+ messages in thread
From: Prasanna S Panchamukhi @ 2006-03-07 13:41 UTC (permalink / raw)
  To: systemtap


This patch fixes the broken kprobes fault handling similar
to i386 architecture.

Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>


 arch/sparc64/kernel/kprobes.c |   66 ++++++++++++++++++++++++++++++++++++++----
 1 files changed, 60 insertions(+), 6 deletions(-)

diff -puN arch/sparc64/kernel/kprobes.c~kprobes-sparc64-pagefault-handling arch/sparc64/kernel/kprobes.c
--- linux-2.6.16-rc5-mm2/arch/sparc64/kernel/kprobes.c~kprobes-sparc64-pagefault-handling	2006-03-07 17:36:16.000000000 +0530
+++ linux-2.6.16-rc5-mm2-prasanna/arch/sparc64/kernel/kprobes.c	2006-03-07 17:38:01.000000000 +0530
@@ -6,9 +6,11 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
+#include <linux/module.h>
 #include <asm/kdebug.h>
 #include <asm/signal.h>
 #include <asm/cacheflush.h>
+#include <asm/uaccess.h>
 
 /* We do not have hardware single-stepping on sparc64.
  * So we implement software single-stepping with breakpoint
@@ -302,16 +304,68 @@ static inline int kprobe_fault_handler(s
 {
 	struct kprobe *cur = kprobe_running();
 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+	const struct exception_table_entry *entry;
 
-	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-		return 1;
+	switch(kcb->kprobe_status) {
+	case KPROBE_HIT_SS:
+	case KPROBE_REENTER:
+		/*
+		 * We are here because the instruction being single
+		 * stepped caused a page fault. We reset the current
+		 * kprobe and the tpc points back to the probe address
+		 * and allow the page fault handler to continue as a
+		 * normal page fault.
+		 */
+		regs->tpc = (unsigned long) curr->addr;
+		regs->tnpc = kcb->kprobe_orig_tnpc;
+		regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
+				kcb->kprobe_orig_tstate_pil);
+		if (kcb->kprobe_status == KPROBE_REENTER)
+			restore_previous_kprobe(kcb);
+		else
+			reset_current_kprobe();
+		preempt_enable_no_resched();
+		break;
+	case KPROBE_HIT_ACTIVE:
+	case KPROBE_HIT_SSDONE:
+		/*
+		 * We increment the nmissed count for accounting,
+		 * we can also use npre/npostfault count for accouting
+		 * these specific fault cases.
+		 */
+		kprobes_inc_nmissed_count(cur);
 
-	if (kcb->kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(cur, regs, kcb);
+		/*
+		 * We come here because instructions in the pre/post
+		 * handler caused the page_fault, this could happen
+		 * if handler tries to access user space by
+		 * copy_from_user(), get_user() etc. Let the
+		 * user-specified handler try to fix it first.
+		 */
+		if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+			return 1;
 
-		reset_current_kprobe();
-		preempt_enable_no_resched();
+		/*
+		 * In case the user-specified fault handler returned
+		 * zero, try to fix up.
+		 */
+
+		entry = search_exception_tables(regs->tpc);
+		if (entry) {
+			regs->tpc = entry->fixup;
+			regs->tnpc = regs->tpc + 4;
+			return 1;
+		}
+
+		/*
+		 * fixup_exception() could not handle it,
+		 * Let do_page_fault() fix it.
+		 */
+		break;
+	default:
+		break;
 	}
+
 	return 0;
 }
 

_
-- 
Prasanna S Panchamukhi
Linux Technology Center
India Software Labs, IBM Bangalore
Email: prasanna@in.ibm.com
Ph: 91-80-51776329

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [1/5 PATCH] Kprobes fix for broken fault handling for i386
  2006-03-07 13:37 [1/5 PATCH] Kprobes fix for broken fault handling for i386 Prasanna S Panchamukhi
  2006-03-07 13:40 ` [2/5 PATCH] Kprobes fix for broken fault handling for x86_64 Prasanna S Panchamukhi
@ 2006-03-07 21:26 ` Keshavamurthy Anil S
  2006-03-07 22:24   ` Hien Nguyen
  1 sibling, 1 reply; 10+ messages in thread
From: Keshavamurthy Anil S @ 2006-03-07 21:26 UTC (permalink / raw)
  To: Prasanna S Panchamukhi; +Cc: systemtap

On Tue, Mar 07, 2006 at 05:38:32AM -0800, Prasanna S Panchamukhi wrote:
> 
>    Hi,
> 
>    Below is the set of patches to fix broken fault handling
>    for i386, x86_64, ppc64, ia64 and sparc64 architectures
>    against 2.6.16-rc5-mm2.
> 
>    These patches are tested for i386 and x86_64 architectures.
>    Could you please test it for ia64 and ppc64.

Prasanna,
	Can you share your test module code here,
so that the same can be used(with minor tweak, if requred)
for testing other architecture. Also in you testing, did 
you cover fault handling during pre/post/singlestep
cases?

Thanks,
Anil

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [1/5 PATCH] Kprobes fix for broken fault handling for i386
  2006-03-07 21:26 ` [1/5 PATCH] Kprobes fix for broken fault handling for i386 Keshavamurthy Anil S
@ 2006-03-07 22:24   ` Hien Nguyen
  2006-03-08  5:13     ` Prasanna S Panchamukhi
  0 siblings, 1 reply; 10+ messages in thread
From: Hien Nguyen @ 2006-03-07 22:24 UTC (permalink / raw)
  To: Keshavamurthy Anil S; +Cc: Prasanna S Panchamukhi, systemtap

Keshavamurthy Anil S wrote:

>On Tue, Mar 07, 2006 at 05:38:32AM -0800, Prasanna S Panchamukhi wrote:
>  
>
>>   Hi,
>>
>>   Below is the set of patches to fix broken fault handling
>>   for i386, x86_64, ppc64, ia64 and sparc64 architectures
>>   against 2.6.16-rc5-mm2.
>>
>>   These patches are tested for i386 and x86_64 architectures.
>>   Could you please test it for ia64 and ppc64.
>>    
>>
>
>Prasanna,
>	Can you share your test module code here,
>so that the same can be used(with minor tweak, if requred)
>for testing other architecture. Also in you testing, did 
>you cover fault handling during pre/post/singlestep
>cases?
>
>Thanks,
>Anil
>
>  
>
I tested Prasanna's fault handling patch with the current syscalls 
tapset (latest from CVS) which does lots of user copies. Without the 
patch the system crashes right away, but with this patch I finally can 
test the system calls tapset.

I use Martin's sys.stp script below

probe syscall.*, syscall.*.return {
        if (pid() == target()) {
                if (returnp)
                        printf("%d\n", returnval())
                else
                        printf("%s (%s) = ", name, argstr)
        }
}

Invoke the script as follow
stap -c bash sys.stp
to exit the script, just type exit.

Hien.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [1/5 PATCH] Kprobes fix for broken fault handling for i386
  2006-03-07 22:24   ` Hien Nguyen
@ 2006-03-08  5:13     ` Prasanna S Panchamukhi
  0 siblings, 0 replies; 10+ messages in thread
From: Prasanna S Panchamukhi @ 2006-03-08  5:13 UTC (permalink / raw)
  To: Keshavamurthy Anil S; +Cc: systemtap

Anil,

You can use the test script mentioned by Hien below.
Also to test the fault handling, you need to just
call copy_from_user(), that will generate a page fault.
In the post/pre handler allocate a buffer and 
copy some data from the user address space.

copy_from_user(&buf, (unsigned long *)0xbff2d020, 10);

where the from address should be a valid user space address.


Thanks
Prasanna

On Tue, Mar 07, 2006 at 02:23:58PM -0800, Hien Nguyen wrote:
> Keshavamurthy Anil S wrote:
> 
> >On Tue, Mar 07, 2006 at 05:38:32AM -0800, Prasanna S Panchamukhi wrote:
> > 
> >
> >>  Hi,
> >>
> >>  Below is the set of patches to fix broken fault handling
> >>  for i386, x86_64, ppc64, ia64 and sparc64 architectures
> >>  against 2.6.16-rc5-mm2.
> >>
> >>  These patches are tested for i386 and x86_64 architectures.
> >>  Could you please test it for ia64 and ppc64.
> >>   
> >>
> >
> >Prasanna,
> >	Can you share your test module code here,
> >so that the same can be used(with minor tweak, if requred)
> >for testing other architecture. Also in you testing, did 
> >you cover fault handling during pre/post/singlestep
> >cases?
> >
> >Thanks,
> >Anil
> >
> > 
> >
> I tested Prasanna's fault handling patch with the current syscalls 
> tapset (latest from CVS) which does lots of user copies. Without the 
> patch the system crashes right away, but with this patch I finally can 
> test the system calls tapset.
> 
> I use Martin's sys.stp script below
> 
> probe syscall.*, syscall.*.return {
>        if (pid() == target()) {
>                if (returnp)
>                        printf("%d\n", returnval())
>                else
>                        printf("%s (%s) = ", name, argstr)
>        }
> }
> 
> Invoke the script as follow
> stap -c bash sys.stp
> to exit the script, just type exit.
> 
> Hien.
> 
> 
> 

-- 
Prasanna S Panchamukhi
Linux Technology Center
India Software Labs, IBM Bangalore
Email: prasanna@in.ibm.com
Ph: 91-80-51776329

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [4/5 PATCH] Kprobes fix for broken fault handling for ia64
  2006-03-07 13:40     ` [4/5 PATCH] Kprobes fix for broken fault handling for ia64 Prasanna S Panchamukhi
  2006-03-07 13:41       ` [5/5 PATCH] Kprobes fix for broken fault handling for sparc64 Prasanna S Panchamukhi
@ 2006-03-08  8:13       ` bibo,mao
  2006-03-08 11:17         ` Prasanna S Panchamukhi
  1 sibling, 1 reply; 10+ messages in thread
From: bibo,mao @ 2006-03-08  8:13 UTC (permalink / raw)
  To: prasanna; +Cc: systemtap

[-- Attachment #1: Type: text/plain, Size: 2338 bytes --]

Prasanna S Panchamukhi wrote:
> This patch fixes the broken kprobes fault handling similar
> to i386 architecture.
> 
> Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>
> Acked-by: Anil S Keshavamurthy<anil.s.keshavamurthy@intel.com>
> 
> 
>  arch/ia64/kernel/kprobes.c |   55 ++++++++++++++++++++++++++++++++++++++++-----
>  1 files changed, 50 insertions(+), 5 deletions(-)
> 
> diff -puN arch/ia64/kernel/kprobes.c~kprobes-ia64-pagefault-handling arch/ia64/kernel/kprobes.c
> --- linux-2.6.16-rc5-mm2/arch/ia64/kernel/kprobes.c~kprobes-ia64-pagefault-handling	2006-03-07 11:18:46.000000000 +0530
> +++ linux-2.6.16-rc5-mm2-prasanna/arch/ia64/kernel/kprobes.c	2006-03-07 11:21:12.000000000 +0530
> @@ -34,6 +34,7 @@
>  #include <asm/pgtable.h>
>  #include <asm/kdebug.h>
>  #include <asm/sections.h>
> +#include <asm/uaccess.h>
>  
>  extern void jprobe_inst_return(void);
>  
> @@ -722,13 +723,57 @@ static int __kprobes kprobes_fault_handl
>  	struct kprobe *cur = kprobe_running();
>  	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
>  
> -	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
> -		return 1;
>  
> -	if (kcb->kprobe_status & KPROBE_HIT_SS) {
> -		resume_execution(cur, regs);
> -		reset_current_kprobe();
> +	switch(kcb->kprobe_status) {
> +	case KPROBE_HIT_SS:
> +	case KPROBE_REENTER:
> +		/*
> +		 * We are here because the instruction being single
> +		 * stepped caused a page fault. We reset the current
> +		 * kprobe and the instruction pointer points back to
> +		 * the probe address and allow the page fault handler
> +		 * to continue as a normal page fault.
> +		 */
> +		regs->cr_iip = ((unsigned long)cur->addr) & ~0xFULL;
> +		ia64_psr(regs) = ((unsigned long)cur->addr) & 0xf;
It should be:
		regs->cr_iip = ((unsigned long)cur->addr) & ~0xFULL;
                 ia64_psr(regs)->ri  = ((unsigned long)cur->addr) & 0xf;
And I test this patch in IA64 platform, it passed. But find that 
sometime user space copy is incomplete. If page fault happens in kprobe 
prehandler/posthandler, if will first call fix_exception() and return, 
Normally in page fault process procedure system will load page into 
memory, and the system will call fix_exceptioin if failed to load page 
into memory.

The attachment is my test case in IA64, it is easy to port to other 
platform.

Bibo,mao

[-- Attachment #2: fault.c --]
[-- Type: text/x-csrc, Size: 3187 bytes --]

/*kprobe_example.c*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
#include <linux/sched.h>
#include <asm/uaccess.h>

#define PATH_MAX        4096	/* # chars in a path name including nul */

/*For each probe you need to allocate a kprobe structure*/
static struct kprobe kp;
static char *filename, *filename1;
static int fault_happened;
static unsigned long r32;

struct ia64_stap_get_arbsp_param {
        unsigned long ip;
        unsigned long *address;
};

static void ia64_stap_get_arbsp(struct unw_frame_info *info, void *arg)
{
        unsigned long ip;
        struct ia64_stap_get_arbsp_param *lp = arg;

        do {
                unw_get_ip(info, &ip);
                if (ip == 0)
                        break;
                if (ip == lp->ip) {
                        unw_get_bsp(info, (unsigned long*)&lp->address);
                        return;
                }
        } while (unw_unwind(info) >= 0);
        lp->address = 0;
}

static long ia64_fetch_register(int regno, struct pt_regs *pt_regs)
{
        struct ia64_stap_get_arbsp_param pa;

        if (regno < 32 || regno > 127)
                return 0;

        pa.ip = pt_regs->cr_iip;
        unw_init_running(ia64_stap_get_arbsp, &pa);
        if (pa.address == 0)
                return 0;

        return *ia64_rse_skip_regs(pa.address, regno-32);
}

/*kprobe pre_handler: called just before the probed instruction is executed*/
int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
	fault_happened = 0;
	r32 = ia64_fetch_register(32, regs);

	/* here r32 is pointer to filename parameter pointer */
	copy_from_user(filename, (void*)r32, PATH_MAX);
	printk("filename %s \n", filename);
        return 0;
}

/*kprobe post_handler: called after the probed instruction is executed*/
void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
{
	if (fault_happened == 1){
		copy_from_user(filename1, (void*)r32, PATH_MAX);
		printk("filename: %s \n", filename);
		printk("filename1: %s \n", filename1);
	}

	fault_happened = 0; 
}

/* fault_handler: this is called if an exception is generated for any
 * instruction within the pre- or post-handler, or when Kprobes
 * single-steps the probed instruction.
 */
int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
{
        fault_happened = 1 ;

        return 0;
}

int init_module(void)
{
        int ret;
	
	filename = kzalloc(PATH_MAX, GFP_KERNEL);
	filename1 = kzalloc(PATH_MAX, GFP_KERNEL);
        kp.pre_handler = handler_pre;
        kp.post_handler = handler_post;
        kp.fault_handler = handler_fault;
        kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("sys_open");
        /* register the kprobe now */
        if (!kp.addr) {
                return -1;
        }
        if ((ret = register_kprobe(&kp) < 0)) {
                printk("register_kprobe failed, returned %d\n", ret);
                return -1;
        }
        printk("kprobe registered\n");
        return 0;
}

void cleanup_module(void)
{
	unregister_kprobe(&kp);
	kfree(filename);
	kfree(filename1);
	printk("kprobe unregistered\n");
}

MODULE_LICENSE("GPL");


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [4/5 PATCH] Kprobes fix for broken fault handling for ia64
  2006-03-08  8:13       ` [4/5 PATCH] Kprobes fix for broken fault handling for ia64 bibo,mao
@ 2006-03-08 11:17         ` Prasanna S Panchamukhi
  0 siblings, 0 replies; 10+ messages in thread
From: Prasanna S Panchamukhi @ 2006-03-08 11:17 UTC (permalink / raw)
  To: bibo,mao; +Cc: systemtap


On Wed, Mar 08, 2006 at 04:05:27PM +0800, bibo,mao wrote:
> Prasanna S Panchamukhi wrote:
> >This patch fixes the broken kprobes fault handling similar
> >to i386 architecture.
> >
> >Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>
> >Acked-by: Anil S Keshavamurthy<anil.s.keshavamurthy@intel.com>
> >
> >
> > arch/ia64/kernel/kprobes.c |   55 
> > ++++++++++++++++++++++++++++++++++++++++-----
> > 1 files changed, 50 insertions(+), 5 deletions(-)
> >
> >diff -puN arch/ia64/kernel/kprobes.c~kprobes-ia64-pagefault-handling 
> >arch/ia64/kernel/kprobes.c
> >--- 
> >linux-2.6.16-rc5-mm2/arch/ia64/kernel/kprobes.c~kprobes-ia64-pagefault-handling	2006-03-07 11:18:46.000000000 +0530
> >+++ linux-2.6.16-rc5-mm2-prasanna/arch/ia64/kernel/kprobes.c	2006-03-07 
> >11:21:12.000000000 +0530
> >@@ -34,6 +34,7 @@
> > #include <asm/pgtable.h>
> > #include <asm/kdebug.h>
> > #include <asm/sections.h>
> >+#include <asm/uaccess.h>
> > 
> > extern void jprobe_inst_return(void);
> > 
> >@@ -722,13 +723,57 @@ static int __kprobes kprobes_fault_handl
> > 	struct kprobe *cur = kprobe_running();
> > 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> > 
> >-	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
> >-		return 1;
> > 
> >-	if (kcb->kprobe_status & KPROBE_HIT_SS) {
> >-		resume_execution(cur, regs);
> >-		reset_current_kprobe();
> >+	switch(kcb->kprobe_status) {
> >+	case KPROBE_HIT_SS:
> >+	case KPROBE_REENTER:
> >+		/*
> >+		 * We are here because the instruction being single
> >+		 * stepped caused a page fault. We reset the current
> >+		 * kprobe and the instruction pointer points back to
> >+		 * the probe address and allow the page fault handler
> >+		 * to continue as a normal page fault.
> >+		 */
> >+		regs->cr_iip = ((unsigned long)cur->addr) & ~0xFULL;
> >+		ia64_psr(regs) = ((unsigned long)cur->addr) & 0xf;
> It should be:
> 		regs->cr_iip = ((unsigned long)cur->addr) & ~0xFULL;
>                 ia64_psr(regs)->ri  = ((unsigned long)cur->addr) & 0xf;
> And I test this patch in IA64 platform, it passed. But find that 
> sometime user space copy is incomplete. If page fault happens in kprobe 
> prehandler/posthandler, if will first call fix_exception() and return, 
> Normally in page fault process procedure system will load page into 
> memory, and the system will call fix_exceptioin if failed to load page 
> into memory.

Bibo,

Thanks for testing this on ia64, I will make the changes before sending
it upstream.

Since the system page fault handler might sleep while 
loading the page into the memory and we cannot afford to
sleep at this point, we skip loading the page into the memory
and just call fixup_exception.

Thanks
Prasanna

> 
> The attachment is my test case in IA64, it is easy to port to other 
> platform.
> 
> Bibo,mao



-- 
Thanks & Regards
Prasanna S Panchamukhi
Linux Technology Center
India Software Labs, IBM Bangalore
Email: prasanna@in.ibm.com
Ph: 91-80-51776329

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2006-03-08 11:17 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-07 13:37 [1/5 PATCH] Kprobes fix for broken fault handling for i386 Prasanna S Panchamukhi
2006-03-07 13:40 ` [2/5 PATCH] Kprobes fix for broken fault handling for x86_64 Prasanna S Panchamukhi
2006-03-07 13:39   ` [3/5 PATCH] Kprobes fix for broken fault handling for ppc64 Prasanna S Panchamukhi
2006-03-07 13:40     ` [4/5 PATCH] Kprobes fix for broken fault handling for ia64 Prasanna S Panchamukhi
2006-03-07 13:41       ` [5/5 PATCH] Kprobes fix for broken fault handling for sparc64 Prasanna S Panchamukhi
2006-03-08  8:13       ` [4/5 PATCH] Kprobes fix for broken fault handling for ia64 bibo,mao
2006-03-08 11:17         ` Prasanna S Panchamukhi
2006-03-07 21:26 ` [1/5 PATCH] Kprobes fix for broken fault handling for i386 Keshavamurthy Anil S
2006-03-07 22:24   ` Hien Nguyen
2006-03-08  5:13     ` Prasanna S Panchamukhi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).