From e3cb503509e75545d680881c35394e3301e55e9f Mon Sep 17 00:00:00 2001 From: Alexander van Heukelum Date: Tue, 9 Sep 2008 21:56:02 +0200 Subject: [PATCH] --- yaml --- r: 113495 b: refs/heads/master c: 7643e9b936b4af31ba4851eb7d5b3a3bfad52502 h: refs/heads/master i: 113493: dde41a447d5e6918fd8108c1368a31a42f3c7cef 113491: e811695b1d6e4ecebde3ca9d30c73c7f41a92ada 113487: 7ef3ae949155ef094532e088c053402c1ee896c1 v: v3 --- [refs] | 2 +- trunk/arch/x86/kernel/entry_32.S | 15 ++------------- trunk/arch/x86/kernel/traps_32.c | 14 +++++++++++++- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index fdcc9ffb2458..8ab639dfa676 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 12394cf567d509f6ab5d94544e1f414b35286d9e +refs/heads/master: 7643e9b936b4af31ba4851eb7d5b3a3bfad52502 diff --git a/trunk/arch/x86/kernel/entry_32.S b/trunk/arch/x86/kernel/entry_32.S index 109792bc7cfa..5a885855fc88 100644 --- a/trunk/arch/x86/kernel/entry_32.S +++ b/trunk/arch/x86/kernel/entry_32.S @@ -760,20 +760,9 @@ ENTRY(device_not_available) RING0_INT_FRAME pushl $-1 # mark this as an int CFI_ADJUST_CFA_OFFSET 4 - SAVE_ALL - GET_CR0_INTO_EAX - testl $0x4, %eax # EM (math emulation bit) - jne device_not_available_emulate - preempt_stop(CLBR_ANY) - call math_state_restore - jmp ret_from_exception -device_not_available_emulate: - pushl $0 # temporary storage for ORIG_EIP + pushl $do_device_not_available CFI_ADJUST_CFA_OFFSET 4 - call math_emulate - addl $4, %esp - CFI_ADJUST_CFA_OFFSET -4 - jmp ret_from_exception + jmp error_code CFI_ENDPROC END(device_not_available) diff --git a/trunk/arch/x86/kernel/traps_32.c b/trunk/arch/x86/kernel/traps_32.c index 39a6101a6123..5b15f75d0591 100644 --- a/trunk/arch/x86/kernel/traps_32.c +++ b/trunk/arch/x86/kernel/traps_32.c @@ -46,6 +46,7 @@ #include #endif +#include #include #include #include @@ -1236,6 +1237,17 @@ asmlinkage void math_emulate(long arg) #endif /* CONFIG_MATH_EMULATION */ +void __kprobes do_device_not_available(struct pt_regs *regs, long error) +{ + if (read_cr0() & X86_CR0_EM) { + conditional_sti(regs); + math_emulate(0); + } else { + math_state_restore(); /* interrupts still off */ + conditional_sti(regs); + } +} + void __init trap_init(void) { int i; @@ -1255,7 +1267,7 @@ void __init trap_init(void) set_system_intr_gate(4, &overflow); /* int4 can be called from all */ set_intr_gate(5, &bounds); set_intr_gate(6, &invalid_op); - set_trap_gate(7, &device_not_available); + set_intr_gate(7, &device_not_available); set_task_gate(8, GDT_ENTRY_DOUBLEFAULT_TSS); set_trap_gate(9, &coprocessor_segment_overrun); set_trap_gate(10, &invalid_TSS);