aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/kprobes.c
diff options
context:
space:
mode:
authorbibo,mao <bibo.mao@intel.com>2006-03-26 04:38:21 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-26 11:57:04 -0500
commit2326c77017c79fd6d55c69d8a49a57a252921bcd (patch)
tree5a2cafc7452953a4d5c8a8e8eaa0ae34fe306f74 /arch/i386/kernel/kprobes.c
parentc6fd91f0bdcd294a0ae0ba2b2a7f7456ef4b7144 (diff)
[PATCH] kprobe handler: discard user space trap
Currently kprobe handler traps only happen in kernel space, so function kprobe_exceptions_notify should skip traps which happen in user space. This patch modifies this, and it is based on 2.6.16-rc4. Signed-off-by: bibo mao <bibo.mao@intel.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: "Keshavamurthy, Anil S" <anil.s.keshavamurthy@intel.com> Cc: <hiramatu@sdl.hitachi.co.jp> Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/kprobes.c')
-rw-r--r--arch/i386/kernel/kprobes.c19
1 files changed, 6 insertions, 13 deletions
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index acdcc640a72a..df1b346d36ff 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -203,13 +203,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
203{ 203{
204 struct kprobe *p; 204 struct kprobe *p;
205 int ret = 0; 205 int ret = 0;
206 kprobe_opcode_t *addr = NULL; 206 kprobe_opcode_t *addr;
207 unsigned long *lp;
208 struct kprobe_ctlblk *kcb; 207 struct kprobe_ctlblk *kcb;
209#ifdef CONFIG_PREEMPT 208#ifdef CONFIG_PREEMPT
210 unsigned pre_preempt_count = preempt_count(); 209 unsigned pre_preempt_count = preempt_count();
211#endif /* CONFIG_PREEMPT */ 210#endif /* CONFIG_PREEMPT */
212 211
212 addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
213
213 /* 214 /*
214 * We don't want to be preempted for the entire 215 * We don't want to be preempted for the entire
215 * duration of kprobe processing 216 * duration of kprobe processing
@@ -217,17 +218,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
217 preempt_disable(); 218 preempt_disable();
218 kcb = get_kprobe_ctlblk(); 219 kcb = get_kprobe_ctlblk();
219 220
220 /* Check if the application is using LDT entry for its code segment and
221 * calculate the address by reading the base address from the LDT entry.
222 */
223 if ((regs->xcs & 4) && (current->mm)) {
224 lp = (unsigned long *) ((unsigned long)((regs->xcs >> 3) * 8)
225 + (char *) current->mm->context.ldt);
226 addr = (kprobe_opcode_t *) (get_desc_base(lp) + regs->eip -
227 sizeof(kprobe_opcode_t));
228 } else {
229 addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
230 }
231 /* Check we're not actually recursing */ 221 /* Check we're not actually recursing */
232 if (kprobe_running()) { 222 if (kprobe_running()) {
233 p = get_kprobe(addr); 223 p = get_kprobe(addr);
@@ -579,6 +569,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
579 struct die_args *args = (struct die_args *)data; 569 struct die_args *args = (struct die_args *)data;
580 int ret = NOTIFY_DONE; 570 int ret = NOTIFY_DONE;
581 571
572 if (args->regs && user_mode(args->regs))
573 return ret;
574
582 switch (val) { 575 switch (val) {
583 case DIE_INT3: 576 case DIE_INT3:
584 if (kprobe_handler(args->regs)) 577 if (kprobe_handler(args->regs))