public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes
@ 2005-07-07 10:10 Prasanna S Panchamukhi
  2005-07-07 10:11 ` [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes Prasanna S Panchamukhi
  2005-07-07 10:25 ` [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes Andrew Morton
  0 siblings, 2 replies; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-07 10:10 UTC (permalink / raw)
  To: akpm, Andi Kleen, David S. Miller, systemtap; +Cc: linux-kernel

Hi,

Please provide your feedback on this kprobes patch set.

Thanks
Prasanna


There are possible race conditions if probes are placed on routines within the
kprobes files and routines used by the kprobes. For example if you put probe on
get_kprobe() routines, the system can hang while inserting probes on
any routine such as do_fork(). Because while inserting probes on do_fork(),
register_kprobes() routine grabs the kprobes spin lock and executes get_kprobe()
routine and to handle probe of get_kprobe(), kprobes_handler() gets executed 
and tries to grab kprobes spin lock, and spins forever. This patch avoids such
possible race conditions by preventing probes on routines within the kprobes
file and routines used by kprobes.

I have modified the patches as per Andi Kleen's suggestion to move kprobes
routines and other routines used by kprobes to a seperate section .kprobes.text.
Also moved page fault and exception handlers to .kprobes.text section.
These patches have been tested on i386, x86_64 and ppc64 architectures,
also compiled on ia64 and sparc64 architectures.

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


---

 linux-2.6.13-rc1-mm1-prasanna/include/asm-generic/vmlinux.lds.h |    5 
 linux-2.6.13-rc1-mm1-prasanna/include/linux/kprobes.h           |    4 
 linux-2.6.13-rc1-mm1-prasanna/kernel/kprobes.c                  |   69 ++++++----
 3 files changed, 51 insertions(+), 27 deletions(-)

diff -puN kernel/kprobes.c~kprobes-exclude-functions-generic kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/kernel/kprobes.c~kprobes-exclude-functions-generic	2005-07-06 18:51:16.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/kernel/kprobes.c	2005-07-06 18:51:45.000000000 +0530
@@ -72,7 +72,7 @@ static struct hlist_head kprobe_insn_pag
  * get_insn_slot() - Find a slot on an executable page for an instruction.
  * We allocate an executable page if there's no room on existing ones.
  */
-kprobe_opcode_t *get_insn_slot(void)
+kprobe_opcode_t * __kprobes get_insn_slot(void)
 {
 	struct kprobe_insn_page *kip;
 	struct hlist_node *pos;
@@ -117,7 +117,7 @@ kprobe_opcode_t *get_insn_slot(void)
 	return kip->insns;
 }
 
-void free_insn_slot(kprobe_opcode_t *slot)
+void __kprobes free_insn_slot(kprobe_opcode_t *slot)
 {
 	struct kprobe_insn_page *kip;
 	struct hlist_node *pos;
@@ -152,20 +152,20 @@ void free_insn_slot(kprobe_opcode_t *slo
 }
 
 /* Locks kprobe: irqs must be disabled */
-void lock_kprobes(void)
+void __kprobes lock_kprobes(void)
 {
 	spin_lock(&kprobe_lock);
 	kprobe_cpu = smp_processor_id();
 }
 
-void unlock_kprobes(void)
+void __kprobes unlock_kprobes(void)
 {
 	kprobe_cpu = NR_CPUS;
 	spin_unlock(&kprobe_lock);
 }
 
 /* You have to be holding the kprobe_lock */
-struct kprobe *get_kprobe(void *addr)
+struct kprobe * __kprobes get_kprobe(void *addr)
 {
 	struct hlist_head *head;
 	struct hlist_node *node;
@@ -183,7 +183,7 @@ struct kprobe *get_kprobe(void *addr)
  * Aggregate handlers for multiple kprobes support - these handlers
  * take care of invoking the individual kprobe handlers on p->list
  */
-static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kprobe *kp;
 
@@ -198,8 +198,8 @@ static int aggr_pre_handler(struct kprob
 	return 0;
 }
 
-static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
-			      unsigned long flags)
+static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
+					unsigned long flags)
 {
 	struct kprobe *kp;
 
@@ -213,8 +213,8 @@ static void aggr_post_handler(struct kpr
 	return;
 }
 
-static int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
-			      int trapnr)
+static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
+					int trapnr)
 {
 	/*
 	 * if we faulted "during" the execution of a user specified
@@ -227,7 +227,7 @@ static int aggr_fault_handler(struct kpr
 	return 0;
 }
 
-static int aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kprobe *kp = curr_kprobe;
 	if (curr_kprobe && kp->break_handler) {
@@ -240,7 +240,7 @@ static int aggr_break_handler(struct kpr
 	return 0;
 }
 
-struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp)
+struct kretprobe_instance * __kprobes get_free_rp_inst(struct kretprobe *rp)
 {
 	struct hlist_node *node;
 	struct kretprobe_instance *ri;
@@ -249,7 +249,8 @@ struct kretprobe_instance *get_free_rp_i
 	return NULL;
 }
 
-static struct kretprobe_instance *get_used_rp_inst(struct kretprobe *rp)
+static struct kretprobe_instance * __kprobes get_used_rp_inst(struct kretprobe
+							      *rp)
 {
 	struct hlist_node *node;
 	struct kretprobe_instance *ri;
@@ -258,7 +259,7 @@ static struct kretprobe_instance *get_us
 	return NULL;
 }
 
-void add_rp_inst(struct kretprobe_instance *ri)
+void __kprobes add_rp_inst(struct kretprobe_instance *ri)
 {
 	/*
 	 * Remove rp inst off the free list -
@@ -276,7 +277,7 @@ void add_rp_inst(struct kretprobe_instan
 	hlist_add_head(&ri->uflist, &ri->rp->used_instances);
 }
 
-void recycle_rp_inst(struct kretprobe_instance *ri)
+void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
 {
 	/* remove rp inst off the rprobe_inst_table */
 	hlist_del(&ri->hlist);
@@ -291,7 +292,7 @@ void recycle_rp_inst(struct kretprobe_in
 		kfree(ri);
 }
 
-struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk)
+struct hlist_head * __kprobes kretprobe_inst_table_head(struct task_struct *tsk)
 {
 	return &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)];
 }
@@ -302,7 +303,7 @@ struct hlist_head * kretprobe_inst_table
  * instances associated with this task. These left over instances represent
  * probed functions that have been called but will never return.
  */
-void kprobe_flush_task(struct task_struct *tk)
+void __kprobes kprobe_flush_task(struct task_struct *tk)
 {
         struct kretprobe_instance *ri;
         struct hlist_head *head;
@@ -322,7 +323,8 @@ void kprobe_flush_task(struct task_struc
  * This kprobe pre_handler is registered with every kretprobe. When probe
  * hits it will set up the return probe.
  */
-static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes pre_handler_kretprobe(struct kprobe *p,
+					   struct pt_regs *regs)
 {
 	struct kretprobe *rp = container_of(p, struct kretprobe, kp);
 
@@ -353,7 +355,7 @@ static inline void copy_kprobe(struct kp
 * Add the new probe to old_p->list. Fail if this is the
 * second jprobe at the address - two jprobes can't coexist
 */
-static int add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
+static int __kprobes add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
 {
         struct kprobe *kp;
 
@@ -395,7 +397,8 @@ static inline void add_aggr_kprobe(struc
  * the intricacies
  * TODO: Move kcalloc outside the spinlock
  */
-static int register_aggr_kprobe(struct kprobe *old_p, struct kprobe *p)
+static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
+					  struct kprobe *p)
 {
 	int ret = 0;
 	struct kprobe *ap;
@@ -434,12 +437,24 @@ static inline void cleanup_aggr_kprobe(s
 		spin_unlock_irqrestore(&kprobe_lock, flags);
 }
 
-int register_kprobe(struct kprobe *p)
+static int __kprobes in_kprobes_functions(unsigned long addr)
+{
+	/* Linker adds these: start and end of __kprobes functions */
+	extern char __kprobes_text_start[], __kprobes_text_end[];
+	if (addr >= (unsigned long)__kprobes_text_start
+		&& addr < (unsigned long)__kprobes_text_end)
+		return -EINVAL;
+	return 0;
+}
+
+int __kprobes register_kprobe(struct kprobe *p)
 {
 	int ret = 0;
 	unsigned long flags = 0;
 	struct kprobe *old_p;
 
+	if ((ret = in_kprobes_functions((unsigned long) p->addr)) !=0)
+		return ret;
 	if ((ret = arch_prepare_kprobe(p)) != 0) {
 		goto rm_kprobe;
 	}
@@ -466,7 +481,7 @@ rm_kprobe:
 	return ret;
 }
 
-void unregister_kprobe(struct kprobe *p)
+void __kprobes unregister_kprobe(struct kprobe *p)
 {
 	unsigned long flags;
 	struct kprobe *old_p;
@@ -487,7 +502,7 @@ static struct notifier_block kprobe_exce
 	.priority = 0x7fffffff /* we need to notified first */
 };
 
-int register_jprobe(struct jprobe *jp)
+int __kprobes register_jprobe(struct jprobe *jp)
 {
 	/* Todo: Verify probepoint is a function entry point */
 	jp->kp.pre_handler = setjmp_pre_handler;
@@ -496,14 +511,14 @@ int register_jprobe(struct jprobe *jp)
 	return register_kprobe(&jp->kp);
 }
 
-void unregister_jprobe(struct jprobe *jp)
+void __kprobes unregister_jprobe(struct jprobe *jp)
 {
 	unregister_kprobe(&jp->kp);
 }
 
 #ifdef ARCH_SUPPORTS_KRETPROBES
 
-int register_kretprobe(struct kretprobe *rp)
+int __kprobes register_kretprobe(struct kretprobe *rp)
 {
 	int ret = 0;
 	struct kretprobe_instance *inst;
@@ -540,14 +555,14 @@ int register_kretprobe(struct kretprobe 
 
 #else /* ARCH_SUPPORTS_KRETPROBES */
 
-int register_kretprobe(struct kretprobe *rp)
+int __kprobes register_kretprobe(struct kretprobe *rp)
 {
 	return -ENOSYS;
 }
 
 #endif /* ARCH_SUPPORTS_KRETPROBES */
 
-void unregister_kretprobe(struct kretprobe *rp)
+void __kprobes unregister_kretprobe(struct kretprobe *rp)
 {
 	unsigned long flags;
 	struct kretprobe_instance *ri;
diff -puN include/linux/kprobes.h~kprobes-exclude-functions-generic include/linux/kprobes.h
--- linux-2.6.13-rc1-mm1/include/linux/kprobes.h~kprobes-exclude-functions-generic	2005-07-06 18:51:16.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/include/linux/kprobes.h	2005-07-06 18:51:16.000000000 +0530
@@ -42,6 +42,10 @@
 #define KPROBE_REENTER		0x00000004
 #define KPROBE_HIT_SSDONE	0x00000008
 
+/* Attach to insert probes on any functions which should be ignored*/
+#define __kprobes	__attribute__((__section__(".kprobes.text")))
+/* Is this address in the __kprobes functions? */
+
 struct kprobe;
 struct pt_regs;
 struct kretprobe;
diff -puN include/asm-generic/vmlinux.lds.h~kprobes-exclude-functions-generic include/asm-generic/vmlinux.lds.h
--- linux-2.6.13-rc1-mm1/include/asm-generic/vmlinux.lds.h~kprobes-exclude-functions-generic	2005-07-06 18:51:16.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/include/asm-generic/vmlinux.lds.h	2005-07-06 18:51:16.000000000 +0530
@@ -95,3 +95,8 @@
 		VMLINUX_SYMBOL(__lock_text_start) = .;			\
 		*(.spinlock.text)					\
 		VMLINUX_SYMBOL(__lock_text_end) = .;
+
+#define KPROBES_TEXT							\
+		VMLINUX_SYMBOL(__kprobes_text_start) = .;			\
+		*(.kprobes.text)					\
+		VMLINUX_SYMBOL(__kprobes_text_end) = .;

_
-- 

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

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

* Re: [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes
  2005-07-07 10:10 [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes Prasanna S Panchamukhi
@ 2005-07-07 10:11 ` Prasanna S Panchamukhi
  2005-07-07 10:14   ` [3/6 PATCH] Kprobes : Prevent possible race conditions x86_64 changes Prasanna S Panchamukhi
  2005-07-07 13:19   ` [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes Andi Kleen
  2005-07-07 10:25 ` [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes Andrew Morton
  1 sibling, 2 replies; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-07 10:11 UTC (permalink / raw)
  To: akpm, Andi Kleen, David S. Miller, systemtap; +Cc: linux-kernel


This patch contains the i386 architecture specific changes to
prevent the possible race conditions.

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


---

 linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/kprobes.c     |   29 +++++------
 linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/traps.c       |   12 ++--
 linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/vmlinux.lds.S |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/i386/mm/fault.c           |    4 +
 4 files changed, 26 insertions(+), 20 deletions(-)

diff -puN arch/i386/kernel/kprobes.c~kprobes-exclude-functions-i386 arch/i386/kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/arch/i386/kernel/kprobes.c~kprobes-exclude-functions-i386	2005-07-06 17:31:04.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/kprobes.c	2005-07-06 17:43:59.000000000 +0530
@@ -62,32 +62,32 @@ static inline int is_IF_modifier(kprobe_
 	return 0;
 }
 
-int arch_prepare_kprobe(struct kprobe *p)
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	return 0;
 }
 
-void arch_copy_kprobe(struct kprobe *p)
+void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
 	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
 	p->opcode = *p->addr;
 }
 
-void arch_arm_kprobe(struct kprobe *p)
+void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
 	*p->addr = BREAKPOINT_INSTRUCTION;
 	flush_icache_range((unsigned long) p->addr,
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_disarm_kprobe(struct kprobe *p)
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
 	*p->addr = p->opcode;
 	flush_icache_range((unsigned long) p->addr,
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
 }
 
@@ -127,7 +127,8 @@ static inline void prepare_singlestep(st
 		regs->eip = (unsigned long)&p->ainsn.insn;
 }
 
-void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+				      struct pt_regs *regs)
 {
 	unsigned long *sara = (unsigned long *)&regs->esp;
         struct kretprobe_instance *ri;
@@ -150,7 +151,7 @@ void arch_prepare_kretprobe(struct kretp
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
  * remain disabled thorough out this function.
  */
-static int kprobe_handler(struct pt_regs *regs)
+static int __kprobes kprobe_handler(struct pt_regs *regs)
 {
 	struct kprobe *p;
 	int ret = 0;
@@ -259,7 +260,7 @@ no_kprobe:
 /*
  * Called when we hit the probe point at kretprobe_trampoline
  */
-int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
@@ -338,7 +339,7 @@ int trampoline_probe_handler(struct kpro
  * that is atop the stack is the address following the copied instruction.
  * We need to make it the address following the original instruction.
  */
-static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
 	unsigned long *tos = (unsigned long *)&regs->esp;
 	unsigned long next_eip = 0;
@@ -444,8 +445,8 @@ static inline int kprobe_fault_handler(s
 /*
  * Wrapper routine to for handling exceptions.
  */
-int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
-			     void *data)
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
 	switch (val) {
@@ -473,7 +474,7 @@ int kprobe_exceptions_notify(struct noti
 	return NOTIFY_DONE;
 }
 
-int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 	unsigned long addr;
@@ -495,7 +496,7 @@ int setjmp_pre_handler(struct kprobe *p,
 	return 1;
 }
 
-void jprobe_return(void)
+void __kprobes jprobe_return(void)
 {
 	preempt_enable_no_resched();
 	asm volatile ("       xchgl   %%ebx,%%esp     \n"
@@ -506,7 +507,7 @@ void jprobe_return(void)
 		      (jprobe_saved_esp):"memory");
 }
 
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	u8 *addr = (u8 *) (regs->eip - 1);
 	unsigned long stack_addr = (unsigned long)jprobe_saved_esp;
diff -puN arch/i386/kernel/traps.c~kprobes-exclude-functions-i386 arch/i386/kernel/traps.c
--- linux-2.6.13-rc1-mm1/arch/i386/kernel/traps.c~kprobes-exclude-functions-i386	2005-07-06 17:31:04.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/traps.c	2005-07-06 17:31:04.000000000 +0530
@@ -408,8 +408,9 @@ static inline void die_if_kernel(const c
 		die(str, regs, err);
 }
 
-static void do_trap(int trapnr, int signr, char *str, int vm86,
-			   struct pt_regs * regs, long error_code, siginfo_t *info)
+static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86,
+			      struct pt_regs * regs, long error_code,
+			      siginfo_t *info)
 {
 	struct task_struct *tsk = current;
 	tsk->thread.error_code = error_code;
@@ -507,7 +508,8 @@ DO_ERROR(12, SIGBUS,  "stack segment", s
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
 DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
 
-fastcall void do_general_protection(struct pt_regs * regs, long error_code)
+fastcall void __kprobes do_general_protection(struct pt_regs * regs,
+					      long error_code)
 {
 	int cpu = get_cpu();
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
@@ -737,7 +739,7 @@ void unset_nmi_callback(void)
 EXPORT_SYMBOL_GPL(unset_nmi_callback);
 
 #ifdef CONFIG_KPROBES
-fastcall void do_int3(struct pt_regs *regs, long error_code)
+fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
 {
 	if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
 			== NOTIFY_STOP)
@@ -771,7 +773,7 @@ fastcall void do_int3(struct pt_regs *re
  * find every occurrence of the TF bit that could be saved away even
  * by user code)
  */
-fastcall void do_debug(struct pt_regs * regs, long error_code)
+fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
 {
 	unsigned int condition;
 	struct task_struct *tsk = current;
diff -puN arch/i386/kernel/vmlinux.lds.S~kprobes-exclude-functions-i386 arch/i386/kernel/vmlinux.lds.S
--- linux-2.6.13-rc1-mm1/arch/i386/kernel/vmlinux.lds.S~kprobes-exclude-functions-i386	2005-07-06 17:31:04.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/vmlinux.lds.S	2005-07-06 17:31:04.000000000 +0530
@@ -22,6 +22,7 @@ SECTIONS
 	*(.text)
 	SCHED_TEXT
 	LOCK_TEXT
+	KPROBES_TEXT
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x9090
diff -puN arch/i386/mm/fault.c~kprobes-exclude-functions-i386 arch/i386/mm/fault.c
--- linux-2.6.13-rc1-mm1/arch/i386/mm/fault.c~kprobes-exclude-functions-i386	2005-07-06 17:31:04.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/i386/mm/fault.c	2005-07-06 17:31:04.000000000 +0530
@@ -21,6 +21,7 @@
 #include <linux/vt_kern.h>		/* For unblank_screen() */
 #include <linux/highmem.h>
 #include <linux/module.h>
+#include <linux/kprobes.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -211,7 +212,8 @@ fastcall void do_invalid_op(struct pt_re
  *	bit 1 == 0 means read, 1 means write
  *	bit 2 == 0 means kernel, 1 means user-mode
  */
-fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+fastcall void __kprobes do_page_fault(struct pt_regs *regs,
+				      unsigned long error_code)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;

_
-- 

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

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

* Re: [3/6 PATCH] Kprobes : Prevent possible race conditions x86_64 changes
  2005-07-07 10:11 ` [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes Prasanna S Panchamukhi
@ 2005-07-07 10:14   ` Prasanna S Panchamukhi
  2005-07-07 10:16     ` [4/6 PATCH] Kprobes : Prevent possible race conditions ppc64 changes Prasanna S Panchamukhi
  2005-07-08 11:07     ` [3/6 PATCH] Kprobes : Prevent possible race conditions x86_64 changes Prasanna S Panchamukhi
  2005-07-07 13:19   ` [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes Andi Kleen
  1 sibling, 2 replies; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-07 10:14 UTC (permalink / raw)
  To: akpm, Andi Kleen, David S. Miller, systemtap; +Cc: linux-kernel



This patch contains the x86_64 architecture specific changes to
prevent the possible race conditions.

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


---

 linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/kprobes.c     |   35 +++++-----
 linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/traps.c       |   14 ++--
 linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/vmlinux.lds.S |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/mm/fault.c           |    3 
 4 files changed, 30 insertions(+), 23 deletions(-)

diff -puN arch/x86_64/kernel/kprobes.c~kprobes-exclude-functions-x86_64 arch/x86_64/kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/arch/x86_64/kernel/kprobes.c~kprobes-exclude-functions-x86_64	2005-07-06 17:45:18.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/kprobes.c	2005-07-06 17:45:43.000000000 +0530
@@ -74,7 +74,7 @@ static inline int is_IF_modifier(kprobe_
 	return 0;
 }
 
-int arch_prepare_kprobe(struct kprobe *p)
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	/* insn: must be on special executable page on x86_64. */
 	up(&kprobe_mutex);
@@ -189,7 +189,7 @@ static inline s32 *is_riprel(u8 *insn)
 	return NULL;
 }
 
-void arch_copy_kprobe(struct kprobe *p)
+void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
 	s32 *ripdisp;
 	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
@@ -215,21 +215,21 @@ void arch_copy_kprobe(struct kprobe *p)
 	p->opcode = *p->addr;
 }
 
-void arch_arm_kprobe(struct kprobe *p)
+void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
 	*p->addr = BREAKPOINT_INSTRUCTION;
 	flush_icache_range((unsigned long) p->addr,
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_disarm_kprobe(struct kprobe *p)
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
 	*p->addr = p->opcode;
 	flush_icache_range((unsigned long) p->addr,
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
 	up(&kprobe_mutex);
 	free_insn_slot(p->ainsn.insn);
@@ -261,7 +261,7 @@ static inline void set_current_kprobe(st
 		kprobe_saved_rflags &= ~IF_MASK;
 }
 
-static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
 	regs->eflags |= TF_MASK;
 	regs->eflags &= ~IF_MASK;
@@ -272,7 +272,8 @@ static void prepare_singlestep(struct kp
 		regs->rip = (unsigned long)p->ainsn.insn;
 }
 
-void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+				      struct pt_regs *regs)
 {
 	unsigned long *sara = (unsigned long *)regs->rsp;
         struct kretprobe_instance *ri;
@@ -295,7 +296,7 @@ void arch_prepare_kretprobe(struct kretp
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
  * remain disabled thorough out this function.
  */
-int kprobe_handler(struct pt_regs *regs)
+int __kprobes kprobe_handler(struct pt_regs *regs)
 {
 	struct kprobe *p;
 	int ret = 0;
@@ -399,7 +400,7 @@ no_kprobe:
 /*
  * Called when we hit the probe point at kretprobe_trampoline
  */
-int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
@@ -478,7 +479,7 @@ int trampoline_probe_handler(struct kpro
  * that is atop the stack is the address following the copied instruction.
  * We need to make it the address following the original instruction.
  */
-static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
 	unsigned long *tos = (unsigned long *)regs->rsp;
 	unsigned long next_rip = 0;
@@ -536,7 +537,7 @@ static void resume_execution(struct kpro
  * Interrupts are disabled on entry as trap1 is an interrupt gate and they
  * remain disabled thoroughout this function.  And we hold kprobe lock.
  */
-int post_kprobe_handler(struct pt_regs *regs)
+int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
 	if (!kprobe_running())
 		return 0;
@@ -571,7 +572,7 @@ out:
 }
 
 /* Interrupts disabled, kprobe_lock held. */
-int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
 	if (current_kprobe->fault_handler
 	    && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
@@ -590,8 +591,8 @@ int kprobe_fault_handler(struct pt_regs 
 /*
  * Wrapper routine for handling exceptions.
  */
-int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
-			     void *data)
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
 	switch (val) {
@@ -619,7 +620,7 @@ int kprobe_exceptions_notify(struct noti
 	return NOTIFY_DONE;
 }
 
-int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 	unsigned long addr;
@@ -640,7 +641,7 @@ int setjmp_pre_handler(struct kprobe *p,
 	return 1;
 }
 
-void jprobe_return(void)
+void __kprobes jprobe_return(void)
 {
 	preempt_enable_no_resched();
 	asm volatile ("       xchg   %%rbx,%%rsp     \n"
@@ -651,7 +652,7 @@ void jprobe_return(void)
 		      (jprobe_saved_rsp):"memory");
 }
 
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	u8 *addr = (u8 *) (regs->rip - 1);
 	unsigned long stack_addr = (unsigned long)jprobe_saved_rsp;
diff -puN arch/x86_64/kernel/traps.c~kprobes-exclude-functions-x86_64 arch/x86_64/kernel/traps.c
--- linux-2.6.13-rc1-mm1/arch/x86_64/kernel/traps.c~kprobes-exclude-functions-x86_64	2005-07-06 17:45:18.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/traps.c	2005-07-06 17:45:18.000000000 +0530
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/nmi.h>
+#include <linux/kprobes.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -422,8 +423,9 @@ void die_nmi(char *str, struct pt_regs *
 	do_exit(SIGSEGV);
 }
 
-static void do_trap(int trapnr, int signr, char *str, 
-			   struct pt_regs * regs, long error_code, siginfo_t *info)
+static void __kprobes do_trap(int trapnr, int signr, char *str,
+			      struct pt_regs * regs, long error_code,
+			      siginfo_t *info)
 {
 	conditional_sti(regs);
 
@@ -507,7 +509,8 @@ DO_ERROR(18, SIGSEGV, "reserved", reserv
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR( 8, SIGSEGV, "double fault", double_fault)
 
-asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
+asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
+						long error_code)
 {
 	conditional_sti(regs);
 
@@ -628,7 +631,7 @@ asmlinkage void default_do_nmi(struct pt
 		io_check_error(reason, regs);
 }
 
-asmlinkage void do_int3(struct pt_regs * regs, long error_code)
+asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code)
 {
 	if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) {
 		return;
@@ -659,7 +662,8 @@ asmlinkage struct pt_regs *sync_regs(str
 }
 
 /* runs on IST stack. */
-asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code)
+asmlinkage void __kprobes do_debug(struct pt_regs * regs,
+				   unsigned long error_code)
 {
 	unsigned long condition;
 	struct task_struct *tsk = current;
diff -puN arch/x86_64/kernel/vmlinux.lds.S~kprobes-exclude-functions-x86_64 arch/x86_64/kernel/vmlinux.lds.S
--- linux-2.6.13-rc1-mm1/arch/x86_64/kernel/vmlinux.lds.S~kprobes-exclude-functions-x86_64	2005-07-06 17:45:18.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/vmlinux.lds.S	2005-07-06 17:45:18.000000000 +0530
@@ -21,6 +21,7 @@ SECTIONS
 	*(.text)
 	SCHED_TEXT
 	LOCK_TEXT
+	KPROBES_TEXT
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x9090
diff -puN arch/x86_64/mm/fault.c~kprobes-exclude-functions-x86_64 arch/x86_64/mm/fault.c
--- linux-2.6.13-rc1-mm1/arch/x86_64/mm/fault.c~kprobes-exclude-functions-x86_64	2005-07-06 17:45:18.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/mm/fault.c	2005-07-06 17:45:18.000000000 +0530
@@ -297,7 +297,8 @@ int exception_trace = 1;
  *	bit 2 == 0 means kernel, 1 means user-mode
  *      bit 3 == 1 means fault was an instruction fetch
  */
-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
+					unsigned long error_code)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;

_
-- 

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

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

* Re: [4/6 PATCH] Kprobes : Prevent possible race conditions ppc64 changes
  2005-07-07 10:14   ` [3/6 PATCH] Kprobes : Prevent possible race conditions x86_64 changes Prasanna S Panchamukhi
@ 2005-07-07 10:16     ` Prasanna S Panchamukhi
  2005-07-07 10:18       ` [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes Prasanna S Panchamukhi
  2005-07-08 14:13       ` [4/6 PATCH] Kprobes : Prevent possible race conditions ppc64 changes Ananth N Mavinakayanahalli
  2005-07-08 11:07     ` [3/6 PATCH] Kprobes : Prevent possible race conditions x86_64 changes Prasanna S Panchamukhi
  1 sibling, 2 replies; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-07 10:16 UTC (permalink / raw)
  To: akpm, Andi Kleen, David S. Miller, systemtap; +Cc: linux-kernel


This patch contains the ppc64 architecture specific changes to
prevent the possible race conditions.

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


---

 linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/kprobes.c     |   29 +++++-----
 linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/misc.S        |    4 -
 linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/traps.c       |    5 +
 linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/vmlinux.lds.S |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/mm/fault.c           |    5 +
 linux-2.6.13-rc1-mm1-prasanna/include/asm-ppc64/processor.h   |   14 ++++
 6 files changed, 38 insertions(+), 20 deletions(-)

diff -puN arch/ppc64/kernel/kprobes.c~kprobes-exclude-functions-ppc64 arch/ppc64/kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/arch/ppc64/kernel/kprobes.c~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/kprobes.c	2005-07-06 20:07:22.000000000 +0530
@@ -44,7 +44,7 @@ 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)
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	int ret = 0;
 	kprobe_opcode_t insn = *p->addr;
@@ -68,27 +68,27 @@ int arch_prepare_kprobe(struct kprobe *p
 	return ret;
 }
 
-void arch_copy_kprobe(struct kprobe *p)
+void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
 	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
 	p->opcode = *p->addr;
 }
 
-void arch_arm_kprobe(struct kprobe *p)
+void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
 	*p->addr = BREAKPOINT_INSTRUCTION;
 	flush_icache_range((unsigned long) p->addr,
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_disarm_kprobe(struct kprobe *p)
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
 	*p->addr = p->opcode;
 	flush_icache_range((unsigned long) p->addr,
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
 	up(&kprobe_mutex);
 	free_insn_slot(p->ainsn.insn);
@@ -122,7 +122,8 @@ static inline void restore_previous_kpro
 	kprobe_saved_msr = kprobe_saved_msr_prev;
 }
 
-void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+				      struct pt_regs *regs)
 {
 	struct kretprobe_instance *ri;
 
@@ -244,7 +245,7 @@ void kretprobe_trampoline_holder(void)
 /*
  * Called when the probe at kretprobe trampoline is hit
  */
-int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
@@ -308,7 +309,7 @@ int trampoline_probe_handler(struct kpro
  * single-stepped a copy of the instruction.  The address of this
  * copy is p->ainsn.insn.
  */
-static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
 	int ret;
 	unsigned int insn = *p->ainsn.insn;
@@ -373,8 +374,8 @@ static inline int kprobe_fault_handler(s
 /*
  * Wrapper routine to for handling exceptions.
  */
-int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
-			     void *data)
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
 	int ret = NOTIFY_DONE;
@@ -406,7 +407,7 @@ int kprobe_exceptions_notify(struct noti
 	return ret;
 }
 
-int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 
@@ -419,16 +420,16 @@ int setjmp_pre_handler(struct kprobe *p,
 	return 1;
 }
 
-void jprobe_return(void)
+void __kprobes jprobe_return(void)
 {
 	asm volatile("trap" ::: "memory");
 }
 
-void jprobe_return_end(void)
+void __kprobes jprobe_return_end(void)
 {
 };
 
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	/*
 	 * FIXME - we should ideally be validating that we got here 'cos
diff -puN arch/ppc64/kernel/traps.c~kprobes-exclude-functions-ppc64 arch/ppc64/kernel/traps.c
--- linux-2.6.13-rc1-mm1/arch/ppc64/kernel/traps.c~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/traps.c	2005-07-06 20:07:22.000000000 +0530
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/kprobes.h>
 #include <asm/kdebug.h>
 
 #include <asm/pgtable.h>
@@ -220,7 +221,7 @@ void instruction_breakpoint_exception(st
 	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
 }
 
-void single_step_exception(struct pt_regs *regs)
+void __kprobes single_step_exception(struct pt_regs *regs)
 {
 	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
 
@@ -398,7 +399,7 @@ check_bug_trap(struct pt_regs *regs)
 	return 0;
 }
 
-void program_check_exception(struct pt_regs *regs)
+void __kprobes program_check_exception(struct pt_regs *regs)
 {
 	if (debugger_fault_handler(regs))
 		return;
diff -puN arch/ppc64/kernel/vmlinux.lds.S~kprobes-exclude-functions-ppc64 arch/ppc64/kernel/vmlinux.lds.S
--- linux-2.6.13-rc1-mm1/arch/ppc64/kernel/vmlinux.lds.S~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/vmlinux.lds.S	2005-07-06 20:07:22.000000000 +0530
@@ -15,6 +15,7 @@ SECTIONS
 	*(.text .text.*)
 	SCHED_TEXT
 	LOCK_TEXT
+	KPROBES_TEXT
 	*(.fixup)
 	. = ALIGN(4096);
 	_etext = .;
diff -puN arch/ppc64/mm/fault.c~kprobes-exclude-functions-ppc64 arch/ppc64/mm/fault.c
--- linux-2.6.13-rc1-mm1/arch/ppc64/mm/fault.c~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/mm/fault.c	2005-07-06 20:07:22.000000000 +0530
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
 #include <linux/module.h>
+#include <linux/kprobes.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -84,8 +85,8 @@ static int store_updates_sp(struct pt_re
  * The return value is 0 if the fault was handled, or the signal
  * number if this is a kernel fault that can't be handled here.
  */
-int do_page_fault(struct pt_regs *regs, unsigned long address,
-		  unsigned long error_code)
+int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
+			    unsigned long error_code)
 {
 	struct vm_area_struct * vma;
 	struct mm_struct *mm = current->mm;
diff -puN arch/ppc64/kernel/misc.S~kprobes-exclude-functions-ppc64 arch/ppc64/kernel/misc.S
--- linux-2.6.13-rc1-mm1/arch/ppc64/kernel/misc.S~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/misc.S	2005-07-07 10:24:00.000000000 +0530
@@ -183,7 +183,7 @@ PPC64_CACHES:
  *   flush all bytes from start through stop-1 inclusive
  */
 
-_GLOBAL(__flush_icache_range)
+_KPROBE(__flush_icache_range)
 
 /*
  * Flush the data cache to memory 
@@ -223,7 +223,7 @@ _GLOBAL(__flush_icache_range)
 	bdnz	2b
 	isync
 	blr
-	
+	.previous .text
 /*
  * Like above, but only do the D-cache.
  *
diff -puN include/asm-ppc64/processor.h~kprobes-exclude-functions-ppc64 include/asm-ppc64/processor.h
--- linux-2.6.13-rc1-mm1/include/asm-ppc64/processor.h~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/include/asm-ppc64/processor.h	2005-07-07 10:22:29.000000000 +0530
@@ -309,6 +309,20 @@ name: \
 	.type GLUE(.,name),@function; \
 GLUE(.,name):
 
+#define _KPROBE(name) \
+	.section ".kprobes.text","a"; \
+	.align 2 ; \
+	.globl name; \
+	.globl GLUE(.,name); \
+	.section ".opd","aw"; \
+name: \
+	.quad GLUE(.,name); \
+	.quad .TOC.@tocbase; \
+	.quad 0; \
+	.previous; \
+	.type GLUE(.,name),@function; \
+GLUE(.,name):
+
 #define _STATIC(name) \
 	.section ".text"; \
 	.align 2 ; \

_
-- 

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

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

* Re: [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes
  2005-07-07 10:16     ` [4/6 PATCH] Kprobes : Prevent possible race conditions ppc64 changes Prasanna S Panchamukhi
@ 2005-07-07 10:18       ` Prasanna S Panchamukhi
  2005-07-07 10:20         ` [6/6 PATCH] Kprobes : Prevent possible race conditions sparc64 changes Prasanna S Panchamukhi
  2005-07-08  2:06         ` [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes Keshavamurthy Anil S
  2005-07-08 14:13       ` [4/6 PATCH] Kprobes : Prevent possible race conditions ppc64 changes Ananth N Mavinakayanahalli
  1 sibling, 2 replies; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-07 10:18 UTC (permalink / raw)
  To: akpm, Andi Kleen, David S. Miller, systemtap; +Cc: linux-kernel


This patch contains the ia64 architecture specific changes to
prevent the possible race conditions.

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


---

 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/kprobes.c     |   57 ++++++-----
 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/traps.c       |    5 
 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/vmlinux.lds.S |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/lib/flush.S          |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/mm/fault.c           |    3 
 5 files changed, 40 insertions(+), 27 deletions(-)

diff -puN arch/ia64/kernel/kprobes.c~kprobes-exclude-functions-ia64 arch/ia64/kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/arch/ia64/kernel/kprobes.c~kprobes-exclude-functions-ia64	2005-07-07 11:19:05.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/kprobes.c	2005-07-07 11:19:05.000000000 +0530
@@ -87,8 +87,10 @@ static enum instruction_type bundle_enco
  * is IP relative instruction and update the kprobe
  * inst flag accordingly
  */
-static void update_kprobe_inst_flag(uint template, uint  slot, uint major_opcode,
-	unsigned long kprobe_inst, struct kprobe *p)
+static void __kprobes update_kprobe_inst_flag(uint template, uint  slot,
+					      uint major_opcode,
+					      unsigned long kprobe_inst,
+					      struct kprobe *p)
 {
 	p->ainsn.inst_flag = 0;
 	p->ainsn.target_br_reg = 0;
@@ -126,8 +128,10 @@ static void update_kprobe_inst_flag(uint
  * Returns 0 if supported
  * Returns -EINVAL if unsupported
  */
-static int unsupported_inst(uint template, uint  slot, uint major_opcode,
-	unsigned long kprobe_inst, struct kprobe *p)
+static int __kprobes unsupported_inst(uint template, uint  slot,
+				      uint major_opcode,
+				      unsigned long kprobe_inst,
+				      struct kprobe *p)
 {
 	unsigned long addr = (unsigned long)p->addr;
 
@@ -168,8 +172,9 @@ static int unsupported_inst(uint templat
  * on which we are inserting kprobe is cmp instruction
  * with ctype as unc.
  */
-static uint is_cmp_ctype_unc_inst(uint template, uint slot, uint major_opcode,
-unsigned long kprobe_inst)
+static uint __kprobes is_cmp_ctype_unc_inst(uint template, uint slot,
+					    uint major_opcode,
+					    unsigned long kprobe_inst)
 {
 	cmp_inst_t cmp_inst;
 	uint ctype_unc = 0;
@@ -201,8 +206,10 @@ out:
  * In this function we override the bundle with
  * the break instruction at the given slot.
  */
-static void prepare_break_inst(uint template, uint  slot, uint major_opcode,
-	unsigned long kprobe_inst, struct kprobe *p)
+static void __kprobes prepare_break_inst(uint template, uint  slot,
+					 uint major_opcode,
+					 unsigned long kprobe_inst,
+					 struct kprobe *p)
 {
 	unsigned long break_inst = BREAK_INST;
 	bundle_t *bundle = &p->ainsn.insn.bundle;
@@ -271,7 +278,8 @@ static inline int in_ivt_functions(unsig
 		&& addr < (unsigned long)__end_ivt_text);
 }
 
-static int valid_kprobe_addr(int template, int slot, unsigned long addr)
+static int __kprobes valid_kprobe_addr(int template, int slot,
+				       unsigned long addr)
 {
 	if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) {
 		printk(KERN_WARNING "Attempting to insert unaligned kprobe "
@@ -323,7 +331,7 @@ static void kretprobe_trampoline(void)
  *    - cleanup by marking the instance as unused
  *    - long jump back to the original return address
  */
-int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kretprobe_instance *ri = NULL;
 	struct hlist_head *head;
@@ -381,7 +389,8 @@ int trampoline_probe_handler(struct kpro
         return 1;
 }
 
-void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+				      struct pt_regs *regs)
 {
 	struct kretprobe_instance *ri;
 
@@ -399,7 +408,7 @@ void arch_prepare_kretprobe(struct kretp
 	}
 }
 
-int arch_prepare_kprobe(struct kprobe *p)
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	unsigned long addr = (unsigned long) p->addr;
 	unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL);
@@ -430,7 +439,7 @@ int arch_prepare_kprobe(struct kprobe *p
 	return 0;
 }
 
-void arch_arm_kprobe(struct kprobe *p)
+void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
 	unsigned long addr = (unsigned long)p->addr;
 	unsigned long arm_addr = addr & ~0xFULL;
@@ -439,7 +448,7 @@ void arch_arm_kprobe(struct kprobe *p)
 	flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
 }
 
-void arch_disarm_kprobe(struct kprobe *p)
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
 	unsigned long addr = (unsigned long)p->addr;
 	unsigned long arm_addr = addr & ~0xFULL;
@@ -449,7 +458,7 @@ void arch_disarm_kprobe(struct kprobe *p
 	flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
 }
 
@@ -461,7 +470,7 @@ void arch_remove_kprobe(struct kprobe *p
  * to original stack address, handle the case where we need to fixup the
  * relative IP address and/or fixup branch register.
  */
-static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
   	unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL;
   	unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
@@ -528,7 +537,7 @@ turn_ss_off:
   	ia64_psr(regs)->ss = 0;
 }
 
-static void prepare_ss(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
 {
 	unsigned long bundle_addr = (unsigned long) &p->opcode.bundle;
 	unsigned long slot = (unsigned long)p->addr & 0xf;
@@ -545,7 +554,7 @@ static void prepare_ss(struct kprobe *p,
 	ia64_psr(regs)->ss = 1;
 }
 
-static int pre_kprobes_handler(struct die_args *args)
+static int __kprobes pre_kprobes_handler(struct die_args *args)
 {
 	struct kprobe *p;
 	int ret = 0;
@@ -616,7 +625,7 @@ no_kprobe:
 	return ret;
 }
 
-static int post_kprobes_handler(struct pt_regs *regs)
+static int __kprobes post_kprobes_handler(struct pt_regs *regs)
 {
 	if (!kprobe_running())
 		return 0;
@@ -641,7 +650,7 @@ out:
 	return 1;
 }
 
-static int kprobes_fault_handler(struct pt_regs *regs, int trapnr)
+static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
 {
 	if (!kprobe_running())
 		return 0;
@@ -659,8 +668,8 @@ static int kprobes_fault_handler(struct 
 	return 0;
 }
 
-int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
-			     void *data)
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
 	switch(val) {
@@ -681,7 +690,7 @@ int kprobe_exceptions_notify(struct noti
 	return NOTIFY_DONE;
 }
 
-int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 	unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
@@ -703,7 +712,7 @@ int setjmp_pre_handler(struct kprobe *p,
 	return 1;
 }
 
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	*regs = jprobe_saved_regs;
 	return 1;
diff -puN arch/ia64/kernel/traps.c~kprobes-exclude-functions-ia64 arch/ia64/kernel/traps.c
--- linux-2.6.13-rc1-mm1/arch/ia64/kernel/traps.c~kprobes-exclude-functions-ia64	2005-07-07 11:19:05.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/traps.c	2005-07-07 11:19:05.000000000 +0530
@@ -15,6 +15,7 @@
 #include <linux/vt_kern.h>		/* For unblank_screen() */
 #include <linux/module.h>       /* for EXPORT_SYMBOL */
 #include <linux/hardirq.h>
+#include <linux/kprobes.h>
 
 #include <asm/fpswa.h>
 #include <asm/ia32.h>
@@ -120,7 +121,7 @@ die_if_kernel (char *str, struct pt_regs
 }
 
 void
-ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
+__kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
 {
 	siginfo_t siginfo;
 	int sig, code;
@@ -442,7 +443,7 @@ ia64_illegal_op_fault (unsigned long ec,
 	return rv;
 }
 
-void
+void __kprobes
 ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 	    unsigned long iim, unsigned long itir, long arg5, long arg6,
 	    long arg7, struct pt_regs regs)
diff -puN arch/ia64/kernel/vmlinux.lds.S~kprobes-exclude-functions-ia64 arch/ia64/kernel/vmlinux.lds.S
--- linux-2.6.13-rc1-mm1/arch/ia64/kernel/vmlinux.lds.S~kprobes-exclude-functions-ia64	2005-07-07 11:19:05.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/vmlinux.lds.S	2005-07-07 11:19:05.000000000 +0530
@@ -48,6 +48,7 @@ SECTIONS
 	*(.text)
 	SCHED_TEXT
 	LOCK_TEXT
+	KPROBES_TEXT
 	*(.gnu.linkonce.t*)
     }
   .text2 : AT(ADDR(.text2) - LOAD_OFFSET)
diff -puN arch/ia64/mm/fault.c~kprobes-exclude-functions-ia64 arch/ia64/mm/fault.c
--- linux-2.6.13-rc1-mm1/arch/ia64/mm/fault.c~kprobes-exclude-functions-ia64	2005-07-07 11:19:05.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/mm/fault.c	2005-07-07 11:19:05.000000000 +0530
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
+#include <linux/kprobes.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -76,7 +77,7 @@ mapped_kernel_page_is_present (unsigned 
 	return pte_present(pte);
 }
 
-void
+void __kprobes
 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
 {
 	int signal = SIGSEGV, code = SEGV_MAPERR;
diff -puN arch/ia64/lib/flush.S~kprobes-exclude-functions-ia64 arch/ia64/lib/flush.S
--- linux-2.6.13-rc1-mm1/arch/ia64/lib/flush.S~kprobes-exclude-functions-ia64	2005-07-07 11:19:05.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/lib/flush.S	2005-07-07 11:20:23.000000000 +0530
@@ -12,6 +12,7 @@
 	 *	Must flush range from start to end-1 but nothing else (need to
 	 *	be careful not to touch addresses that may be unmapped).
 	 */
+	.section .kprobes.text
 GLOBAL_ENTRY(flush_icache_range)
 	.prologue
 	alloc r2=ar.pfs,2,0,0,0
diff -puN include/asm-ia64/asmmacro.h~kprobes-exclude-functions-ia64 include/asm-ia64/asmmacro.h

_
-- 

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

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

* Re: [6/6 PATCH] Kprobes : Prevent possible race conditions sparc64 changes
  2005-07-07 10:18       ` [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes Prasanna S Panchamukhi
@ 2005-07-07 10:20         ` Prasanna S Panchamukhi
  2005-07-08  2:06         ` [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes Keshavamurthy Anil S
  1 sibling, 0 replies; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-07 10:20 UTC (permalink / raw)
  To: akpm, Andi Kleen, David S. Miller, systemtap; +Cc: linux-kernel


This patch contains the sparc64 architecture specific changes to
prevent the possible race conditions.

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


---

 linux-2.6.13-rc1-mm1-prasanna/arch/sparc64/kernel/kprobes.c     |   36 +++++-----
 linux-2.6.13-rc1-mm1-prasanna/arch/sparc64/kernel/vmlinux.lds.S |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/sparc64/mm/fault.c           |    8 +-
 linux-2.6.13-rc1-mm1-prasanna/arch/sparc64/mm/init.c            |    3 
 linux-2.6.13-rc1-mm1-prasanna/arch/sparc64/mm/ultra.S           |    2 
 5 files changed, 30 insertions(+), 20 deletions(-)

diff -puN arch/sparc64/kernel/kprobes.c~kprobes-exclude-functions-sparc64 arch/sparc64/kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/arch/sparc64/kernel/kprobes.c~kprobes-exclude-functions-sparc64	2005-07-06 20:08:40.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/sparc64/kernel/kprobes.c	2005-07-06 20:08:40.000000000 +0530
@@ -8,6 +8,7 @@
 #include <linux/kprobes.h>
 #include <asm/kdebug.h>
 #include <asm/signal.h>
+#include <asm/cacheflush.h>
 
 /* We do not have hardware single-stepping on sparc64.
  * So we implement software single-stepping with breakpoint
@@ -37,31 +38,31 @@
  * - Mark that we are no longer actively in a kprobe.
  */
 
-int arch_prepare_kprobe(struct kprobe *p)
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	return 0;
 }
 
-void arch_copy_kprobe(struct kprobe *p)
+void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
 	p->ainsn.insn[0] = *p->addr;
 	p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2;
 	p->opcode = *p->addr;
 }
 
-void arch_arm_kprobe(struct kprobe *p)
+void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
 	*p->addr = BREAKPOINT_INSTRUCTION;
 	flushi(p->addr);
 }
 
-void arch_disarm_kprobe(struct kprobe *p)
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
 	*p->addr = p->opcode;
 	flushi(p->addr);
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
 }
 
@@ -111,7 +112,7 @@ static inline void prepare_singlestep(st
 	}
 }
 
-static int kprobe_handler(struct pt_regs *regs)
+static int __kprobes kprobe_handler(struct pt_regs *regs)
 {
 	struct kprobe *p;
 	void *addr = (void *) regs->tpc;
@@ -191,8 +192,9 @@ no_kprobe:
  * The original INSN location was REAL_PC, it actually
  * executed at PC and produced destination address NPC.
  */
-static unsigned long relbranch_fixup(u32 insn, unsigned long real_pc,
-				     unsigned long pc, unsigned long npc)
+static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc,
+					       unsigned long pc,
+					       unsigned long npc)
 {
 	/* Branch not taken, no mods necessary.  */
 	if (npc == pc + 0x4UL)
@@ -217,7 +219,8 @@ static unsigned long relbranch_fixup(u32
 /* If INSN is an instruction which writes it's PC location
  * into a destination register, fix that up.
  */
-static void retpc_fixup(struct pt_regs *regs, u32 insn, unsigned long real_pc)
+static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn,
+				  unsigned long real_pc)
 {
 	unsigned long *slot = NULL;
 
@@ -257,7 +260,7 @@ static void retpc_fixup(struct pt_regs *
  * This function prepares to return from the post-single-step
  * breakpoint trap.
  */
-static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
 	u32 insn = p->ainsn.insn[0];
 
@@ -315,8 +318,8 @@ static inline int kprobe_fault_handler(s
 /*
  * Wrapper routine to for handling exceptions.
  */
-int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
-			     void *data)
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
 	switch (val) {
@@ -344,7 +347,8 @@ int kprobe_exceptions_notify(struct noti
 	return NOTIFY_DONE;
 }
 
-asmlinkage void kprobe_trap(unsigned long trap_level, struct pt_regs *regs)
+asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
+				      struct pt_regs *regs)
 {
 	BUG_ON(trap_level != 0x170 && trap_level != 0x171);
 
@@ -368,7 +372,7 @@ static struct pt_regs jprobe_saved_regs;
 static struct pt_regs *jprobe_saved_regs_location;
 static struct sparc_stackf jprobe_saved_stack;
 
-int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 
@@ -390,7 +394,7 @@ int setjmp_pre_handler(struct kprobe *p,
 	return 1;
 }
 
-void jprobe_return(void)
+void __kprobes jprobe_return(void)
 {
 	preempt_enable_no_resched();
 	__asm__ __volatile__(
@@ -403,7 +407,7 @@ extern void jprobe_return_trap_instructi
 
 extern void __show_regs(struct pt_regs * regs);
 
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	u32 *addr = (u32 *) regs->tpc;
 
diff -puN arch/sparc64/kernel/vmlinux.lds.S~kprobes-exclude-functions-sparc64 arch/sparc64/kernel/vmlinux.lds.S
--- linux-2.6.13-rc1-mm1/arch/sparc64/kernel/vmlinux.lds.S~kprobes-exclude-functions-sparc64	2005-07-06 20:08:40.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/sparc64/kernel/vmlinux.lds.S	2005-07-06 20:08:40.000000000 +0530
@@ -17,6 +17,7 @@ SECTIONS
     *(.text)
     SCHED_TEXT
     LOCK_TEXT
+    KPROBES_TEXT
     *(.gnu.warning)
   } =0
   _etext = .;
diff -puN arch/sparc64/mm/fault.c~kprobes-exclude-functions-sparc64 arch/sparc64/mm/fault.c
--- linux-2.6.13-rc1-mm1/arch/sparc64/mm/fault.c~kprobes-exclude-functions-sparc64	2005-07-06 20:08:40.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/sparc64/mm/fault.c	2005-07-06 20:08:40.000000000 +0530
@@ -18,6 +18,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/kprobes.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -133,8 +134,9 @@ unsigned long __init prom_probe_memory (
 	return tally;
 }
 
-static void unhandled_fault(unsigned long address, struct task_struct *tsk,
-			    struct pt_regs *regs)
+static void __kprobes unhandled_fault(unsigned long address,
+				      struct task_struct *tsk,
+				      struct pt_regs *regs)
 {
 	if ((unsigned long) address < PAGE_SIZE) {
 		printk(KERN_ALERT "Unable to handle kernel NULL "
@@ -320,7 +322,7 @@ cannot_handle:
 	unhandled_fault (address, current, regs);
 }
 
-asmlinkage void do_sparc64_fault(struct pt_regs *regs)
+asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
 {
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
diff -puN arch/sparc64/mm/init.c~kprobes-exclude-functions-sparc64 arch/sparc64/mm/init.c
--- linux-2.6.13-rc1-mm1/arch/sparc64/mm/init.c~kprobes-exclude-functions-sparc64	2005-07-06 20:08:40.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/sparc64/mm/init.c	2005-07-06 20:08:40.000000000 +0530
@@ -19,6 +19,7 @@
 #include <linux/pagemap.h>
 #include <linux/fs.h>
 #include <linux/seq_file.h>
+#include <linux/kprobes.h>
 
 #include <asm/head.h>
 #include <asm/system.h>
@@ -239,7 +240,7 @@ out:
 	put_cpu();
 }
 
-void flush_icache_range(unsigned long start, unsigned long end)
+void __kprobes flush_icache_range(unsigned long start, unsigned long end)
 {
 	/* Cheetah has coherent I-cache. */
 	if (tlb_type == spitfire) {
diff -puN arch/sparc64/mm/ultra.S~kprobes-exclude-functions-sparc64 arch/sparc64/mm/ultra.S
--- linux-2.6.13-rc1-mm1/arch/sparc64/mm/ultra.S~kprobes-exclude-functions-sparc64	2005-07-06 20:08:40.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/sparc64/mm/ultra.S	2005-07-07 10:19:48.000000000 +0530
@@ -112,6 +112,7 @@ __spitfire_flush_tlb_mm_slow:
 #else
 #error unsupported PAGE_SIZE
 #endif
+	.section .kprobes.text
 	.align		32
 	.globl		__flush_icache_page
 __flush_icache_page:	/* %o0 = phys_page */
@@ -194,6 +195,7 @@ dflush4:stxa		%g0, [%o4] ASI_DCACHE_TAG
 	 nop
 #endif /* DCACHE_ALIASING_POSSIBLE */
 
+	.previous .text
 	.align		32
 __prefill_dtlb:
 	rdpr		%pstate, %g7

_
-- 

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

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

* Re: [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes
  2005-07-07 10:10 [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes Prasanna S Panchamukhi
  2005-07-07 10:11 ` [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes Prasanna S Panchamukhi
@ 2005-07-07 10:25 ` Andrew Morton
  2005-07-07 10:34   ` Andi Kleen
  1 sibling, 1 reply; 19+ messages in thread
From: Andrew Morton @ 2005-07-07 10:25 UTC (permalink / raw)
  To: prasanna; +Cc: ak, davem, systemtap, linux-kernel

Prasanna S Panchamukhi <prasanna@in.ibm.com> wrote:
>
> There are possible race conditions if probes are placed on routines within the
> kprobes files and routines used by the kprobes.

So...  don't do that then?  Is it likely that anyone would want to stick a
probe on the kprobe code itself?

> -kprobe_opcode_t *get_insn_slot(void)
> +kprobe_opcode_t * __kprobes get_insn_slot(void)

coding style regression...

> -int register_kprobe(struct kprobe *p)
> +static int __kprobes in_kprobes_functions(unsigned long addr)
> +{
> +	/* Linker adds these: start and end of __kprobes functions */
> +	extern char __kprobes_text_start[], __kprobes_text_end[];

There's an old unix convention that section markers (start, end, edata,
etc) are declared `int'.  For some reason we don't do that in the kernel. 
Oh well.

> +	if ((ret = in_kprobes_functions((unsigned long) p->addr)) !=0)

whitespace broke.

Some people don't like the assign-then-test-it style.

> +		return ret;
>  	if ((ret = arch_prepare_kprobe(p)) != 0) {
>  		goto rm_kprobe;
>  	}

hm, who put the unneeded braces in there?

> --- linux-2.6.13-rc1-mm1/include/linux/kprobes.h~kprobes-exclude-functions-generic	2005-07-06 18:51:16.000000000 +0530
> +++ linux-2.6.13-rc1-mm1-prasanna/include/linux/kprobes.h	2005-07-06 18:51:16.000000000 +0530
> @@ -42,6 +42,10 @@
>  #define KPROBE_REENTER		0x00000004
>  #define KPROBE_HIT_SSDONE	0x00000008
>  
> +/* Attach to insert probes on any functions which should be ignored*/
> +#define __kprobes	__attribute__((__section__(".kprobes.text")))
> +/* Is this address in the __kprobes functions? */
> +

What's that comment mean?



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

* Re: [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes
  2005-07-07 10:25 ` [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes Andrew Morton
@ 2005-07-07 10:34   ` Andi Kleen
  2005-07-07 13:01     ` Prasanna S Panchamukhi
  2005-07-07 21:20     ` Vara Prasad
  0 siblings, 2 replies; 19+ messages in thread
From: Andi Kleen @ 2005-07-07 10:34 UTC (permalink / raw)
  To: Andrew Morton; +Cc: prasanna, ak, davem, systemtap, linux-kernel

On Thu, Jul 07, 2005 at 03:25:37AM -0700, Andrew Morton wrote:
> Prasanna S Panchamukhi <prasanna@in.ibm.com> wrote:
> >
> > There are possible race conditions if probes are placed on routines within the
> > kprobes files and routines used by the kprobes.
> 
> So...  don't do that then?  Is it likely that anyone would want to stick a
> probe on the kprobe code itself?

iirc one goal of systemtap (which uses kprobes) is to be provable
safe so that an user cannot crash the kernel by adding probes. Basically
to make it possible to use this on production systems safely. I have my
doubts they will fully reach it, but at least it's a nice goal.

> > -int register_kprobe(struct kprobe *p)
> > +static int __kprobes in_kprobes_functions(unsigned long addr)
> > +{
> > +	/* Linker adds these: start and end of __kprobes functions */
> > +	extern char __kprobes_text_start[], __kprobes_text_end[];
> 
> There's an old unix convention that section markers (start, end, edata,
> etc) are declared `int'.  For some reason we don't do that in the kernel. 
> Oh well.

The Linux convention is to put it into asm-generic/sections.h at least.

-Andi

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

* Re: [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes
  2005-07-07 10:34   ` Andi Kleen
@ 2005-07-07 13:01     ` Prasanna S Panchamukhi
  2005-07-08 11:02       ` Prasanna S Panchamukhi
  2005-07-07 21:20     ` Vara Prasad
  1 sibling, 1 reply; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-07 13:01 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Andrew Morton, davem, systemtap, linux-kernel

Hi Andrew,

I have modified the patch as per your comments.

As Andi mentioned, this patch set provides safety for kprobes and avoids
possible kernel crash  I think this safety feature will helps tools like 
systemtap which are uses kprobes mechanism.
Also kprobes cleanup patch to cleanup the codingstyle is on the way.

Please let me know if you have any issues.

Thanks
Prasanna


There are possible race conditions if probes are placed on routines within the
kprobes files and routines used by the kprobes. For example if you put probe on
get_kprobe() routines, the system can hang while inserting probes on
any routine such as do_fork(). Because while inserting probes on do_fork(),
register_kprobes() routine grabs the kprobes spin lock and executes get_kprobe()
routine and to handle probe of get_kprobe(), kprobes_handler() gets executed 
and tries to grab kprobes spin lock, and spins forever. This patch avoids such
possible race conditions by preventing probes on routines within the kprobes
file and routines used by kprobes.

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


---

 linux-2.6.13-rc1-mm1-prasanna/include/asm-generic/sections.h    |    1 
 linux-2.6.13-rc1-mm1-prasanna/include/asm-generic/vmlinux.lds.h |    5 
 linux-2.6.13-rc1-mm1-prasanna/include/linux/kprobes.h           |    3 
 linux-2.6.13-rc1-mm1-prasanna/kernel/kprobes.c                  |   72 +++++-----
 4 files changed, 52 insertions(+), 29 deletions(-)

diff -puN kernel/kprobes.c~kprobes-exclude-functions-generic kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/kernel/kprobes.c~kprobes-exclude-functions-generic	2005-07-07 17:13:26.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/kernel/kprobes.c	2005-07-07 17:18:44.000000000 +0530
@@ -37,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleloader.h>
+#include <asm-generic/sections.h>
 #include <asm/cacheflush.h>
 #include <asm/errno.h>
 #include <asm/kdebug.h>
@@ -72,7 +73,7 @@ static struct hlist_head kprobe_insn_pag
  * get_insn_slot() - Find a slot on an executable page for an instruction.
  * We allocate an executable page if there's no room on existing ones.
  */
-kprobe_opcode_t *get_insn_slot(void)
+kprobe_opcode_t __kprobes *get_insn_slot(void)
 {
 	struct kprobe_insn_page *kip;
 	struct hlist_node *pos;
@@ -117,7 +118,7 @@ kprobe_opcode_t *get_insn_slot(void)
 	return kip->insns;
 }
 
-void free_insn_slot(kprobe_opcode_t *slot)
+void __kprobes free_insn_slot(kprobe_opcode_t *slot)
 {
 	struct kprobe_insn_page *kip;
 	struct hlist_node *pos;
@@ -152,20 +153,20 @@ void free_insn_slot(kprobe_opcode_t *slo
 }
 
 /* Locks kprobe: irqs must be disabled */
-void lock_kprobes(void)
+void __kprobes lock_kprobes(void)
 {
 	spin_lock(&kprobe_lock);
 	kprobe_cpu = smp_processor_id();
 }
 
-void unlock_kprobes(void)
+void __kprobes unlock_kprobes(void)
 {
 	kprobe_cpu = NR_CPUS;
 	spin_unlock(&kprobe_lock);
 }
 
 /* You have to be holding the kprobe_lock */
-struct kprobe *get_kprobe(void *addr)
+struct kprobe __kprobes *get_kprobe(void *addr)
 {
 	struct hlist_head *head;
 	struct hlist_node *node;
@@ -183,7 +184,7 @@ struct kprobe *get_kprobe(void *addr)
  * Aggregate handlers for multiple kprobes support - these handlers
  * take care of invoking the individual kprobe handlers on p->list
  */
-static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kprobe *kp;
 
@@ -198,8 +199,8 @@ static int aggr_pre_handler(struct kprob
 	return 0;
 }
 
-static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
-			      unsigned long flags)
+static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
+					unsigned long flags)
 {
 	struct kprobe *kp;
 
@@ -213,8 +214,8 @@ static void aggr_post_handler(struct kpr
 	return;
 }
 
-static int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
-			      int trapnr)
+static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
+					int trapnr)
 {
 	/*
 	 * if we faulted "during" the execution of a user specified
@@ -227,7 +228,7 @@ static int aggr_fault_handler(struct kpr
 	return 0;
 }
 
-static int aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kprobe *kp = curr_kprobe;
 	if (curr_kprobe && kp->break_handler) {
@@ -240,7 +241,7 @@ static int aggr_break_handler(struct kpr
 	return 0;
 }
 
-struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp)
+struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
 {
 	struct hlist_node *node;
 	struct kretprobe_instance *ri;
@@ -249,7 +250,8 @@ struct kretprobe_instance *get_free_rp_i
 	return NULL;
 }
 
-static struct kretprobe_instance *get_used_rp_inst(struct kretprobe *rp)
+static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
+							      *rp)
 {
 	struct hlist_node *node;
 	struct kretprobe_instance *ri;
@@ -258,7 +260,7 @@ static struct kretprobe_instance *get_us
 	return NULL;
 }
 
-void add_rp_inst(struct kretprobe_instance *ri)
+void __kprobes add_rp_inst(struct kretprobe_instance *ri)
 {
 	/*
 	 * Remove rp inst off the free list -
@@ -276,7 +278,7 @@ void add_rp_inst(struct kretprobe_instan
 	hlist_add_head(&ri->uflist, &ri->rp->used_instances);
 }
 
-void recycle_rp_inst(struct kretprobe_instance *ri)
+void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
 {
 	/* remove rp inst off the rprobe_inst_table */
 	hlist_del(&ri->hlist);
@@ -291,7 +293,7 @@ void recycle_rp_inst(struct kretprobe_in
 		kfree(ri);
 }
 
-struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk)
+struct hlist_head __kprobes *kretprobe_inst_table_head(struct task_struct *tsk)
 {
 	return &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)];
 }
@@ -302,7 +304,7 @@ struct hlist_head * kretprobe_inst_table
  * instances associated with this task. These left over instances represent
  * probed functions that have been called but will never return.
  */
-void kprobe_flush_task(struct task_struct *tk)
+void __kprobes kprobe_flush_task(struct task_struct *tk)
 {
         struct kretprobe_instance *ri;
         struct hlist_head *head;
@@ -322,7 +324,8 @@ void kprobe_flush_task(struct task_struc
  * This kprobe pre_handler is registered with every kretprobe. When probe
  * hits it will set up the return probe.
  */
-static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes pre_handler_kretprobe(struct kprobe *p,
+					   struct pt_regs *regs)
 {
 	struct kretprobe *rp = container_of(p, struct kretprobe, kp);
 
@@ -353,7 +356,7 @@ static inline void copy_kprobe(struct kp
 * Add the new probe to old_p->list. Fail if this is the
 * second jprobe at the address - two jprobes can't coexist
 */
-static int add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
+static int __kprobes add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
 {
         struct kprobe *kp;
 
@@ -395,7 +398,8 @@ static inline void add_aggr_kprobe(struc
  * the intricacies
  * TODO: Move kcalloc outside the spinlock
  */
-static int register_aggr_kprobe(struct kprobe *old_p, struct kprobe *p)
+static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
+					  struct kprobe *p)
 {
 	int ret = 0;
 	struct kprobe *ap;
@@ -434,15 +438,25 @@ static inline void cleanup_aggr_kprobe(s
 		spin_unlock_irqrestore(&kprobe_lock, flags);
 }
 
-int register_kprobe(struct kprobe *p)
+static int __kprobes in_kprobes_functions(unsigned long addr)
+{
+	if (addr >= (unsigned long)__kprobes_text_start
+		&& addr < (unsigned long)__kprobes_text_end)
+		return -EINVAL;
+	return 0;
+}
+
+int __kprobes register_kprobe(struct kprobe *p)
 {
 	int ret = 0;
 	unsigned long flags = 0;
 	struct kprobe *old_p;
 
-	if ((ret = arch_prepare_kprobe(p)) != 0) {
+	if ((ret = in_kprobes_functions((unsigned long) p->addr)) != 0)
+		return ret;
+	if ((ret = arch_prepare_kprobe(p)) != 0)
 		goto rm_kprobe;
-	}
+
 	spin_lock_irqsave(&kprobe_lock, flags);
 	old_p = get_kprobe(p->addr);
 	p->nmissed = 0;
@@ -466,7 +480,7 @@ rm_kprobe:
 	return ret;
 }
 
-void unregister_kprobe(struct kprobe *p)
+void __kprobes unregister_kprobe(struct kprobe *p)
 {
 	unsigned long flags;
 	struct kprobe *old_p;
@@ -487,7 +501,7 @@ static struct notifier_block kprobe_exce
 	.priority = 0x7fffffff /* we need to notified first */
 };
 
-int register_jprobe(struct jprobe *jp)
+int __kprobes register_jprobe(struct jprobe *jp)
 {
 	/* Todo: Verify probepoint is a function entry point */
 	jp->kp.pre_handler = setjmp_pre_handler;
@@ -496,14 +510,14 @@ int register_jprobe(struct jprobe *jp)
 	return register_kprobe(&jp->kp);
 }
 
-void unregister_jprobe(struct jprobe *jp)
+void __kprobes unregister_jprobe(struct jprobe *jp)
 {
 	unregister_kprobe(&jp->kp);
 }
 
 #ifdef ARCH_SUPPORTS_KRETPROBES
 
-int register_kretprobe(struct kretprobe *rp)
+int __kprobes register_kretprobe(struct kretprobe *rp)
 {
 	int ret = 0;
 	struct kretprobe_instance *inst;
@@ -540,14 +554,14 @@ int register_kretprobe(struct kretprobe 
 
 #else /* ARCH_SUPPORTS_KRETPROBES */
 
-int register_kretprobe(struct kretprobe *rp)
+int __kprobes register_kretprobe(struct kretprobe *rp)
 {
 	return -ENOSYS;
 }
 
 #endif /* ARCH_SUPPORTS_KRETPROBES */
 
-void unregister_kretprobe(struct kretprobe *rp)
+void __kprobes unregister_kretprobe(struct kretprobe *rp)
 {
 	unsigned long flags;
 	struct kretprobe_instance *ri;
diff -puN include/linux/kprobes.h~kprobes-exclude-functions-generic include/linux/kprobes.h
--- linux-2.6.13-rc1-mm1/include/linux/kprobes.h~kprobes-exclude-functions-generic	2005-07-07 17:13:26.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/include/linux/kprobes.h	2005-07-07 17:13:26.000000000 +0530
@@ -42,6 +42,9 @@
 #define KPROBE_REENTER		0x00000004
 #define KPROBE_HIT_SSDONE	0x00000008
 
+/* Attach to insert probes on any functions which should be ignored*/
+#define __kprobes	__attribute__((__section__(".kprobes.text")))
+
 struct kprobe;
 struct pt_regs;
 struct kretprobe;
diff -puN include/asm-generic/vmlinux.lds.h~kprobes-exclude-functions-generic include/asm-generic/vmlinux.lds.h
--- linux-2.6.13-rc1-mm1/include/asm-generic/vmlinux.lds.h~kprobes-exclude-functions-generic	2005-07-07 17:13:26.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/include/asm-generic/vmlinux.lds.h	2005-07-07 17:13:26.000000000 +0530
@@ -95,3 +95,8 @@
 		VMLINUX_SYMBOL(__lock_text_start) = .;			\
 		*(.spinlock.text)					\
 		VMLINUX_SYMBOL(__lock_text_end) = .;
+
+#define KPROBES_TEXT							\
+		VMLINUX_SYMBOL(__kprobes_text_start) = .;			\
+		*(.kprobes.text)					\
+		VMLINUX_SYMBOL(__kprobes_text_end) = .;
diff -puN include/asm-generic/sections.h~kprobes-exclude-functions-generic include/asm-generic/sections.h
--- linux-2.6.13-rc1-mm1/include/asm-generic/sections.h~kprobes-exclude-functions-generic	2005-07-07 17:13:26.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/include/asm-generic/sections.h	2005-07-07 17:13:26.000000000 +0530
@@ -11,5 +11,6 @@ extern char _sinittext[], _einittext[];
 extern char _sextratext[] __attribute__((weak));
 extern char _eextratext[] __attribute__((weak));
 extern char _end[];
+extern char __kprobes_text_start[], __kprobes_text_end[];
 
 #endif /* _ASM_GENERIC_SECTIONS_H_ */

_
-- 

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

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

* Re: [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes
  2005-07-07 10:11 ` [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes Prasanna S Panchamukhi
  2005-07-07 10:14   ` [3/6 PATCH] Kprobes : Prevent possible race conditions x86_64 changes Prasanna S Panchamukhi
@ 2005-07-07 13:19   ` Andi Kleen
  2005-07-08 11:05     ` Prasanna S Panchamukhi
  1 sibling, 1 reply; 19+ messages in thread
From: Andi Kleen @ 2005-07-07 13:19 UTC (permalink / raw)
  To: Prasanna S Panchamukhi
  Cc: akpm, Andi Kleen, David S. Miller, systemtap, linux-kernel

> -fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code)
> +fastcall void __kprobes do_page_fault(struct pt_regs *regs,
> +				      unsigned long error_code)

That's not enough. You would need to change entry.S too.

Same on x86-64. And how about general protection fault?

-Andi

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

* Re: [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes
  2005-07-07 10:34   ` Andi Kleen
  2005-07-07 13:01     ` Prasanna S Panchamukhi
@ 2005-07-07 21:20     ` Vara Prasad
  1 sibling, 0 replies; 19+ messages in thread
From: Vara Prasad @ 2005-07-07 21:20 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Andrew Morton, prasanna, davem, systemtap, linux-kernel

Andi Kleen wrote:

>On Thu, Jul 07, 2005 at 03:25:37AM -0700, Andrew Morton wrote:
>  
>
>>Prasanna S Panchamukhi <prasanna@in.ibm.com> wrote:
>>    
>>
>>>There are possible race conditions if probes are placed on routines within the
>>>kprobes files and routines used by the kprobes.
>>>      
>>>
>>So...  don't do that then?  Is it likely that anyone would want to stick a
>>probe on the kprobe code itself?
>>    
>>
>
>iirc one goal of systemtap (which uses kprobes) is to be provable
>safe so that an user cannot crash the kernel by adding probes. Basically
>to make it possible to use this on production systems safely. I have my
>doubts they will fully reach it, but at least it's a nice goal.
>  
>
Yes, you are right it is a lofty goal but we feel we can achieve this 
with safety features built into the system. To facilitate this we are 
providing two modes safe and guru. In safe mode we are trying to limit 
the user to do limited yet useful operations so that they don't 
compromise the integrity of the system. Guru mode is meant for power 
users where we expect the users to know what they are doing hence they 
can do more intrusive operations. Another feature we are doing is coming 
up with a library of routines for common needs. Users can activate these 
routines with a simple scripting language so that they don't write their 
own kernel modules, this limits their ability to compromise the 
integrity of the system. We expect users to use this method 
predominantly in the safe mode.

>  
>
>>>-int register_kprobe(struct kprobe *p)
>>>+static int __kprobes in_kprobes_functions(unsigned long addr)
>>>+{
>>>+	/* Linker adds these: start and end of __kprobes functions */
>>>+	extern char __kprobes_text_start[], __kprobes_text_end[];
>>>      
>>>
>>There's an old unix convention that section markers (start, end, edata,
>>etc) are declared `int'.  For some reason we don't do that in the kernel. 
>>Oh well.
>>    
>>
>
>The Linux convention is to put it into asm-generic/sections.h at least.
>
>-Andi
>
>  
>



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

* Re: [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes
  2005-07-07 10:18       ` [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes Prasanna S Panchamukhi
  2005-07-07 10:20         ` [6/6 PATCH] Kprobes : Prevent possible race conditions sparc64 changes Prasanna S Panchamukhi
@ 2005-07-08  2:06         ` Keshavamurthy Anil S
  2005-07-08 11:10           ` Prasanna S Panchamukhi
  1 sibling, 1 reply; 19+ messages in thread
From: Keshavamurthy Anil S @ 2005-07-08  2:06 UTC (permalink / raw)
  To: Prasanna S Panchamukhi
  Cc: akpm, Andi Kleen, David S. Miller, systemtap, linux-kernel,
	anil.s.keshavamurthy

On Thu, Jul 07, 2005 at 03:18:33AM -0700, Prasanna S Panchamukhi wrote:
> 
>    This patch contains the ia64 architecture specific changes to
>    prevent the possible race conditions.
> 
>    Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>
> 
>    ---
> 
>     linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/kprobes.c      |    57
>    ++++++-----
>     linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/traps.c       |    5
>     linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/vmlinux.lds.S |    1
>     linux-2.6.13-rc1-mm1-prasanna/arch/ia64/lib/flush.S          |    1
>     linux-2.6.13-rc1-mm1-prasanna/arch/ia64/mm/fault.c           |    3
>     5 files changed, 40 insertions(+), 27 deletions(-)

Prasanna,
	You have missed one jprobe specific file
i.e arch/ia64/kernel/jprobe.S. I guess you need to patch this
file in the same way as you have done for flush.S, i,e by adding
.section .kprobes.text

Thanks,
Anil


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

* Re: [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes
  2005-07-07 13:01     ` Prasanna S Panchamukhi
@ 2005-07-08 11:02       ` Prasanna S Panchamukhi
  0 siblings, 0 replies; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-08 11:02 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Andrew Morton, davem, systemtap, linux-kernel

Hi Andrew,

I have modified the patches as per your's and Andi's comments.
Also modified entry.S for i386 and x86_64 architecture, to move
few exception handlers page fault, general protection, int3, debug
to .kprobes.text section. Also ia64 specific patch contains more
routines from jprobes.S file as per Anil's comment.

Please let me know if you have any issues.

Thanks
Prasanna


There are possible race conditions if probes are placed on routines within the
kprobes files and routines used by the kprobes. For example if you put probe on
get_kprobe() routines, the system can hang while inserting probes on
any routine such as do_fork(). Because while inserting probes on do_fork(),
register_kprobes() routine grabs the kprobes spin lock and executes get_kprobe()
routine and to handle probe of get_kprobe(), kprobes_handler() gets executed 
and tries to grab kprobes spin lock, and spins forever. This patch avoids such
possible race conditions by preventing probes on routines within the kprobes
file and routines used by kprobes.

I have modified the patches as per Andi Kleen's suggestion to move kprobes
routines and other routines used by kprobes to a seperate section .kprobes.text.
Also moved page fault and exception handlers, general protection fault to 
.kprobes.text section.
These patches have been tested on i386, x86_64 and ppc64 architectures,
also compiled on ia64 and sparc64 architectures.

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


---

 linux-2.6.13-rc1-mm1-prasanna/include/asm-generic/sections.h    |    1 
 linux-2.6.13-rc1-mm1-prasanna/include/asm-generic/vmlinux.lds.h |    5 
 linux-2.6.13-rc1-mm1-prasanna/include/linux/kprobes.h           |    3 
 linux-2.6.13-rc1-mm1-prasanna/include/linux/linkage.h           |    7 
 linux-2.6.13-rc1-mm1-prasanna/kernel/kprobes.c                  |   72 +++++-----
 5 files changed, 59 insertions(+), 29 deletions(-)

diff -puN kernel/kprobes.c~kprobes-exclude-functions-generic kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/kernel/kprobes.c~kprobes-exclude-functions-generic	2005-07-08 14:05:14.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/kernel/kprobes.c	2005-07-08 14:05:14.000000000 +0530
@@ -37,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleloader.h>
+#include <asm-generic/sections.h>
 #include <asm/cacheflush.h>
 #include <asm/errno.h>
 #include <asm/kdebug.h>
@@ -72,7 +73,7 @@ static struct hlist_head kprobe_insn_pag
  * get_insn_slot() - Find a slot on an executable page for an instruction.
  * We allocate an executable page if there's no room on existing ones.
  */
-kprobe_opcode_t *get_insn_slot(void)
+kprobe_opcode_t __kprobes *get_insn_slot(void)
 {
 	struct kprobe_insn_page *kip;
 	struct hlist_node *pos;
@@ -117,7 +118,7 @@ kprobe_opcode_t *get_insn_slot(void)
 	return kip->insns;
 }
 
-void free_insn_slot(kprobe_opcode_t *slot)
+void __kprobes free_insn_slot(kprobe_opcode_t *slot)
 {
 	struct kprobe_insn_page *kip;
 	struct hlist_node *pos;
@@ -152,20 +153,20 @@ void free_insn_slot(kprobe_opcode_t *slo
 }
 
 /* Locks kprobe: irqs must be disabled */
-void lock_kprobes(void)
+void __kprobes lock_kprobes(void)
 {
 	spin_lock(&kprobe_lock);
 	kprobe_cpu = smp_processor_id();
 }
 
-void unlock_kprobes(void)
+void __kprobes unlock_kprobes(void)
 {
 	kprobe_cpu = NR_CPUS;
 	spin_unlock(&kprobe_lock);
 }
 
 /* You have to be holding the kprobe_lock */
-struct kprobe *get_kprobe(void *addr)
+struct kprobe __kprobes *get_kprobe(void *addr)
 {
 	struct hlist_head *head;
 	struct hlist_node *node;
@@ -183,7 +184,7 @@ struct kprobe *get_kprobe(void *addr)
  * Aggregate handlers for multiple kprobes support - these handlers
  * take care of invoking the individual kprobe handlers on p->list
  */
-static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kprobe *kp;
 
@@ -198,8 +199,8 @@ static int aggr_pre_handler(struct kprob
 	return 0;
 }
 
-static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
-			      unsigned long flags)
+static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
+					unsigned long flags)
 {
 	struct kprobe *kp;
 
@@ -213,8 +214,8 @@ static void aggr_post_handler(struct kpr
 	return;
 }
 
-static int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
-			      int trapnr)
+static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
+					int trapnr)
 {
 	/*
 	 * if we faulted "during" the execution of a user specified
@@ -227,7 +228,7 @@ static int aggr_fault_handler(struct kpr
 	return 0;
 }
 
-static int aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kprobe *kp = curr_kprobe;
 	if (curr_kprobe && kp->break_handler) {
@@ -240,7 +241,7 @@ static int aggr_break_handler(struct kpr
 	return 0;
 }
 
-struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp)
+struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
 {
 	struct hlist_node *node;
 	struct kretprobe_instance *ri;
@@ -249,7 +250,8 @@ struct kretprobe_instance *get_free_rp_i
 	return NULL;
 }
 
-static struct kretprobe_instance *get_used_rp_inst(struct kretprobe *rp)
+static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
+							      *rp)
 {
 	struct hlist_node *node;
 	struct kretprobe_instance *ri;
@@ -258,7 +260,7 @@ static struct kretprobe_instance *get_us
 	return NULL;
 }
 
-void add_rp_inst(struct kretprobe_instance *ri)
+void __kprobes add_rp_inst(struct kretprobe_instance *ri)
 {
 	/*
 	 * Remove rp inst off the free list -
@@ -276,7 +278,7 @@ void add_rp_inst(struct kretprobe_instan
 	hlist_add_head(&ri->uflist, &ri->rp->used_instances);
 }
 
-void recycle_rp_inst(struct kretprobe_instance *ri)
+void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
 {
 	/* remove rp inst off the rprobe_inst_table */
 	hlist_del(&ri->hlist);
@@ -291,7 +293,7 @@ void recycle_rp_inst(struct kretprobe_in
 		kfree(ri);
 }
 
-struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk)
+struct hlist_head __kprobes *kretprobe_inst_table_head(struct task_struct *tsk)
 {
 	return &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)];
 }
@@ -302,7 +304,7 @@ struct hlist_head * kretprobe_inst_table
  * instances associated with this task. These left over instances represent
  * probed functions that have been called but will never return.
  */
-void kprobe_flush_task(struct task_struct *tk)
+void __kprobes kprobe_flush_task(struct task_struct *tk)
 {
         struct kretprobe_instance *ri;
         struct hlist_head *head;
@@ -322,7 +324,8 @@ void kprobe_flush_task(struct task_struc
  * This kprobe pre_handler is registered with every kretprobe. When probe
  * hits it will set up the return probe.
  */
-static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes pre_handler_kretprobe(struct kprobe *p,
+					   struct pt_regs *regs)
 {
 	struct kretprobe *rp = container_of(p, struct kretprobe, kp);
 
@@ -353,7 +356,7 @@ static inline void copy_kprobe(struct kp
 * Add the new probe to old_p->list. Fail if this is the
 * second jprobe at the address - two jprobes can't coexist
 */
-static int add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
+static int __kprobes add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
 {
         struct kprobe *kp;
 
@@ -395,7 +398,8 @@ static inline void add_aggr_kprobe(struc
  * the intricacies
  * TODO: Move kcalloc outside the spinlock
  */
-static int register_aggr_kprobe(struct kprobe *old_p, struct kprobe *p)
+static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
+					  struct kprobe *p)
 {
 	int ret = 0;
 	struct kprobe *ap;
@@ -434,15 +438,25 @@ static inline void cleanup_aggr_kprobe(s
 		spin_unlock_irqrestore(&kprobe_lock, flags);
 }
 
-int register_kprobe(struct kprobe *p)
+static int __kprobes in_kprobes_functions(unsigned long addr)
+{
+	if (addr >= (unsigned long)__kprobes_text_start
+		&& addr < (unsigned long)__kprobes_text_end)
+		return -EINVAL;
+	return 0;
+}
+
+int __kprobes register_kprobe(struct kprobe *p)
 {
 	int ret = 0;
 	unsigned long flags = 0;
 	struct kprobe *old_p;
 
-	if ((ret = arch_prepare_kprobe(p)) != 0) {
+	if ((ret = in_kprobes_functions((unsigned long) p->addr)) != 0)
+		return ret;
+	if ((ret = arch_prepare_kprobe(p)) != 0)
 		goto rm_kprobe;
-	}
+
 	spin_lock_irqsave(&kprobe_lock, flags);
 	old_p = get_kprobe(p->addr);
 	p->nmissed = 0;
@@ -466,7 +480,7 @@ rm_kprobe:
 	return ret;
 }
 
-void unregister_kprobe(struct kprobe *p)
+void __kprobes unregister_kprobe(struct kprobe *p)
 {
 	unsigned long flags;
 	struct kprobe *old_p;
@@ -487,7 +501,7 @@ static struct notifier_block kprobe_exce
 	.priority = 0x7fffffff /* we need to notified first */
 };
 
-int register_jprobe(struct jprobe *jp)
+int __kprobes register_jprobe(struct jprobe *jp)
 {
 	/* Todo: Verify probepoint is a function entry point */
 	jp->kp.pre_handler = setjmp_pre_handler;
@@ -496,14 +510,14 @@ int register_jprobe(struct jprobe *jp)
 	return register_kprobe(&jp->kp);
 }
 
-void unregister_jprobe(struct jprobe *jp)
+void __kprobes unregister_jprobe(struct jprobe *jp)
 {
 	unregister_kprobe(&jp->kp);
 }
 
 #ifdef ARCH_SUPPORTS_KRETPROBES
 
-int register_kretprobe(struct kretprobe *rp)
+int __kprobes register_kretprobe(struct kretprobe *rp)
 {
 	int ret = 0;
 	struct kretprobe_instance *inst;
@@ -540,14 +554,14 @@ int register_kretprobe(struct kretprobe 
 
 #else /* ARCH_SUPPORTS_KRETPROBES */
 
-int register_kretprobe(struct kretprobe *rp)
+int __kprobes register_kretprobe(struct kretprobe *rp)
 {
 	return -ENOSYS;
 }
 
 #endif /* ARCH_SUPPORTS_KRETPROBES */
 
-void unregister_kretprobe(struct kretprobe *rp)
+void __kprobes unregister_kretprobe(struct kretprobe *rp)
 {
 	unsigned long flags;
 	struct kretprobe_instance *ri;
diff -puN include/linux/kprobes.h~kprobes-exclude-functions-generic include/linux/kprobes.h
--- linux-2.6.13-rc1-mm1/include/linux/kprobes.h~kprobes-exclude-functions-generic	2005-07-08 14:05:14.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/include/linux/kprobes.h	2005-07-08 14:05:14.000000000 +0530
@@ -42,6 +42,9 @@
 #define KPROBE_REENTER		0x00000004
 #define KPROBE_HIT_SSDONE	0x00000008
 
+/* Attach to insert probes on any functions which should be ignored*/
+#define __kprobes	__attribute__((__section__(".kprobes.text")))
+
 struct kprobe;
 struct pt_regs;
 struct kretprobe;
diff -puN include/asm-generic/vmlinux.lds.h~kprobes-exclude-functions-generic include/asm-generic/vmlinux.lds.h
--- linux-2.6.13-rc1-mm1/include/asm-generic/vmlinux.lds.h~kprobes-exclude-functions-generic	2005-07-08 14:05:14.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/include/asm-generic/vmlinux.lds.h	2005-07-08 14:05:14.000000000 +0530
@@ -95,3 +95,8 @@
 		VMLINUX_SYMBOL(__lock_text_start) = .;			\
 		*(.spinlock.text)					\
 		VMLINUX_SYMBOL(__lock_text_end) = .;
+
+#define KPROBES_TEXT							\
+		VMLINUX_SYMBOL(__kprobes_text_start) = .;			\
+		*(.kprobes.text)					\
+		VMLINUX_SYMBOL(__kprobes_text_end) = .;
diff -puN include/asm-generic/sections.h~kprobes-exclude-functions-generic include/asm-generic/sections.h
--- linux-2.6.13-rc1-mm1/include/asm-generic/sections.h~kprobes-exclude-functions-generic	2005-07-08 14:05:14.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/include/asm-generic/sections.h	2005-07-08 14:05:14.000000000 +0530
@@ -11,5 +11,6 @@ extern char _sinittext[], _einittext[];
 extern char _sextratext[] __attribute__((weak));
 extern char _eextratext[] __attribute__((weak));
 extern char _end[];
+extern char __kprobes_text_start[], __kprobes_text_end[];
 
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
diff -puN arch/i386/kernel/entry.S~kprobes-exclude-functions-generic arch/i386/kernel/entry.S
diff -puN include/linux/linkage.h~kprobes-exclude-functions-generic include/linux/linkage.h
--- linux-2.6.13-rc1-mm1/include/linux/linkage.h~kprobes-exclude-functions-generic	2005-07-08 14:05:14.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/include/linux/linkage.h	2005-07-08 14:05:27.000000000 +0530
@@ -33,6 +33,13 @@
   ALIGN; \
   name:
 
+#define KPROBE_ENTRY(name) \
+  .section .kprobes.text, "ax"; \
+  .globl name; \
+  ALIGN; \
+  name:
+
+
 #endif
 
 #define NORET_TYPE    /**/

_
-- 

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

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

* Re: [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes
  2005-07-07 13:19   ` [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes Andi Kleen
@ 2005-07-08 11:05     ` Prasanna S Panchamukhi
  0 siblings, 0 replies; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-08 11:05 UTC (permalink / raw)
  To: Andi Kleen; +Cc: akpm, David S. Miller, systemtap, linux-kernel

Hi Andi,

I have updated the patch as per your comments to move int3,debug, page_fault,
general_protection routines to .kprobes.text section.

Please let me know if you any issues.

Thanks
Prasanna


This patch contains the i386 architecture specific changes to
prevent the possible race conditions.

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


---

 linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/entry.S       |   13 +++-
 linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/kprobes.c     |   29 +++++------
 linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/traps.c       |   12 ++--
 linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/vmlinux.lds.S |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/i386/mm/fault.c           |    4 +
 5 files changed, 34 insertions(+), 25 deletions(-)

diff -puN arch/i386/kernel/kprobes.c~kprobes-exclude-functions-i386 arch/i386/kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/arch/i386/kernel/kprobes.c~kprobes-exclude-functions-i386	2005-07-08 12:09:51.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/kprobes.c	2005-07-08 12:09:51.000000000 +0530
@@ -62,32 +62,32 @@ static inline int is_IF_modifier(kprobe_
 	return 0;
 }
 
-int arch_prepare_kprobe(struct kprobe *p)
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	return 0;
 }
 
-void arch_copy_kprobe(struct kprobe *p)
+void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
 	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
 	p->opcode = *p->addr;
 }
 
-void arch_arm_kprobe(struct kprobe *p)
+void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
 	*p->addr = BREAKPOINT_INSTRUCTION;
 	flush_icache_range((unsigned long) p->addr,
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_disarm_kprobe(struct kprobe *p)
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
 	*p->addr = p->opcode;
 	flush_icache_range((unsigned long) p->addr,
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
 }
 
@@ -127,7 +127,8 @@ static inline void prepare_singlestep(st
 		regs->eip = (unsigned long)&p->ainsn.insn;
 }
 
-void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+				      struct pt_regs *regs)
 {
 	unsigned long *sara = (unsigned long *)&regs->esp;
         struct kretprobe_instance *ri;
@@ -150,7 +151,7 @@ void arch_prepare_kretprobe(struct kretp
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
  * remain disabled thorough out this function.
  */
-static int kprobe_handler(struct pt_regs *regs)
+static int __kprobes kprobe_handler(struct pt_regs *regs)
 {
 	struct kprobe *p;
 	int ret = 0;
@@ -259,7 +260,7 @@ no_kprobe:
 /*
  * Called when we hit the probe point at kretprobe_trampoline
  */
-int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
@@ -338,7 +339,7 @@ int trampoline_probe_handler(struct kpro
  * that is atop the stack is the address following the copied instruction.
  * We need to make it the address following the original instruction.
  */
-static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
 	unsigned long *tos = (unsigned long *)&regs->esp;
 	unsigned long next_eip = 0;
@@ -444,8 +445,8 @@ static inline int kprobe_fault_handler(s
 /*
  * Wrapper routine to for handling exceptions.
  */
-int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
-			     void *data)
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
 	switch (val) {
@@ -473,7 +474,7 @@ int kprobe_exceptions_notify(struct noti
 	return NOTIFY_DONE;
 }
 
-int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 	unsigned long addr;
@@ -495,7 +496,7 @@ int setjmp_pre_handler(struct kprobe *p,
 	return 1;
 }
 
-void jprobe_return(void)
+void __kprobes jprobe_return(void)
 {
 	preempt_enable_no_resched();
 	asm volatile ("       xchgl   %%ebx,%%esp     \n"
@@ -506,7 +507,7 @@ void jprobe_return(void)
 		      (jprobe_saved_esp):"memory");
 }
 
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	u8 *addr = (u8 *) (regs->eip - 1);
 	unsigned long stack_addr = (unsigned long)jprobe_saved_esp;
diff -puN arch/i386/kernel/traps.c~kprobes-exclude-functions-i386 arch/i386/kernel/traps.c
--- linux-2.6.13-rc1-mm1/arch/i386/kernel/traps.c~kprobes-exclude-functions-i386	2005-07-08 12:09:51.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/traps.c	2005-07-08 12:09:51.000000000 +0530
@@ -408,8 +408,9 @@ static inline void die_if_kernel(const c
 		die(str, regs, err);
 }
 
-static void do_trap(int trapnr, int signr, char *str, int vm86,
-			   struct pt_regs * regs, long error_code, siginfo_t *info)
+static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86,
+			      struct pt_regs * regs, long error_code,
+			      siginfo_t *info)
 {
 	struct task_struct *tsk = current;
 	tsk->thread.error_code = error_code;
@@ -507,7 +508,8 @@ DO_ERROR(12, SIGBUS,  "stack segment", s
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
 DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
 
-fastcall void do_general_protection(struct pt_regs * regs, long error_code)
+fastcall void __kprobes do_general_protection(struct pt_regs * regs,
+					      long error_code)
 {
 	int cpu = get_cpu();
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
@@ -737,7 +739,7 @@ void unset_nmi_callback(void)
 EXPORT_SYMBOL_GPL(unset_nmi_callback);
 
 #ifdef CONFIG_KPROBES
-fastcall void do_int3(struct pt_regs *regs, long error_code)
+fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
 {
 	if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
 			== NOTIFY_STOP)
@@ -771,7 +773,7 @@ fastcall void do_int3(struct pt_regs *re
  * find every occurrence of the TF bit that could be saved away even
  * by user code)
  */
-fastcall void do_debug(struct pt_regs * regs, long error_code)
+fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
 {
 	unsigned int condition;
 	struct task_struct *tsk = current;
diff -puN arch/i386/kernel/vmlinux.lds.S~kprobes-exclude-functions-i386 arch/i386/kernel/vmlinux.lds.S
--- linux-2.6.13-rc1-mm1/arch/i386/kernel/vmlinux.lds.S~kprobes-exclude-functions-i386	2005-07-08 12:09:51.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/vmlinux.lds.S	2005-07-08 12:09:51.000000000 +0530
@@ -22,6 +22,7 @@ SECTIONS
 	*(.text)
 	SCHED_TEXT
 	LOCK_TEXT
+	KPROBES_TEXT
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x9090
diff -puN arch/i386/mm/fault.c~kprobes-exclude-functions-i386 arch/i386/mm/fault.c
--- linux-2.6.13-rc1-mm1/arch/i386/mm/fault.c~kprobes-exclude-functions-i386	2005-07-08 12:09:51.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/i386/mm/fault.c	2005-07-08 12:09:51.000000000 +0530
@@ -21,6 +21,7 @@
 #include <linux/vt_kern.h>		/* For unblank_screen() */
 #include <linux/highmem.h>
 #include <linux/module.h>
+#include <linux/kprobes.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -211,7 +212,8 @@ fastcall void do_invalid_op(struct pt_re
  *	bit 1 == 0 means read, 1 means write
  *	bit 2 == 0 means kernel, 1 means user-mode
  */
-fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+fastcall void __kprobes do_page_fault(struct pt_regs *regs,
+				      unsigned long error_code)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
diff -puN arch/i386/kernel/entry.S~kprobes-exclude-functions-i386 arch/i386/kernel/entry.S
--- linux-2.6.13-rc1-mm1/arch/i386/kernel/entry.S~kprobes-exclude-functions-i386	2005-07-08 12:09:51.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/i386/kernel/entry.S	2005-07-08 12:09:51.000000000 +0530
@@ -532,7 +532,7 @@ label:						\
 	pushl $__KERNEL_CS;			\
 	pushl $sysenter_past_esp
 
-ENTRY(debug)
+KPROBE_ENTRY(debug)
 	cmpl $sysenter_entry,(%esp)
 	jne debug_stack_correct
 	FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
@@ -543,7 +543,7 @@ debug_stack_correct:
 	movl %esp,%eax			# pt_regs pointer
 	call do_debug
 	jmp ret_from_exception
-
+	.previous .text
 /*
  * NMI is doubly nasty. It can happen _while_ we're handling
  * a debug fault, and the debug fault hasn't yet been able to
@@ -616,13 +616,14 @@ nmi_16bit_stack:
 	.long 1b,iret_exc
 .previous
 
-ENTRY(int3)
+KPROBE_ENTRY(int3)
 	pushl $-1			# mark this as an int
 	SAVE_ALL
 	xorl %edx,%edx		# zero error code
 	movl %esp,%eax		# pt_regs pointer
 	call do_int3
 	jmp ret_from_exception
+	.previous .text
 
 ENTRY(overflow)
 	pushl $0
@@ -656,17 +657,19 @@ ENTRY(stack_segment)
 	pushl $do_stack_segment
 	jmp error_code
 
-ENTRY(general_protection)
+KPROBE_ENTRY(general_protection)
 	pushl $do_general_protection
 	jmp error_code
+	.previous .text
 
 ENTRY(alignment_check)
 	pushl $do_alignment_check
 	jmp error_code
 
-ENTRY(page_fault)
+KPROBE_ENTRY(page_fault)
 	pushl $do_page_fault
 	jmp error_code
+	.previous .text
 
 #ifdef CONFIG_X86_MCE
 ENTRY(machine_check)

_
-- 

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

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

* Re: [3/6 PATCH] Kprobes : Prevent possible race conditions x86_64 changes
  2005-07-07 10:14   ` [3/6 PATCH] Kprobes : Prevent possible race conditions x86_64 changes Prasanna S Panchamukhi
  2005-07-07 10:16     ` [4/6 PATCH] Kprobes : Prevent possible race conditions ppc64 changes Prasanna S Panchamukhi
@ 2005-07-08 11:07     ` Prasanna S Panchamukhi
  1 sibling, 0 replies; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-08 11:07 UTC (permalink / raw)
  To: akpm, Andi Kleen, David S. Miller, systemtap; +Cc: linux-kernel

Hi Andi,

I have updated the patch as per your comments to move int3,debug, page_fault,
general_protection routines to .kprobes.text section.

Please let me know if you any issues.

Thanks
Prasanna

This patch contains the x86_64 architecture specific changes to
prevent the possible race conditions.

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


---

 linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/entry.S       |   12 ++-
 linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/kprobes.c     |   35 +++++-----
 linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/traps.c       |   14 ++--
 linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/vmlinux.lds.S |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/mm/fault.c           |    3 
 5 files changed, 38 insertions(+), 27 deletions(-)

diff -puN arch/x86_64/kernel/kprobes.c~kprobes-exclude-functions-x86_64 arch/x86_64/kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/arch/x86_64/kernel/kprobes.c~kprobes-exclude-functions-x86_64	2005-07-08 11:14:01.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/kprobes.c	2005-07-08 11:14:01.000000000 +0530
@@ -74,7 +74,7 @@ static inline int is_IF_modifier(kprobe_
 	return 0;
 }
 
-int arch_prepare_kprobe(struct kprobe *p)
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	/* insn: must be on special executable page on x86_64. */
 	up(&kprobe_mutex);
@@ -189,7 +189,7 @@ static inline s32 *is_riprel(u8 *insn)
 	return NULL;
 }
 
-void arch_copy_kprobe(struct kprobe *p)
+void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
 	s32 *ripdisp;
 	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
@@ -215,21 +215,21 @@ void arch_copy_kprobe(struct kprobe *p)
 	p->opcode = *p->addr;
 }
 
-void arch_arm_kprobe(struct kprobe *p)
+void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
 	*p->addr = BREAKPOINT_INSTRUCTION;
 	flush_icache_range((unsigned long) p->addr,
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_disarm_kprobe(struct kprobe *p)
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
 	*p->addr = p->opcode;
 	flush_icache_range((unsigned long) p->addr,
 			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
 	up(&kprobe_mutex);
 	free_insn_slot(p->ainsn.insn);
@@ -261,7 +261,7 @@ static inline void set_current_kprobe(st
 		kprobe_saved_rflags &= ~IF_MASK;
 }
 
-static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
 	regs->eflags |= TF_MASK;
 	regs->eflags &= ~IF_MASK;
@@ -272,7 +272,8 @@ static void prepare_singlestep(struct kp
 		regs->rip = (unsigned long)p->ainsn.insn;
 }
 
-void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+				      struct pt_regs *regs)
 {
 	unsigned long *sara = (unsigned long *)regs->rsp;
         struct kretprobe_instance *ri;
@@ -295,7 +296,7 @@ void arch_prepare_kretprobe(struct kretp
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
  * remain disabled thorough out this function.
  */
-int kprobe_handler(struct pt_regs *regs)
+int __kprobes kprobe_handler(struct pt_regs *regs)
 {
 	struct kprobe *p;
 	int ret = 0;
@@ -399,7 +400,7 @@ no_kprobe:
 /*
  * Called when we hit the probe point at kretprobe_trampoline
  */
-int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
@@ -478,7 +479,7 @@ int trampoline_probe_handler(struct kpro
  * that is atop the stack is the address following the copied instruction.
  * We need to make it the address following the original instruction.
  */
-static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
 	unsigned long *tos = (unsigned long *)regs->rsp;
 	unsigned long next_rip = 0;
@@ -536,7 +537,7 @@ static void resume_execution(struct kpro
  * Interrupts are disabled on entry as trap1 is an interrupt gate and they
  * remain disabled thoroughout this function.  And we hold kprobe lock.
  */
-int post_kprobe_handler(struct pt_regs *regs)
+int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
 	if (!kprobe_running())
 		return 0;
@@ -571,7 +572,7 @@ out:
 }
 
 /* Interrupts disabled, kprobe_lock held. */
-int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
 	if (current_kprobe->fault_handler
 	    && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
@@ -590,8 +591,8 @@ int kprobe_fault_handler(struct pt_regs 
 /*
  * Wrapper routine for handling exceptions.
  */
-int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
-			     void *data)
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
 	switch (val) {
@@ -619,7 +620,7 @@ int kprobe_exceptions_notify(struct noti
 	return NOTIFY_DONE;
 }
 
-int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 	unsigned long addr;
@@ -640,7 +641,7 @@ int setjmp_pre_handler(struct kprobe *p,
 	return 1;
 }
 
-void jprobe_return(void)
+void __kprobes jprobe_return(void)
 {
 	preempt_enable_no_resched();
 	asm volatile ("       xchg   %%rbx,%%rsp     \n"
@@ -651,7 +652,7 @@ void jprobe_return(void)
 		      (jprobe_saved_rsp):"memory");
 }
 
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	u8 *addr = (u8 *) (regs->rip - 1);
 	unsigned long stack_addr = (unsigned long)jprobe_saved_rsp;
diff -puN arch/x86_64/kernel/traps.c~kprobes-exclude-functions-x86_64 arch/x86_64/kernel/traps.c
--- linux-2.6.13-rc1-mm1/arch/x86_64/kernel/traps.c~kprobes-exclude-functions-x86_64	2005-07-08 11:14:01.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/traps.c	2005-07-08 11:14:01.000000000 +0530
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/nmi.h>
+#include <linux/kprobes.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -422,8 +423,9 @@ void die_nmi(char *str, struct pt_regs *
 	do_exit(SIGSEGV);
 }
 
-static void do_trap(int trapnr, int signr, char *str, 
-			   struct pt_regs * regs, long error_code, siginfo_t *info)
+static void __kprobes do_trap(int trapnr, int signr, char *str,
+			      struct pt_regs * regs, long error_code,
+			      siginfo_t *info)
 {
 	conditional_sti(regs);
 
@@ -507,7 +509,8 @@ DO_ERROR(18, SIGSEGV, "reserved", reserv
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR( 8, SIGSEGV, "double fault", double_fault)
 
-asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
+asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
+						long error_code)
 {
 	conditional_sti(regs);
 
@@ -628,7 +631,7 @@ asmlinkage void default_do_nmi(struct pt
 		io_check_error(reason, regs);
 }
 
-asmlinkage void do_int3(struct pt_regs * regs, long error_code)
+asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code)
 {
 	if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) {
 		return;
@@ -659,7 +662,8 @@ asmlinkage struct pt_regs *sync_regs(str
 }
 
 /* runs on IST stack. */
-asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code)
+asmlinkage void __kprobes do_debug(struct pt_regs * regs,
+				   unsigned long error_code)
 {
 	unsigned long condition;
 	struct task_struct *tsk = current;
diff -puN arch/x86_64/kernel/vmlinux.lds.S~kprobes-exclude-functions-x86_64 arch/x86_64/kernel/vmlinux.lds.S
--- linux-2.6.13-rc1-mm1/arch/x86_64/kernel/vmlinux.lds.S~kprobes-exclude-functions-x86_64	2005-07-08 11:14:01.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/vmlinux.lds.S	2005-07-08 11:14:01.000000000 +0530
@@ -21,6 +21,7 @@ SECTIONS
 	*(.text)
 	SCHED_TEXT
 	LOCK_TEXT
+	KPROBES_TEXT
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x9090
diff -puN arch/x86_64/mm/fault.c~kprobes-exclude-functions-x86_64 arch/x86_64/mm/fault.c
--- linux-2.6.13-rc1-mm1/arch/x86_64/mm/fault.c~kprobes-exclude-functions-x86_64	2005-07-08 11:14:01.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/mm/fault.c	2005-07-08 11:14:01.000000000 +0530
@@ -297,7 +297,8 @@ int exception_trace = 1;
  *	bit 2 == 0 means kernel, 1 means user-mode
  *      bit 3 == 1 means fault was an instruction fetch
  */
-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
+					unsigned long error_code)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
diff -puN arch/x86_64/kernel/entry.S~kprobes-exclude-functions-x86_64 arch/x86_64/kernel/entry.S
--- linux-2.6.13-rc1-mm1/arch/x86_64/kernel/entry.S~kprobes-exclude-functions-x86_64	2005-07-08 11:14:01.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/x86_64/kernel/entry.S	2005-07-08 11:17:03.000000000 +0530
@@ -789,8 +789,9 @@ ENTRY(execve)
 	ret
 	CFI_ENDPROC
 
-ENTRY(page_fault)
+KPROBE_ENTRY(page_fault)
 	errorentry do_page_fault
+	.previous .text
 
 ENTRY(coprocessor_error)
 	zeroentry do_coprocessor_error
@@ -802,13 +803,14 @@ ENTRY(device_not_available)
 	zeroentry math_state_restore
 
 	/* runs on exception stack */
-ENTRY(debug)
+KPROBE_ENTRY(debug)
 	CFI_STARTPROC
 	pushq $0
 	CFI_ADJUST_CFA_OFFSET 8		
 	paranoidentry do_debug
 	jmp paranoid_exit
 	CFI_ENDPROC
+	.previous .text
 
 	/* runs on exception stack */	
 ENTRY(nmi)
@@ -859,8 +861,9 @@ paranoid_schedule:
 	jmp paranoid_userspace
 	CFI_ENDPROC
 
-ENTRY(int3)
+KPROBE_ENTRY(int3)
 	zeroentry do_int3	
+	.previous .text
 
 ENTRY(overflow)
 	zeroentry do_overflow
@@ -897,8 +900,9 @@ ENTRY(stack_segment)
 	jmp paranoid_exit
 	CFI_ENDPROC
 
-ENTRY(general_protection)
+KPROBE_ENTRY(general_protection)
 	errorentry do_general_protection
+	.previous .text
 
 ENTRY(alignment_check)
 	errorentry do_alignment_check

_
-- 

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

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

* Re: [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes
  2005-07-08  2:06         ` [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes Keshavamurthy Anil S
@ 2005-07-08 11:10           ` Prasanna S Panchamukhi
  2005-07-08 19:01             ` Keshavamurthy Anil S
  0 siblings, 1 reply; 19+ messages in thread
From: Prasanna S Panchamukhi @ 2005-07-08 11:10 UTC (permalink / raw)
  To: Keshavamurthy Anil S
  Cc: akpm, Andi Kleen, David S. Miller, systemtap, linux-kernel

Hi Anil,

I have updated the patch as per your comments to move routines
from jprobes.S to .kprobes.text section.

Please let me know if you any issues.

Thanks
Prasanna


This patch contains the ia64 architecture specific changes to
prevent the possible race conditions.

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


---

 include/asm-ia64/asmmacro.h                                  |    0 
 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/jprobes.S     |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/kprobes.c     |   57 ++++++-----
 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/traps.c       |    5 
 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/vmlinux.lds.S |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/lib/flush.S          |    1 
 linux-2.6.13-rc1-mm1-prasanna/arch/ia64/mm/fault.c           |    3 
 7 files changed, 41 insertions(+), 27 deletions(-)

diff -puN arch/ia64/kernel/kprobes.c~kprobes-exclude-functions-ia64 arch/ia64/kernel/kprobes.c
--- linux-2.6.13-rc1-mm1/arch/ia64/kernel/kprobes.c~kprobes-exclude-functions-ia64	2005-07-08 15:22:52.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/kprobes.c	2005-07-08 15:22:52.000000000 +0530
@@ -87,8 +87,10 @@ static enum instruction_type bundle_enco
  * is IP relative instruction and update the kprobe
  * inst flag accordingly
  */
-static void update_kprobe_inst_flag(uint template, uint  slot, uint major_opcode,
-	unsigned long kprobe_inst, struct kprobe *p)
+static void __kprobes update_kprobe_inst_flag(uint template, uint  slot,
+					      uint major_opcode,
+					      unsigned long kprobe_inst,
+					      struct kprobe *p)
 {
 	p->ainsn.inst_flag = 0;
 	p->ainsn.target_br_reg = 0;
@@ -126,8 +128,10 @@ static void update_kprobe_inst_flag(uint
  * Returns 0 if supported
  * Returns -EINVAL if unsupported
  */
-static int unsupported_inst(uint template, uint  slot, uint major_opcode,
-	unsigned long kprobe_inst, struct kprobe *p)
+static int __kprobes unsupported_inst(uint template, uint  slot,
+				      uint major_opcode,
+				      unsigned long kprobe_inst,
+				      struct kprobe *p)
 {
 	unsigned long addr = (unsigned long)p->addr;
 
@@ -168,8 +172,9 @@ static int unsupported_inst(uint templat
  * on which we are inserting kprobe is cmp instruction
  * with ctype as unc.
  */
-static uint is_cmp_ctype_unc_inst(uint template, uint slot, uint major_opcode,
-unsigned long kprobe_inst)
+static uint __kprobes is_cmp_ctype_unc_inst(uint template, uint slot,
+					    uint major_opcode,
+					    unsigned long kprobe_inst)
 {
 	cmp_inst_t cmp_inst;
 	uint ctype_unc = 0;
@@ -201,8 +206,10 @@ out:
  * In this function we override the bundle with
  * the break instruction at the given slot.
  */
-static void prepare_break_inst(uint template, uint  slot, uint major_opcode,
-	unsigned long kprobe_inst, struct kprobe *p)
+static void __kprobes prepare_break_inst(uint template, uint  slot,
+					 uint major_opcode,
+					 unsigned long kprobe_inst,
+					 struct kprobe *p)
 {
 	unsigned long break_inst = BREAK_INST;
 	bundle_t *bundle = &p->ainsn.insn.bundle;
@@ -271,7 +278,8 @@ static inline int in_ivt_functions(unsig
 		&& addr < (unsigned long)__end_ivt_text);
 }
 
-static int valid_kprobe_addr(int template, int slot, unsigned long addr)
+static int __kprobes valid_kprobe_addr(int template, int slot,
+				       unsigned long addr)
 {
 	if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) {
 		printk(KERN_WARNING "Attempting to insert unaligned kprobe "
@@ -323,7 +331,7 @@ static void kretprobe_trampoline(void)
  *    - cleanup by marking the instance as unused
  *    - long jump back to the original return address
  */
-int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kretprobe_instance *ri = NULL;
 	struct hlist_head *head;
@@ -381,7 +389,8 @@ int trampoline_probe_handler(struct kpro
         return 1;
 }
 
-void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+				      struct pt_regs *regs)
 {
 	struct kretprobe_instance *ri;
 
@@ -399,7 +408,7 @@ void arch_prepare_kretprobe(struct kretp
 	}
 }
 
-int arch_prepare_kprobe(struct kprobe *p)
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	unsigned long addr = (unsigned long) p->addr;
 	unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL);
@@ -430,7 +439,7 @@ int arch_prepare_kprobe(struct kprobe *p
 	return 0;
 }
 
-void arch_arm_kprobe(struct kprobe *p)
+void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
 	unsigned long addr = (unsigned long)p->addr;
 	unsigned long arm_addr = addr & ~0xFULL;
@@ -439,7 +448,7 @@ void arch_arm_kprobe(struct kprobe *p)
 	flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
 }
 
-void arch_disarm_kprobe(struct kprobe *p)
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
 	unsigned long addr = (unsigned long)p->addr;
 	unsigned long arm_addr = addr & ~0xFULL;
@@ -449,7 +458,7 @@ void arch_disarm_kprobe(struct kprobe *p
 	flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
 }
 
@@ -461,7 +470,7 @@ void arch_remove_kprobe(struct kprobe *p
  * to original stack address, handle the case where we need to fixup the
  * relative IP address and/or fixup branch register.
  */
-static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
   	unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL;
   	unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
@@ -528,7 +537,7 @@ turn_ss_off:
   	ia64_psr(regs)->ss = 0;
 }
 
-static void prepare_ss(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
 {
 	unsigned long bundle_addr = (unsigned long) &p->opcode.bundle;
 	unsigned long slot = (unsigned long)p->addr & 0xf;
@@ -545,7 +554,7 @@ static void prepare_ss(struct kprobe *p,
 	ia64_psr(regs)->ss = 1;
 }
 
-static int pre_kprobes_handler(struct die_args *args)
+static int __kprobes pre_kprobes_handler(struct die_args *args)
 {
 	struct kprobe *p;
 	int ret = 0;
@@ -616,7 +625,7 @@ no_kprobe:
 	return ret;
 }
 
-static int post_kprobes_handler(struct pt_regs *regs)
+static int __kprobes post_kprobes_handler(struct pt_regs *regs)
 {
 	if (!kprobe_running())
 		return 0;
@@ -641,7 +650,7 @@ out:
 	return 1;
 }
 
-static int kprobes_fault_handler(struct pt_regs *regs, int trapnr)
+static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
 {
 	if (!kprobe_running())
 		return 0;
@@ -659,8 +668,8 @@ static int kprobes_fault_handler(struct 
 	return 0;
 }
 
-int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
-			     void *data)
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
 	switch(val) {
@@ -681,7 +690,7 @@ int kprobe_exceptions_notify(struct noti
 	return NOTIFY_DONE;
 }
 
-int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 	unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
@@ -703,7 +712,7 @@ int setjmp_pre_handler(struct kprobe *p,
 	return 1;
 }
 
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	*regs = jprobe_saved_regs;
 	return 1;
diff -puN arch/ia64/kernel/traps.c~kprobes-exclude-functions-ia64 arch/ia64/kernel/traps.c
--- linux-2.6.13-rc1-mm1/arch/ia64/kernel/traps.c~kprobes-exclude-functions-ia64	2005-07-08 15:22:52.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/traps.c	2005-07-08 15:22:52.000000000 +0530
@@ -15,6 +15,7 @@
 #include <linux/vt_kern.h>		/* For unblank_screen() */
 #include <linux/module.h>       /* for EXPORT_SYMBOL */
 #include <linux/hardirq.h>
+#include <linux/kprobes.h>
 
 #include <asm/fpswa.h>
 #include <asm/ia32.h>
@@ -120,7 +121,7 @@ die_if_kernel (char *str, struct pt_regs
 }
 
 void
-ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
+__kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
 {
 	siginfo_t siginfo;
 	int sig, code;
@@ -442,7 +443,7 @@ ia64_illegal_op_fault (unsigned long ec,
 	return rv;
 }
 
-void
+void __kprobes
 ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 	    unsigned long iim, unsigned long itir, long arg5, long arg6,
 	    long arg7, struct pt_regs regs)
diff -puN arch/ia64/kernel/vmlinux.lds.S~kprobes-exclude-functions-ia64 arch/ia64/kernel/vmlinux.lds.S
--- linux-2.6.13-rc1-mm1/arch/ia64/kernel/vmlinux.lds.S~kprobes-exclude-functions-ia64	2005-07-08 15:22:52.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/vmlinux.lds.S	2005-07-08 15:22:52.000000000 +0530
@@ -48,6 +48,7 @@ SECTIONS
 	*(.text)
 	SCHED_TEXT
 	LOCK_TEXT
+	KPROBES_TEXT
 	*(.gnu.linkonce.t*)
     }
   .text2 : AT(ADDR(.text2) - LOAD_OFFSET)
diff -puN arch/ia64/mm/fault.c~kprobes-exclude-functions-ia64 arch/ia64/mm/fault.c
--- linux-2.6.13-rc1-mm1/arch/ia64/mm/fault.c~kprobes-exclude-functions-ia64	2005-07-08 15:22:52.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/mm/fault.c	2005-07-08 15:22:52.000000000 +0530
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
+#include <linux/kprobes.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -76,7 +77,7 @@ mapped_kernel_page_is_present (unsigned 
 	return pte_present(pte);
 }
 
-void
+void __kprobes
 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
 {
 	int signal = SIGSEGV, code = SEGV_MAPERR;
diff -puN arch/ia64/lib/flush.S~kprobes-exclude-functions-ia64 arch/ia64/lib/flush.S
--- linux-2.6.13-rc1-mm1/arch/ia64/lib/flush.S~kprobes-exclude-functions-ia64	2005-07-08 15:22:52.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/lib/flush.S	2005-07-08 15:22:52.000000000 +0530
@@ -12,6 +12,7 @@
 	 *	Must flush range from start to end-1 but nothing else (need to
 	 *	be careful not to touch addresses that may be unmapped).
 	 */
+	.section .kprobes.text
 GLOBAL_ENTRY(flush_icache_range)
 	.prologue
 	alloc r2=ar.pfs,2,0,0,0
diff -puN include/asm-ia64/asmmacro.h~kprobes-exclude-functions-ia64 include/asm-ia64/asmmacro.h
diff -puN arch/ia64/kernel/jprobes.S~kprobes-exclude-functions-ia64 arch/ia64/kernel/jprobes.S
--- linux-2.6.13-rc1-mm1/arch/ia64/kernel/jprobes.S~kprobes-exclude-functions-ia64	2005-07-08 15:22:52.000000000 +0530
+++ linux-2.6.13-rc1-mm1-prasanna/arch/ia64/kernel/jprobes.S	2005-07-08 15:22:52.000000000 +0530
@@ -49,6 +49,7 @@
 	/*
 	 * void jprobe_break(void)
 	 */
+	.section .kprobes.text, "ax"
 ENTRY(jprobe_break)
 	break.m 0x80300
 END(jprobe_break)

_
-- 

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

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

* Re: [4/6 PATCH] Kprobes : Prevent possible race conditions ppc64 changes
  2005-07-07 10:16     ` [4/6 PATCH] Kprobes : Prevent possible race conditions ppc64 changes Prasanna S Panchamukhi
  2005-07-07 10:18       ` [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes Prasanna S Panchamukhi
@ 2005-07-08 14:13       ` Ananth N Mavinakayanahalli
  1 sibling, 0 replies; 19+ messages in thread
From: Ananth N Mavinakayanahalli @ 2005-07-08 14:13 UTC (permalink / raw)
  To: Prasanna S Panchamukhi
  Cc: akpm, Andi Kleen, David S. Miller, systemtap, linux-kernel

On Thu, Jul 07, 2005 at 03:46:50PM +0530, Prasanna S Panchamukhi wrote:
> 
> This patch contains the ppc64 architecture specific changes to
> prevent the possible race conditions.

Prasanna,

Please cc or post this patch to linuxppc64-dev@ozlabs.org. This patch
touches files I am not sure I can comment on with authority.

Thanks,
Ananth

> 
> Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>
> 
> 
> ---
> 
>  linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/kprobes.c     |   29 +++++-----
>  linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/misc.S        |    4 -
>  linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/traps.c       |    5 +
>  linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/vmlinux.lds.S |    1 
>  linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/mm/fault.c           |    5 +
>  linux-2.6.13-rc1-mm1-prasanna/include/asm-ppc64/processor.h   |   14 ++++
>  6 files changed, 38 insertions(+), 20 deletions(-)
> 
> diff -puN arch/ppc64/kernel/kprobes.c~kprobes-exclude-functions-ppc64 arch/ppc64/kernel/kprobes.c
> --- linux-2.6.13-rc1-mm1/arch/ppc64/kernel/kprobes.c~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
> +++ linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/kprobes.c	2005-07-06 20:07:22.000000000 +0530
> @@ -44,7 +44,7 @@ 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)
> +int __kprobes arch_prepare_kprobe(struct kprobe *p)
>  {
>  	int ret = 0;
>  	kprobe_opcode_t insn = *p->addr;
> @@ -68,27 +68,27 @@ int arch_prepare_kprobe(struct kprobe *p
>  	return ret;
>  }
>  
> -void arch_copy_kprobe(struct kprobe *p)
> +void __kprobes arch_copy_kprobe(struct kprobe *p)
>  {
>  	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
>  	p->opcode = *p->addr;
>  }
>  
> -void arch_arm_kprobe(struct kprobe *p)
> +void __kprobes arch_arm_kprobe(struct kprobe *p)
>  {
>  	*p->addr = BREAKPOINT_INSTRUCTION;
>  	flush_icache_range((unsigned long) p->addr,
>  			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
>  }
>  
> -void arch_disarm_kprobe(struct kprobe *p)
> +void __kprobes arch_disarm_kprobe(struct kprobe *p)
>  {
>  	*p->addr = p->opcode;
>  	flush_icache_range((unsigned long) p->addr,
>  			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
>  }
>  
> -void arch_remove_kprobe(struct kprobe *p)
> +void __kprobes arch_remove_kprobe(struct kprobe *p)
>  {
>  	up(&kprobe_mutex);
>  	free_insn_slot(p->ainsn.insn);
> @@ -122,7 +122,8 @@ static inline void restore_previous_kpro
>  	kprobe_saved_msr = kprobe_saved_msr_prev;
>  }
>  
> -void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
> +void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
> +				      struct pt_regs *regs)
>  {
>  	struct kretprobe_instance *ri;
>  
> @@ -244,7 +245,7 @@ void kretprobe_trampoline_holder(void)
>  /*
>   * Called when the probe at kretprobe trampoline is hit
>   */
> -int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
> +int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
>  {
>          struct kretprobe_instance *ri = NULL;
>          struct hlist_head *head;
> @@ -308,7 +309,7 @@ int trampoline_probe_handler(struct kpro
>   * single-stepped a copy of the instruction.  The address of this
>   * copy is p->ainsn.insn.
>   */
> -static void resume_execution(struct kprobe *p, struct pt_regs *regs)
> +static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
>  {
>  	int ret;
>  	unsigned int insn = *p->ainsn.insn;
> @@ -373,8 +374,8 @@ static inline int kprobe_fault_handler(s
>  /*
>   * Wrapper routine to for handling exceptions.
>   */
> -int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
> -			     void *data)
> +int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
> +				       unsigned long val, void *data)
>  {
>  	struct die_args *args = (struct die_args *)data;
>  	int ret = NOTIFY_DONE;
> @@ -406,7 +407,7 @@ int kprobe_exceptions_notify(struct noti
>  	return ret;
>  }
>  
> -int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
> +int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
>  {
>  	struct jprobe *jp = container_of(p, struct jprobe, kp);
>  
> @@ -419,16 +420,16 @@ int setjmp_pre_handler(struct kprobe *p,
>  	return 1;
>  }
>  
> -void jprobe_return(void)
> +void __kprobes jprobe_return(void)
>  {
>  	asm volatile("trap" ::: "memory");
>  }
>  
> -void jprobe_return_end(void)
> +void __kprobes jprobe_return_end(void)
>  {
>  };
>  
> -int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
> +int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
>  {
>  	/*
>  	 * FIXME - we should ideally be validating that we got here 'cos
> diff -puN arch/ppc64/kernel/traps.c~kprobes-exclude-functions-ppc64 arch/ppc64/kernel/traps.c
> --- linux-2.6.13-rc1-mm1/arch/ppc64/kernel/traps.c~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
> +++ linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/traps.c	2005-07-06 20:07:22.000000000 +0530
> @@ -30,6 +30,7 @@
>  #include <linux/init.h>
>  #include <linux/module.h>
>  #include <linux/delay.h>
> +#include <linux/kprobes.h>
>  #include <asm/kdebug.h>
>  
>  #include <asm/pgtable.h>
> @@ -220,7 +221,7 @@ void instruction_breakpoint_exception(st
>  	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
>  }
>  
> -void single_step_exception(struct pt_regs *regs)
> +void __kprobes single_step_exception(struct pt_regs *regs)
>  {
>  	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
>  
> @@ -398,7 +399,7 @@ check_bug_trap(struct pt_regs *regs)
>  	return 0;
>  }
>  
> -void program_check_exception(struct pt_regs *regs)
> +void __kprobes program_check_exception(struct pt_regs *regs)
>  {
>  	if (debugger_fault_handler(regs))
>  		return;
> diff -puN arch/ppc64/kernel/vmlinux.lds.S~kprobes-exclude-functions-ppc64 arch/ppc64/kernel/vmlinux.lds.S
> --- linux-2.6.13-rc1-mm1/arch/ppc64/kernel/vmlinux.lds.S~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
> +++ linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/vmlinux.lds.S	2005-07-06 20:07:22.000000000 +0530
> @@ -15,6 +15,7 @@ SECTIONS
>  	*(.text .text.*)
>  	SCHED_TEXT
>  	LOCK_TEXT
> +	KPROBES_TEXT
>  	*(.fixup)
>  	. = ALIGN(4096);
>  	_etext = .;
> diff -puN arch/ppc64/mm/fault.c~kprobes-exclude-functions-ppc64 arch/ppc64/mm/fault.c
> --- linux-2.6.13-rc1-mm1/arch/ppc64/mm/fault.c~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
> +++ linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/mm/fault.c	2005-07-06 20:07:22.000000000 +0530
> @@ -29,6 +29,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/smp_lock.h>
>  #include <linux/module.h>
> +#include <linux/kprobes.h>
>  
>  #include <asm/page.h>
>  #include <asm/pgtable.h>
> @@ -84,8 +85,8 @@ static int store_updates_sp(struct pt_re
>   * The return value is 0 if the fault was handled, or the signal
>   * number if this is a kernel fault that can't be handled here.
>   */
> -int do_page_fault(struct pt_regs *regs, unsigned long address,
> -		  unsigned long error_code)
> +int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
> +			    unsigned long error_code)
>  {
>  	struct vm_area_struct * vma;
>  	struct mm_struct *mm = current->mm;
> diff -puN arch/ppc64/kernel/misc.S~kprobes-exclude-functions-ppc64 arch/ppc64/kernel/misc.S
> --- linux-2.6.13-rc1-mm1/arch/ppc64/kernel/misc.S~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
> +++ linux-2.6.13-rc1-mm1-prasanna/arch/ppc64/kernel/misc.S	2005-07-07 10:24:00.000000000 +0530
> @@ -183,7 +183,7 @@ PPC64_CACHES:
>   *   flush all bytes from start through stop-1 inclusive
>   */
>  
> -_GLOBAL(__flush_icache_range)
> +_KPROBE(__flush_icache_range)
>  
>  /*
>   * Flush the data cache to memory 
> @@ -223,7 +223,7 @@ _GLOBAL(__flush_icache_range)
>  	bdnz	2b
>  	isync
>  	blr
> -	
> +	.previous .text
>  /*
>   * Like above, but only do the D-cache.
>   *
> diff -puN include/asm-ppc64/processor.h~kprobes-exclude-functions-ppc64 include/asm-ppc64/processor.h
> --- linux-2.6.13-rc1-mm1/include/asm-ppc64/processor.h~kprobes-exclude-functions-ppc64	2005-07-06 20:07:22.000000000 +0530
> +++ linux-2.6.13-rc1-mm1-prasanna/include/asm-ppc64/processor.h	2005-07-07 10:22:29.000000000 +0530
> @@ -309,6 +309,20 @@ name: \
>  	.type GLUE(.,name),@function; \
>  GLUE(.,name):
>  
> +#define _KPROBE(name) \
> +	.section ".kprobes.text","a"; \
> +	.align 2 ; \
> +	.globl name; \
> +	.globl GLUE(.,name); \
> +	.section ".opd","aw"; \
> +name: \
> +	.quad GLUE(.,name); \
> +	.quad .TOC.@tocbase; \
> +	.quad 0; \
> +	.previous; \
> +	.type GLUE(.,name),@function; \
> +GLUE(.,name):
> +
>  #define _STATIC(name) \
>  	.section ".text"; \
>  	.align 2 ; \
> 
> _
> -- 
> 
> Prasanna S Panchamukhi
> Linux Technology Center
> India Software Labs, IBM Bangalore
> Ph: 91-80-25044636
> <prasanna@in.ibm.com>

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

* Re: [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes
  2005-07-08 11:10           ` Prasanna S Panchamukhi
@ 2005-07-08 19:01             ` Keshavamurthy Anil S
  2005-07-08 19:16               ` Prarit Bhargava
  0 siblings, 1 reply; 19+ messages in thread
From: Keshavamurthy Anil S @ 2005-07-08 19:01 UTC (permalink / raw)
  To: Prasanna S Panchamukhi
  Cc: Keshavamurthy Anil S, akpm, Andi Kleen, David S. Miller,
	systemtap, linux-kernel

On Fri, Jul 08, 2005 at 04:40:45PM +0530, Prasanna S Panchamukhi wrote:
> Hi Anil,
> 
> I have updated the patch as per your comments to move routines
> from jprobes.S to .kprobes.text section.
> 
> Please let me know if you any issues.
Looks fine and tested it too on IA64 Tiger4 box and works as intened.
Acked-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>


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

* Re: [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes
  2005-07-08 19:01             ` Keshavamurthy Anil S
@ 2005-07-08 19:16               ` Prarit Bhargava
  0 siblings, 0 replies; 19+ messages in thread
From: Prarit Bhargava @ 2005-07-08 19:16 UTC (permalink / raw)
  To: Keshavamurthy Anil S
  Cc: Prasanna S Panchamukhi, akpm, Andi Kleen, David S. Miller,
	systemtap, linux-kernel

Keshavamurthy Anil S wrote:
> On Fri, Jul 08, 2005 at 04:40:45PM +0530, Prasanna S Panchamukhi wrote:
> 
>>Hi Anil,
>>
>>I have updated the patch as per your comments to move routines
>>from jprobes.S to .kprobes.text section.
>>
>>Please let me know if you any issues.
> 
> Looks fine and tested it too on IA64 Tiger4 box and works as intened.
> Acked-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
> 

I ran this on 16p and a 64p ia64 systems and didn't see any issues.

P.


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

end of thread, other threads:[~2005-07-08 19:20 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-07 10:10 [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes Prasanna S Panchamukhi
2005-07-07 10:11 ` [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes Prasanna S Panchamukhi
2005-07-07 10:14   ` [3/6 PATCH] Kprobes : Prevent possible race conditions x86_64 changes Prasanna S Panchamukhi
2005-07-07 10:16     ` [4/6 PATCH] Kprobes : Prevent possible race conditions ppc64 changes Prasanna S Panchamukhi
2005-07-07 10:18       ` [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes Prasanna S Panchamukhi
2005-07-07 10:20         ` [6/6 PATCH] Kprobes : Prevent possible race conditions sparc64 changes Prasanna S Panchamukhi
2005-07-08  2:06         ` [5/6 PATCH] Kprobes : Prevent possible race conditions ia64 changes Keshavamurthy Anil S
2005-07-08 11:10           ` Prasanna S Panchamukhi
2005-07-08 19:01             ` Keshavamurthy Anil S
2005-07-08 19:16               ` Prarit Bhargava
2005-07-08 14:13       ` [4/6 PATCH] Kprobes : Prevent possible race conditions ppc64 changes Ananth N Mavinakayanahalli
2005-07-08 11:07     ` [3/6 PATCH] Kprobes : Prevent possible race conditions x86_64 changes Prasanna S Panchamukhi
2005-07-07 13:19   ` [2/6 PATCH] Kprobes : Prevent possible race conditions i386 changes Andi Kleen
2005-07-08 11:05     ` Prasanna S Panchamukhi
2005-07-07 10:25 ` [1/6 PATCH] Kprobes : Prevent possible race conditions generic changes Andrew Morton
2005-07-07 10:34   ` Andi Kleen
2005-07-07 13:01     ` Prasanna S Panchamukhi
2005-07-08 11:02       ` Prasanna S Panchamukhi
2005-07-07 21:20     ` Vara Prasad

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