Author: jgardou Date: Thu Apr 25 21:29:59 2013 New Revision: 58852
URL: http://svn.reactos.org/svn/reactos?rev=58852&view=rev Log: [NTOSKRNL] - Handle VME for the PUSHF and POPF instruction in virtual mode - There is no reason to set interrupt flag when handling POPF - Fix a typo in POPF case : mask out the right variable See http://www.rcollins.org/articles/vme1/ for reference
Modified: trunk/reactos/ntoskrnl/ke/i386/v86vdm.c
Modified: trunk/reactos/ntoskrnl/ke/i386/v86vdm.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/v86vdm.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/v86vdm.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/v86vdm.c [iso-8859-1] Thu Apr 25 21:29:59 2013 @@ -53,16 +53,22 @@ { ULONG Esp, V86EFlags, TrapEFlags;
- /* Check for VME support */ - ASSERT(KeI386VirtualIntExtensions == FALSE); - /* Get current V8086 flags and mask out interrupt flag */ V86EFlags = *KiNtVdmState; V86EFlags &= ~EFLAGS_INTERRUPT_MASK;
- /* Get trap frame EFLags and leave only align, nested task and interrupt */ + /* Get trap frame EFLags */ TrapEFlags = TrapFrame->EFlags; - V86EFlags &= (EFLAGS_ALIGN_CHECK | EFLAGS_NESTED_TASK | EFLAGS_INTERRUPT_MASK); + /* Check for VME support */ + if(KeI386VirtualIntExtensions) + { + /* Copy the virtual interrupt flag to the interrupt flag */ + TrapEFlags &= ~EFLAGS_INTERRUPT_MASK; + if(TrapEFlags & EFLAGS_VIF) + TrapEFlags |= EFLAGS_INTERRUPT_MASK; + } + /* Leave only align, nested task and interrupt */ + TrapEFlags &= (EFLAGS_ALIGN_CHECK | EFLAGS_NESTED_TASK | EFLAGS_INTERRUPT_MASK);
/* Add in those flags if they exist, and add in the IOPL flag */ V86EFlags |= TrapEFlags; @@ -133,10 +139,20 @@ TrapEFlags = TrapFrame->EFlags;
/* Check for VME support */ - ASSERT(KeI386VirtualIntExtensions == FALSE); - - /* Add V86 and Interrupt flag */ - V86EFlags |= EFLAGS_V86_MASK | EFLAGS_INTERRUPT_MASK; + if(KeI386VirtualIntExtensions) + { + /* Copy the IF flag into the VIF one */ + V86EFlags &= ~EFLAGS_VIF; + if(V86EFlags & EFLAGS_INTERRUPT_MASK) + { + V86EFlags |= EFLAGS_VIF; + /* Don't set the interrupt flag */ + V86EFlags &= ~EFLAGS_INTERRUPT_MASK; + } + } + + /* Add V86 flag */ + V86EFlags |= EFLAGS_V86_MASK;
/* Update EFlags in trap frame */ TrapFrame->EFlags = V86EFlags;