From b019e57321f3e006c0ec7a54f13efc377bcb6451 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 18 Dec 2007 18:05:58 +0100 Subject: genirq: add unlocked version of set_irq_handler() Add unlocked version for use by irq_chip.set_type handlers which may wish to change handler to level or edge handler when IRQ type is changed. The normal set_irq_handler() call cannot be used because it tries to take irq_desc.lock which is already held when the irq_chip.set_type hook is called. Signed-off-by: Kevin Hilman Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/linux/irq.h b/include/linux/irq.h index efc88538b2ba..4669be080617 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -339,6 +339,13 @@ extern void __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, const char *name); +/* caller has locked the irq_desc and both params are valid */ +static inline void __set_irq_handler_unlocked(int irq, + irq_flow_handler_t handler) +{ + irq_desc[irq].handle_irq = handler; +} + /* * Set a highlevel flow handler for a given IRQ: */ -- cgit v1.2.3-59-g8ed1b From 29b6cd794e73eea7600541d06288a09861ffecb0 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 18 Dec 2007 18:05:58 +0100 Subject: x86: jprobe bugfix jprobe for x86-64 may cause kernel page fault when the jprobe_return() is called from incorrect function. - Use jprobe_saved_regs instead getting it from stack. (Especially on x86-64, it may get incorrect data, because pt_regs can not be get by using container_of(rsp)) - Change the type of stack pointer to unsigned long *. Signed-off-by: Masami Hiramatsu Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/kprobes_32.c | 4 +--- arch/x86/kernel/kprobes_64.c | 6 ++---- include/asm-x86/kprobes_32.h | 2 +- include/asm-x86/kprobes_64.h | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c index d87a523070d1..3a020f79f82b 100644 --- a/arch/x86/kernel/kprobes_32.c +++ b/arch/x86/kernel/kprobes_32.c @@ -727,9 +727,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { if (®s->esp != kcb->jprobe_saved_esp) { - struct pt_regs *saved_regs = - container_of(kcb->jprobe_saved_esp, - struct pt_regs, esp); + struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; printk("current esp %p does not match saved esp %p\n", ®s->esp, kcb->jprobe_saved_esp); printk("Saved registers for jprobe %p\n", jp); diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c index 0c467644589c..a575059fb420 100644 --- a/arch/x86/kernel/kprobes_64.c +++ b/arch/x86/kernel/kprobes_64.c @@ -716,10 +716,8 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) struct jprobe *jp = container_of(p, struct jprobe, kp); if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { - if ((long *)regs->rsp != kcb->jprobe_saved_rsp) { - struct pt_regs *saved_regs = - container_of(kcb->jprobe_saved_rsp, - struct pt_regs, rsp); + if ((unsigned long *)regs->rsp != kcb->jprobe_saved_rsp) { + struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; printk("current rsp %p does not match saved rsp %p\n", (long *)regs->rsp, kcb->jprobe_saved_rsp); printk("Saved registers for jprobe %p\n", jp); diff --git a/include/asm-x86/kprobes_32.h b/include/asm-x86/kprobes_32.h index b772d5b38685..9fe8f3bddfd5 100644 --- a/include/asm-x86/kprobes_32.h +++ b/include/asm-x86/kprobes_32.h @@ -73,7 +73,7 @@ struct kprobe_ctlblk { unsigned long kprobe_status; unsigned long kprobe_old_eflags; unsigned long kprobe_saved_eflags; - long *jprobe_saved_esp; + unsigned long *jprobe_saved_esp; struct pt_regs jprobe_saved_regs; kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; struct prev_kprobe prev_kprobe; diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h index 53f4d8507354..743d76218fc9 100644 --- a/include/asm-x86/kprobes_64.h +++ b/include/asm-x86/kprobes_64.h @@ -66,7 +66,7 @@ struct kprobe_ctlblk { unsigned long kprobe_status; unsigned long kprobe_old_rflags; unsigned long kprobe_saved_rflags; - long *jprobe_saved_rsp; + unsigned long *jprobe_saved_rsp; struct pt_regs jprobe_saved_regs; kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; struct prev_kprobe prev_kprobe; -- cgit v1.2.3-59-g8ed1b From 213fde71024223abcdd7d9e5349d1ea2679227b5 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 18 Dec 2007 18:05:58 +0100 Subject: x86: also define AT_VECTOR_SIZE_ARCH The patch introducing this left out 64-bit x86 despite it also having extra entries. this solves Xen guest troubles. Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/system_64.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h index 4cb23848d460..6e9e4841a2da 100644 --- a/include/asm-x86/system_64.h +++ b/include/asm-x86/system_64.h @@ -7,6 +7,13 @@ #ifdef __KERNEL__ +/* entries in ARCH_DLINFO: */ +#ifdef CONFIG_IA32_EMULATION +# define AT_VECTOR_SIZE_ARCH 2 +#else +# define AT_VECTOR_SIZE_ARCH 1 +#endif + #define __SAVE(reg,offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t" #define __RESTORE(reg,offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t" -- cgit v1.2.3-59-g8ed1b