X-Git-Url: http://ftp.safe.ca/?p=safe%2Fjmp%2Flinux-2.6;a=blobdiff_plain;f=arch%2Fx86%2Fkernel%2Ftraps.c;h=acb8c0585ab9f04a2d79457822d083e7de78f8b3;hp=98c2d055284b32fb2ce6ff6776b9cb049c103ae0;hb=494df596f9c315e20523894caa2a2938db3e5d8d;hpb=f6db44df5bd39ed33883786d35342759af796e4a diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 98c2d055..acb8c05 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -54,12 +54,11 @@ #include #include -#include +#include #ifdef CONFIG_X86_64 #include #include -#include #else #include #include @@ -99,6 +98,12 @@ static inline void preempt_conditional_sti(struct pt_regs *regs) local_irq_enable(); } +static inline void conditional_cli(struct pt_regs *regs) +{ + if (regs->flags & X86_EFLAGS_IF) + local_irq_disable(); +} + static inline void preempt_conditional_cli(struct pt_regs *regs) { if (regs->flags & X86_EFLAGS_IF) @@ -626,8 +631,10 @@ clear_dr7: #ifdef CONFIG_X86_32 debug_vm86: + /* reenable preemption: handle_vm86_trap() might sleep */ + dec_preempt_count(); handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); - preempt_conditional_cli(regs); + conditional_cli(regs); return; #endif @@ -896,7 +903,7 @@ asmlinkage void math_state_restore(void) EXPORT_SYMBOL_GPL(math_state_restore); #ifndef CONFIG_MATH_EMULATION -asmlinkage void math_emulate(long arg) +void math_emulate(struct math_emu_info *info) { printk(KERN_EMERG "math-emulation not enabled and no coprocessor found.\n"); @@ -907,12 +914,16 @@ asmlinkage void math_emulate(long arg) #endif /* CONFIG_MATH_EMULATION */ dotraplinkage void __kprobes -do_device_not_available(struct pt_regs *regs, long error) +do_device_not_available(struct pt_regs *regs, long error_code) { #ifdef CONFIG_X86_32 if (read_cr0() & X86_CR0_EM) { + struct math_emu_info info = { }; + conditional_sti(regs); - math_emulate(0); + + info.regs = regs; + math_emulate(&info); } else { math_state_restore(); /* interrupts still off */ conditional_sti(regs);