public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] Kprobes: Temporary disarming of reentrant probe
@ 2005-05-24 10:15 Prasanna S Panchamukhi
  2005-05-24 10:17 ` [PATCH 2/5] Kprobes: Temporary disarming of reentrant probe for i386 Prasanna S Panchamukhi
  2005-05-24 18:15 ` [PATCH 1/5] Kprobes: Temporary disarming of reentrant probe Andi Kleen
  0 siblings, 2 replies; 9+ messages in thread
From: Prasanna S Panchamukhi @ 2005-05-24 10:15 UTC (permalink / raw)
  To: akpm, ak, davem; +Cc: linux-kernel, systemtap

Hi,

Please provide your feedback on this patchset.

Thanks
Prasanna

In situations where a kprobes handler calls a routine which has a probe on it,
then kprobes_handler() disarms the new probe forever. This patch removes the
above limitation by temporarily disarming the new probe. When the another probe
hits while handling the old probe, the kprobes_handler() saves previous kprobes
state and handles the new probe without calling the new kprobes registered
handlers. kprobe_post_handler() restores back the previous kprobes state and the
normal execution continues.
However on x86_64 architecture, re-rentrancy is provided only through
pre_handler(). If a routine having probe is referenced through post_handler(),
then the probes on that routine are disarmed forever, since the exception stack
is gets changed after the processor single steps the instruction of the new
probe.

This patch includes generic changes to support temporary disarming on
reentrancy of probes.

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


---

 linux-2.6.12-rc4-mm2-prasanna/include/linux/kprobes.h |    9 +++++++++
 linux-2.6.12-rc4-mm2-prasanna/kernel/kprobes.c        |    1 +
 2 files changed, 10 insertions(+)

diff -puN include/linux/kprobes.h~kprobes-temporary-disarming-on-reentrancy-generic include/linux/kprobes.h
--- linux-2.6.12-rc4-mm2/include/linux/kprobes.h~kprobes-temporary-disarming-on-reentrancy-generic	2005-05-24 15:28:08.000000000 +0530
+++ linux-2.6.12-rc4-mm2-prasanna/include/linux/kprobes.h	2005-05-24 15:28:08.000000000 +0530
@@ -36,6 +36,12 @@
 
 #include <asm/kprobes.h>
 
+/* kprobe_status settings */
+#define KPROBE_HIT_ACTIVE	0x00000001
+#define KPROBE_HIT_SS		0x00000002
+#define KPROBE_REENTER		0x00000004
+#define KPROBE_HIT_SSDONE	0x00000008
+
 struct kprobe;
 struct pt_regs;
 struct kretprobe;
@@ -55,6 +61,9 @@ struct kprobe {
 	/* list of kprobes for multi-handler support */
 	struct list_head list;
 
+	/*count the number of times this probe was temporarily disarmed */
+	unsigned long nmissed;
+
 	/* location of the probe point */
 	kprobe_opcode_t *addr;
 
diff -puN kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-generic kernel/kprobes.c
--- linux-2.6.12-rc4-mm2/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-generic	2005-05-24 15:28:08.000000000 +0530
+++ linux-2.6.12-rc4-mm2-prasanna/kernel/kprobes.c	2005-05-24 15:28:08.000000000 +0530
@@ -334,6 +334,7 @@ int register_kprobe(struct kprobe *p)
 	}
 	spin_lock_irqsave(&kprobe_lock, flags);
 	old_p = get_kprobe(p->addr);
+	p->nmissed = 0;
 	if (old_p) {
 		ret = register_aggr_kprobe(old_p, p);
 		goto out;

_
-- 

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

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

* Re: [PATCH 2/5] Kprobes: Temporary disarming of reentrant probe for i386
  2005-05-24 10:15 [PATCH 1/5] Kprobes: Temporary disarming of reentrant probe Prasanna S Panchamukhi
@ 2005-05-24 10:17 ` Prasanna S Panchamukhi
  2005-05-24 10:18   ` [PATCH 3/5] Kprobes: Temporary disarming of reentrant probe for x86_64 Prasanna S Panchamukhi
  2005-05-25 15:19   ` [PATCH 2/5] Kprobes: Temporary disarming of reentrant probe for i386 Andi Kleen
  2005-05-24 18:15 ` [PATCH 1/5] Kprobes: Temporary disarming of reentrant probe Andi Kleen
  1 sibling, 2 replies; 9+ messages in thread
From: Prasanna S Panchamukhi @ 2005-05-24 10:17 UTC (permalink / raw)
  To: akpm, ak, davem; +Cc: linux-kernel, systemtap


This patch includes i386 architecture specific changes to support temporary
disarming on reentrancy of probes.

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

---


---

 linux-2.6.12-rc4-mm2-prasanna/arch/i386/kernel/kprobes.c |   62 +++++++++++----
 1 files changed, 49 insertions(+), 13 deletions(-)

diff -puN arch/i386/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-i386 arch/i386/kernel/kprobes.c
--- linux-2.6.12-rc4-mm2/arch/i386/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-i386	2005-05-24 15:28:48.000000000 +0530
+++ linux-2.6.12-rc4-mm2-prasanna/arch/i386/kernel/kprobes.c	2005-05-24 15:28:48.000000000 +0530
@@ -37,12 +37,10 @@
 #include <asm/kdebug.h>
 #include <asm/desc.h>
 
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE	0x00000001
-#define KPROBE_HIT_SS		0x00000002
-
 static struct kprobe *current_kprobe;
 static unsigned long kprobe_status, kprobe_old_eflags, kprobe_saved_eflags;
+static struct kprobe *kprobe_prev;
+static unsigned long kprobe_status_prev, kprobe_old_eflags_prev, kprobe_saved_eflags_prev;
 static struct pt_regs jprobe_saved_regs;
 static long *jprobe_saved_esp;
 /* copy of the kernel stack at the probe fire time */
@@ -93,6 +91,31 @@ void arch_remove_kprobe(struct kprobe *p
 {
 }
 
+static inline void save_previous_kprobe(void)
+{
+	kprobe_prev = current_kprobe;
+	kprobe_status_prev = kprobe_status;
+	kprobe_old_eflags_prev = kprobe_old_eflags;
+	kprobe_saved_eflags_prev = kprobe_saved_eflags;
+}
+
+static inline void restore_previous_kprobe(void)
+{
+	current_kprobe = kprobe_prev;
+	kprobe_status = kprobe_status_prev;
+	kprobe_old_eflags = kprobe_old_eflags_prev;
+	kprobe_saved_eflags = kprobe_saved_eflags_prev;
+}
+
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+{
+	current_kprobe = p;
+	kprobe_saved_eflags = kprobe_old_eflags
+		= (regs->eflags & (TF_MASK | IF_MASK));
+	if (is_IF_modifier(p->opcode))
+		kprobe_saved_eflags &= ~IF_MASK;
+}
+
 static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
 	regs->eflags |= TF_MASK;
@@ -184,9 +207,18 @@ static int kprobe_handler(struct pt_regs
 				unlock_kprobes();
 				goto no_kprobe;
 			}
-			arch_disarm_kprobe(p);
-			regs->eip = (unsigned long)p->addr;
-			ret = 1;
+			/* 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();
+			set_current_kprobe(p, regs);
+			p->nmissed++;
+			prepare_singlestep(p, regs);
+			kprobe_status = KPROBE_REENTER;
+			return 1;
 		} else {
 			p = current_kprobe;
 			if (p->break_handler && p->break_handler(p, regs)) {
@@ -221,11 +253,7 @@ static int kprobe_handler(struct pt_regs
 	}
 
 	kprobe_status = KPROBE_HIT_ACTIVE;
-	current_kprobe = p;
-	kprobe_saved_eflags = kprobe_old_eflags
-	    = (regs->eflags & (TF_MASK | IF_MASK));
-	if (is_IF_modifier(p->opcode))
-		kprobe_saved_eflags &= ~IF_MASK;
+	set_current_kprobe(p, regs);
 
 	if (p->pre_handler && p->pre_handler(p, regs))
 		/* handler has already set things up, so skip ss setup */
@@ -370,14 +398,22 @@ static inline int post_kprobe_handler(st
 	if (!kprobe_running())
 		return 0;
 
-	if (current_kprobe->post_handler)
+	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
+		kprobe_status = KPROBE_HIT_SSDONE;
 		current_kprobe->post_handler(current_kprobe, regs, 0);
+	}
 
 	if (current_kprobe->post_handler != trampoline_post_handler)
 		resume_execution(current_kprobe, regs);
 	regs->eflags |= kprobe_saved_eflags;
 
+	/*Restore back the original saved kprobes variables and continue. */
+	if (kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe();
+		goto out;
+	}
 	unlock_kprobes();
+out:
 	preempt_enable_no_resched();
 
 	/*

_
-- 
Have a Nice Day!

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

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

* Re: [PATCH 3/5] Kprobes: Temporary disarming of reentrant probe for x86_64
  2005-05-24 10:17 ` [PATCH 2/5] Kprobes: Temporary disarming of reentrant probe for i386 Prasanna S Panchamukhi
@ 2005-05-24 10:18   ` Prasanna S Panchamukhi
  2005-05-24 10:19     ` [PATCH 4/5] Kprobes: Temporary disarming of reentrant probe for ppc64 Prasanna S Panchamukhi
  2005-05-24 18:13     ` [PATCH 3/5] Kprobes: Temporary disarming of reentrant probe for x86_64 Andi Kleen
  2005-05-25 15:19   ` [PATCH 2/5] Kprobes: Temporary disarming of reentrant probe for i386 Andi Kleen
  1 sibling, 2 replies; 9+ messages in thread
From: Prasanna S Panchamukhi @ 2005-05-24 10:18 UTC (permalink / raw)
  To: akpm, ak, davem; +Cc: linux-kernel, systemtap


This patch includes x86_64 architecture specific changes to support temporary
disarming on reentrancy of probes.

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

---


---

 linux-2.6.12-rc4-mm2-prasanna/arch/x86_64/kernel/kprobes.c |   73 ++++++++++---
 1 files changed, 60 insertions(+), 13 deletions(-)

diff -puN arch/x86_64/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-x86_64 arch/x86_64/kernel/kprobes.c
--- linux-2.6.12-rc4-mm2/arch/x86_64/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-x86_64	2005-05-24 15:29:27.000000000 +0530
+++ linux-2.6.12-rc4-mm2-prasanna/arch/x86_64/kernel/kprobes.c	2005-05-24 15:29:27.000000000 +0530
@@ -43,12 +43,10 @@
 
 static DECLARE_MUTEX(kprobe_mutex);
 
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE	0x00000001
-#define KPROBE_HIT_SS		0x00000002
-
 static struct kprobe *current_kprobe;
 static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags;
+static struct kprobe *kprobe_prev;
+static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev;
 static struct pt_regs jprobe_saved_regs;
 static long *jprobe_saved_rsp;
 static kprobe_opcode_t *get_insn_slot(void);
@@ -238,6 +236,31 @@ void arch_remove_kprobe(struct kprobe *p
 	down(&kprobe_mutex);
 }
 
+static inline void save_previous_kprobe(void)
+{
+	kprobe_prev = current_kprobe;
+	kprobe_status_prev = kprobe_status;
+	kprobe_old_rflags_prev = kprobe_old_rflags;
+	kprobe_saved_rflags_prev = kprobe_saved_rflags;
+}
+
+static inline void restore_previous_kprobe(void)
+{
+	current_kprobe = kprobe_prev;
+	kprobe_status = kprobe_status_prev;
+	kprobe_old_rflags = kprobe_old_rflags_prev;
+	kprobe_saved_rflags = kprobe_saved_rflags_prev;
+}
+
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+{
+	current_kprobe = p;
+	kprobe_saved_rflags = kprobe_old_rflags
+		= (regs->eflags & (TF_MASK | IF_MASK));
+	if (is_IF_modifier(p->ainsn.insn))
+		kprobe_saved_rflags &= ~IF_MASK;
+}
+
 static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
 	regs->eflags |= TF_MASK;
@@ -273,10 +296,30 @@ int kprobe_handler(struct pt_regs *regs)
 				regs->eflags |= kprobe_saved_rflags;
 				unlock_kprobes();
 				goto no_kprobe;
+			} else if (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->rip = (unsigned long)p->addr;
+				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();
+				set_current_kprobe(p, regs);
+				p->nmissed++;
+				prepare_singlestep(p, regs);
+				kprobe_status = KPROBE_REENTER;
+				return 1;
 			}
-			arch_disarm_kprobe(p);
-			regs->rip = (unsigned long)p->addr;
-			ret = 1;
 		} else {
 			p = current_kprobe;
 			if (p->break_handler && p->break_handler(p, regs)) {
@@ -306,11 +349,7 @@ int kprobe_handler(struct pt_regs *regs)
 	}
 
 	kprobe_status = KPROBE_HIT_ACTIVE;
-	current_kprobe = p;
-	kprobe_saved_rflags = kprobe_old_rflags
-	    = (regs->eflags & (TF_MASK | IF_MASK));
-	if (is_IF_modifier(p->ainsn.insn))
-		kprobe_saved_rflags &= ~IF_MASK;
+	set_current_kprobe(p, regs);
 
 	if (p->pre_handler && p->pre_handler(p, regs))
 		/* handler has already set things up, so skip ss setup */
@@ -411,13 +450,21 @@ int post_kprobe_handler(struct pt_regs *
 	if (!kprobe_running())
 		return 0;
 
-	if (current_kprobe->post_handler)
+	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
+		kprobe_status = KPROBE_HIT_SSDONE;
 		current_kprobe->post_handler(current_kprobe, regs, 0);
+	}
 
 	resume_execution(current_kprobe, regs);
 	regs->eflags |= kprobe_saved_rflags;
 
+	/*Restore back the original saved kprobes variables and continue. */
+	if (kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe();
+		goto out;
+	}
 	unlock_kprobes();
+out:
 	preempt_enable_no_resched();
 
 	/*

_
-- 

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

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

* Re: [PATCH 4/5] Kprobes: Temporary disarming of reentrant probe for ppc64
  2005-05-24 10:18   ` [PATCH 3/5] Kprobes: Temporary disarming of reentrant probe for x86_64 Prasanna S Panchamukhi
@ 2005-05-24 10:19     ` Prasanna S Panchamukhi
  2005-05-24 10:20       ` [PATCH 5/5] Kprobes: Temporary disarming of reentrant probe for sparc64 Prasanna S Panchamukhi
  2005-05-24 18:13     ` [PATCH 3/5] Kprobes: Temporary disarming of reentrant probe for x86_64 Andi Kleen
  1 sibling, 1 reply; 9+ messages in thread
From: Prasanna S Panchamukhi @ 2005-05-24 10:19 UTC (permalink / raw)
  To: akpm, ak, davem; +Cc: linux-kernel, systemtap


This patch includes ppc64 architecture specific changes to support temporary
disarming on reentrancy of probes.

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


---

 linux-2.6.12-rc4-mm2-prasanna/arch/ppc64/kernel/kprobes.c |   46 +++++++++++---
 1 files changed, 38 insertions(+), 8 deletions(-)

diff -puN arch/ppc64/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-ppc64 arch/ppc64/kernel/kprobes.c
--- linux-2.6.12-rc4-mm2/arch/ppc64/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-ppc64	2005-05-24 15:30:04.000000000 +0530
+++ linux-2.6.12-rc4-mm2-prasanna/arch/ppc64/kernel/kprobes.c	2005-05-24 15:30:04.000000000 +0530
@@ -36,12 +36,10 @@
 #include <asm/kdebug.h>
 #include <asm/sstep.h>
 
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE	0x00000001
-#define KPROBE_HIT_SS		0x00000002
-
 static struct kprobe *current_kprobe;
 static unsigned long kprobe_status, kprobe_saved_msr;
+static struct kprobe *kprobe_prev;
+static unsigned long kprobe_status_prev, kprobe_saved_msr_prev;
 static struct pt_regs jprobe_saved_regs;
 
 int arch_prepare_kprobe(struct kprobe *p)
@@ -88,6 +86,20 @@ static inline void prepare_singlestep(st
 		regs->nip = (unsigned long)&p->ainsn.insn;
 }
 
+static inline void save_previous_kprobe(void)
+{
+	kprobe_prev = current_kprobe;
+	kprobe_status_prev = kprobe_status;
+	kprobe_saved_msr_prev = kprobe_saved_msr;
+}
+
+static inline void restore_previous_kprobe(void)
+{
+	current_kprobe = kprobe_prev;
+	kprobe_status = kprobe_status_prev;
+	kprobe_saved_msr = kprobe_saved_msr_prev;
+}
+
 static inline int kprobe_handler(struct pt_regs *regs)
 {
 	struct kprobe *p;
@@ -106,9 +118,19 @@ static inline int kprobe_handler(struct 
 				unlock_kprobes();
 				goto no_kprobe;
 			}
-			arch_disarm_kprobe(p);
-			regs->nip = (unsigned long)p->addr;
-			ret = 1;
+			/* 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();
+			current_kprobe = p;
+			kprobe_saved_msr = regs->msr;
+			p->nmissed++;
+			prepare_singlestep(p, regs);
+			kprobe_status = KPROBE_REENTER;
+			return 1;
 		} else {
 			p = current_kprobe;
 			if (p->break_handler && p->break_handler(p, regs)) {
@@ -192,13 +214,21 @@ static inline int post_kprobe_handler(st
 	if (!kprobe_running())
 		return 0;
 
-	if (current_kprobe->post_handler)
+	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
+		kprobe_status = KPROBE_HIT_SSDONE;
 		current_kprobe->post_handler(current_kprobe, regs, 0);
+	}
 
 	resume_execution(current_kprobe, regs);
 	regs->msr |= kprobe_saved_msr;
 
+	/*Restore back the original saved kprobes variables and continue. */
+	if (kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe();
+		goto out;
+	}
 	unlock_kprobes();
+out:
 	preempt_enable_no_resched();
 
 	/*

_
-- 

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

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

* Re: [PATCH 5/5] Kprobes: Temporary disarming of reentrant probe for sparc64
  2005-05-24 10:19     ` [PATCH 4/5] Kprobes: Temporary disarming of reentrant probe for ppc64 Prasanna S Panchamukhi
@ 2005-05-24 10:20       ` Prasanna S Panchamukhi
  0 siblings, 0 replies; 9+ messages in thread
From: Prasanna S Panchamukhi @ 2005-05-24 10:20 UTC (permalink / raw)
  To: akpm, ak, davem; +Cc: linux-kernel, systemtap


This patch includes sparc64 architecture specific changes to support temporary
disarming on reentrancy of probes.

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


---

 linux-2.6.12-rc4-mm2-prasanna/arch/sparc64/kernel/kprobes.c |   62 +++++++++---
 1 files changed, 49 insertions(+), 13 deletions(-)

diff -puN arch/sparc64/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-sparc64 arch/sparc64/kernel/kprobes.c
--- linux-2.6.12-rc4-mm2/arch/sparc64/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-sparc64	2005-05-24 15:30:47.000000000 +0530
+++ linux-2.6.12-rc4-mm2-prasanna/arch/sparc64/kernel/kprobes.c	2005-05-24 15:30:47.000000000 +0530
@@ -65,19 +65,40 @@ void arch_remove_kprobe(struct kprobe *p
 {
 }
 
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE	0x00000001
-#define KPROBE_HIT_SS		0x00000002
-
 static struct kprobe *current_kprobe;
 static unsigned long current_kprobe_orig_tnpc;
 static unsigned long current_kprobe_orig_tstate_pil;
 static unsigned int kprobe_status;
+static struct kprobe *kprobe_prev;
+static unsigned long kprobe_orig_tnpc_prev;
+static unsigned long kprobe_orig_tstate_pil_prev;
+static unsigned int kprobe_status_prev;
 
-static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static inline void save_previous_kprobe(void)
+{
+	kprobe_status_prev = kprobe_status;
+	kprobe_orig_tnpc_prev = current_kprobe_orig_tnpc;
+	kprobe_orig_tstate_pil_prev = current_kprobe_orig_tstate_pil;
+	kprobe_prev = current_kprobe;
+}
+
+static inline void restore_previous_kprobe(void)
+{
+	kprobe_status = kprobe_status_prev;
+	current_kprobe_orig_tnpc = kprobe_orig_tnpc_prev;
+	current_kprobe_orig_tstate_pil = kprobe_orig_tstate_pil_prev;
+	current_kprobe = kprobe_prev;
+}
+
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
 {
 	current_kprobe_orig_tnpc = regs->tnpc;
 	current_kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
+	current_kprobe = p;
+}
+
+static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+{
 	regs->tstate |= TSTATE_PIL;
 
 	/*single step inline, if it a breakpoint instruction*/
@@ -110,12 +131,18 @@ static int kprobe_handler(struct pt_regs
 				unlock_kprobes();
 				goto no_kprobe;
 			}
-			arch_disarm_kprobe(p);
-			regs->tpc = (unsigned long) p->addr;
-			regs->tnpc = current_kprobe_orig_tnpc;
-			regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
-					current_kprobe_orig_tstate_pil);
-			ret = 1;
+			/* 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();
+			set_current_kprobe(p, regs);
+			p->nmissed++;
+			kprobe_status = KPROBE_REENTER;
+			prepare_singlestep(p, regs);
+			return 1;
 		} else {
 			p = current_kprobe;
 			if (p->break_handler && p->break_handler(p, regs))
@@ -143,8 +170,8 @@ static int kprobe_handler(struct pt_regs
 		goto no_kprobe;
 	}
 
+	set_current_kprobe(p, regs);
 	kprobe_status = KPROBE_HIT_ACTIVE;
-	current_kprobe = p;
 	if (p->pre_handler && p->pre_handler(p, regs))
 		return 1;
 
@@ -250,12 +277,20 @@ static inline int post_kprobe_handler(st
 	if (!kprobe_running())
 		return 0;
 
-	if (current_kprobe->post_handler)
+	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
+		kprobe_status = KPROBE_HIT_SSDONE;
 		current_kprobe->post_handler(current_kprobe, regs, 0);
+	}
 
 	resume_execution(current_kprobe, regs);
 
+	/*Restore back the original saved kprobes variables and continue. */
+	if (kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe();
+		goto out;
+	}
 	unlock_kprobes();
+out:
 	preempt_enable_no_resched();
 
 	return 1;
@@ -397,3 +432,4 @@ int longjmp_break_handler(struct kprobe 
 	}
 	return 0;
 }
+

_
-- 

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

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

* Re: [PATCH 3/5] Kprobes: Temporary disarming of reentrant probe for x86_64
  2005-05-24 10:18   ` [PATCH 3/5] Kprobes: Temporary disarming of reentrant probe for x86_64 Prasanna S Panchamukhi
  2005-05-24 10:19     ` [PATCH 4/5] Kprobes: Temporary disarming of reentrant probe for ppc64 Prasanna S Panchamukhi
@ 2005-05-24 18:13     ` Andi Kleen
  1 sibling, 0 replies; 9+ messages in thread
From: Andi Kleen @ 2005-05-24 18:13 UTC (permalink / raw)
  To: Prasanna S Panchamukhi; +Cc: akpm, davem, linux-kernel, systemtap

On Tue, May 24, 2005 at 03:48:40PM +0530, Prasanna S Panchamukhi wrote:
> 
> This patch includes x86_64 architecture specific changes to support temporary
> disarming on reentrancy of probes.

Fine for me (for after 2.6.12)

-Andi

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

* Re: [PATCH 1/5] Kprobes: Temporary disarming of reentrant probe
  2005-05-24 10:15 [PATCH 1/5] Kprobes: Temporary disarming of reentrant probe Prasanna S Panchamukhi
  2005-05-24 10:17 ` [PATCH 2/5] Kprobes: Temporary disarming of reentrant probe for i386 Prasanna S Panchamukhi
@ 2005-05-24 18:15 ` Andi Kleen
  2005-05-24 18:21   ` Ananth N Mavinakayanahalli
  1 sibling, 1 reply; 9+ messages in thread
From: Andi Kleen @ 2005-05-24 18:15 UTC (permalink / raw)
  To: Prasanna S Panchamukhi; +Cc: akpm, davem, linux-kernel, systemtap

> @@ -55,6 +61,9 @@ struct kprobe {
>  	/* list of kprobes for multi-handler support */
>  	struct list_head list;
>  
> +	/*count the number of times this probe was temporarily disarmed */
> +	unsigned long nmissed;

You declare a variable.

> +
>  	/* location of the probe point */
>  	kprobe_opcode_t *addr;
>  
> diff -puN kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-generic kernel/kprobes.c
> --- linux-2.6.12-rc4-mm2/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-generic	2005-05-24 15:28:08.000000000 +0530
> +++ linux-2.6.12-rc4-mm2-prasanna/kernel/kprobes.c	2005-05-24 15:28:08.000000000 +0530
> @@ -334,6 +334,7 @@ int register_kprobe(struct kprobe *p)
>  	}
>  	spin_lock_irqsave(&kprobe_lock, flags);
>  	old_p = get_kprobe(p->addr);
> +	p->nmissed = 0;

And then you set it to 0.

And nothing more. Surely this patch does not do anything. Looks like
some code is missing.

-Andi

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

* Re: [PATCH 1/5] Kprobes: Temporary disarming of reentrant probe
  2005-05-24 18:15 ` [PATCH 1/5] Kprobes: Temporary disarming of reentrant probe Andi Kleen
@ 2005-05-24 18:21   ` Ananth N Mavinakayanahalli
  0 siblings, 0 replies; 9+ messages in thread
From: Ananth N Mavinakayanahalli @ 2005-05-24 18:21 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Prasanna S Panchamukhi, akpm, davem, linux-kernel, systemtap

Andi Kleen wrote:

Hi Andi,

>>@@ -55,6 +61,9 @@ struct kprobe {
>> 	/* list of kprobes for multi-handler support */
>> 	struct list_head list;
>> 
>>+	/*count the number of times this probe was temporarily disarmed */
>>+	unsigned long nmissed;
> 
> 
> You declare a variable.
> 
> 
>>+
>> 	/* location of the probe point */
>> 	kprobe_opcode_t *addr;
>> 
>>diff -puN kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-generic kernel/kprobes.c
>>--- linux-2.6.12-rc4-mm2/kernel/kprobes.c~kprobes-temporary-disarming-on-reentrancy-generic	2005-05-24 15:28:08.000000000 +0530
>>+++ linux-2.6.12-rc4-mm2-prasanna/kernel/kprobes.c	2005-05-24 15:28:08.000000000 +0530
>>@@ -334,6 +334,7 @@ int register_kprobe(struct kprobe *p)
>> 	}
>> 	spin_lock_irqsave(&kprobe_lock, flags);
>> 	old_p = get_kprobe(p->addr);
>>+	p->nmissed = 0;
> 
> 
> And then you set it to 0.
> 
> And nothing more. Surely this patch does not do anything. Looks like
> some code is missing.

No Andi - nmissed is incremented in the arch/xxx/kernel/kprobes.c
everytime the probe is "reentered". This is part of the subsequent
patches in the series.

Ananth


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

* Re: [PATCH 2/5] Kprobes: Temporary disarming of reentrant probe for i386
  2005-05-24 10:17 ` [PATCH 2/5] Kprobes: Temporary disarming of reentrant probe for i386 Prasanna S Panchamukhi
  2005-05-24 10:18   ` [PATCH 3/5] Kprobes: Temporary disarming of reentrant probe for x86_64 Prasanna S Panchamukhi
@ 2005-05-25 15:19   ` Andi Kleen
  1 sibling, 0 replies; 9+ messages in thread
From: Andi Kleen @ 2005-05-25 15:19 UTC (permalink / raw)
  To: Prasanna S Panchamukhi; +Cc: akpm, davem, linux-kernel, systemtap

On Tue, May 24, 2005 at 03:47:12PM +0530, Prasanna S Panchamukhi wrote:
> 
> This patch includes i386 architecture specific changes to support temporary
> disarming on reentrancy of probes.

The patches are all fine from my side.

-Andi

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

end of thread, other threads:[~2005-05-25 15:19 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-24 10:15 [PATCH 1/5] Kprobes: Temporary disarming of reentrant probe Prasanna S Panchamukhi
2005-05-24 10:17 ` [PATCH 2/5] Kprobes: Temporary disarming of reentrant probe for i386 Prasanna S Panchamukhi
2005-05-24 10:18   ` [PATCH 3/5] Kprobes: Temporary disarming of reentrant probe for x86_64 Prasanna S Panchamukhi
2005-05-24 10:19     ` [PATCH 4/5] Kprobes: Temporary disarming of reentrant probe for ppc64 Prasanna S Panchamukhi
2005-05-24 10:20       ` [PATCH 5/5] Kprobes: Temporary disarming of reentrant probe for sparc64 Prasanna S Panchamukhi
2005-05-24 18:13     ` [PATCH 3/5] Kprobes: Temporary disarming of reentrant probe for x86_64 Andi Kleen
2005-05-25 15:19   ` [PATCH 2/5] Kprobes: Temporary disarming of reentrant probe for i386 Andi Kleen
2005-05-24 18:15 ` [PATCH 1/5] Kprobes: Temporary disarming of reentrant probe Andi Kleen
2005-05-24 18:21   ` Ananth N Mavinakayanahalli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox