aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorPetr Tesarik <kernel@tesarici.cz>2005-09-03 18:56:28 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:06:09 -0400
commit5fd75ebb1a58c1a3c9e3d9fdf75ce7286b79bb74 (patch)
tree9597e94f20ba1fa317cc05c450e43c8fe80f39ea /arch/i386
parent7ae65fd334232468a9d6b523a4fc141cd6ec5ea4 (diff)
[PATCH] vm86: Honor TF bit when emulating an instruction
If the virtual 86 machine reaches an instruction which raises a General Protection Fault (such as CLI or STI), the instruction is emulated (in handle_vm86_fault). However, the emulation ignored the TF bit, so the hardware debug interrupt was not invoked after such an emulated instruction (and the DOS debugger missed it). This patch fixes the problem by emulating the hardware debug interrupt as the last action before control is returned to the VM86 program. Signed-off-by: Petr Tesarik <kernel@tesarici.cz> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/vm86.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index ec0f68ce688..2daa06fb4a8 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -542,7 +542,7 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
542 unsigned char opcode; 542 unsigned char opcode;
543 unsigned char __user *csp; 543 unsigned char __user *csp;
544 unsigned char __user *ssp; 544 unsigned char __user *ssp;
545 unsigned short ip, sp; 545 unsigned short ip, sp, orig_flags;
546 int data32, pref_done; 546 int data32, pref_done;
547 547
548#define CHECK_IF_IN_TRAP \ 548#define CHECK_IF_IN_TRAP \
@@ -551,8 +551,12 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
551#define VM86_FAULT_RETURN do { \ 551#define VM86_FAULT_RETURN do { \
552 if (VMPI.force_return_for_pic && (VEFLAGS & (IF_MASK | VIF_MASK))) \ 552 if (VMPI.force_return_for_pic && (VEFLAGS & (IF_MASK | VIF_MASK))) \
553 return_to_32bit(regs, VM86_PICRETURN); \ 553 return_to_32bit(regs, VM86_PICRETURN); \
554 if (orig_flags & TF_MASK) \
555 handle_vm86_trap(regs, 0, 1); \
554 return; } while (0) 556 return; } while (0)
555 557
558 orig_flags = *(unsigned short *)&regs->eflags;
559
556 csp = (unsigned char __user *) (regs->cs << 4); 560 csp = (unsigned char __user *) (regs->cs << 4);
557 ssp = (unsigned char __user *) (regs->ss << 4); 561 ssp = (unsigned char __user *) (regs->ss << 4);
558 sp = SP(regs); 562 sp = SP(regs);