From 01d259fe61c43fe659b9e94d098288c50bdc6c61 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 15 Oct 2003 05:25:07 -0700 Subject: [PATCH] [PATCH] Enable interrupts in faults from VM86 mode vm86 mode does a copy_to_user from the general protection fault handler to update the process' vm86 state. The problem is that the full GFP handler runs with interrupts off currently and that trips the might_sleep() test in copy_to_user(). This happens very often in dosemu and once in a while while the X server does its vm86 magic with the VGA bios. See http://bugzilla.kernel.org/show_bug.cgi?id=1339 for details This patch fixes this by enabling interrupts when the original code ran with interrupts on or ran in vm86 mode (vm86 can clear the IF flag) --- arch/i386/kernel/traps.c | 4 ++++ arch/i386/mm/fault.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index fa0f7505f1028..f86037183b984 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -374,6 +374,9 @@ DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) { + if (regs->eflags & X86_EFLAGS_IF) + local_irq_enable(); + if (regs->eflags & VM_MASK) goto gp_in_vm86; @@ -386,6 +389,7 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) return; gp_in_vm86: + local_irq_enable(); handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); return; diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 6ad63aadfaf0f..b05a10a9a69fe 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -223,7 +223,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) __asm__("movl %%cr2,%0":"=r" (address)); /* It's safe to allow irq's after cr2 has been saved */ - if (regs->eflags & X86_EFLAGS_IF) + if (regs->eflags & (X86_EFLAGS_IF|VM_MASK)) local_irq_enable(); tsk = current; -- 2.53.0