mirror of
https://github.com/torvalds/linux.git
synced 2024-12-04 18:13:04 +00:00
i386: convert hardware exception 7 to an interrupt gate
Handle no coprocessor exception with interrupt initially off. device_not_available in entry_32.S calls either math_state_restore or math_emulate. This patch adds an extra indirection to be able to re-enable interrupts explicitly in traps_32.c Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
12394cf567
commit
7643e9b936
@ -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)
|
||||
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <linux/edac.h>
|
||||
#endif
|
||||
|
||||
#include <asm/processor-flags.h>
|
||||
#include <asm/arch_hooks.h>
|
||||
#include <asm/stacktrace.h>
|
||||
#include <asm/processor.h>
|
||||
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user