DECLSPEC_NORETURN VOID FASTCALL KiTrap06Handler(IN PKTRAP_FRAME TrapFrame) { PUCHAR Instruction; ULONG i; KIRQL OldIrql; /* Check for V86 GPF */ if (__builtin_expect(KiV86Trap(TrapFrame), 1)) { /* Enter V86 trap */ KiEnterV86Trap(TrapFrame); /* Must be a VDM process */ if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0)) { /* Enable interrupts */ _enable(); /* Setup illegal instruction fault */ KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION, TrapFrame->Eip, TrapFrame); } /* Go to APC level */ OldIrql = KfRaiseIrql(APC_LEVEL); _enable(); /* Check for BOP */ if (!VdmDispatchBop(TrapFrame)) { /* Should only happen in VDM mode */ UNIMPLEMENTED; while (TRUE); } /* Bring IRQL back */ KfLowerIrql(OldIrql); _disable(); /* Do a quick V86 exit if possible */ KiExitV86Trap(TrapFrame); } /* Save trap frame */ KiEnterTrap(TrapFrame); /* Enable interrupts */ Instruction = (PUCHAR)TrapFrame->Eip; _enable(); /* Check for user trap */ if (KiUserTrap(TrapFrame)) { /* FIXME: Use SEH */ /* Scan next 4 opcodes */ for (i = 0; i < 4; i++) { /* Check for LOCK instruction */ if (Instruction[i] == 0xF0) { /* Send invalid lock sequence exception */ KiDispatchException0Args(STATUS_INVALID_LOCK_SEQUENCE, TrapFrame->Eip, TrapFrame); } } /* FIXME: SEH ends here */ } /* Kernel-mode or user-mode fault (but not LOCK) */ KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION, TrapFrame->Eip, TrapFrame); }
BOOLEAN FASTCALL KiVdmOpcodeIRET(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags) { ULONG Esp, V86EFlags, EFlags, TrapEFlags, Eip; /* Build flat ESP */ Esp = (TrapFrame->HardwareSegSs << 4) + TrapFrame->HardwareEsp; /* Check for OPER32 */ if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32) { /* Build segmented EIP */ TrapFrame->Eip = *(PULONG)Esp; TrapFrame->SegCs = *(PUSHORT)(Esp + 4); /* Set new ESP */ TrapFrame->HardwareEsp += 12; /* Get EFLAGS */ EFlags = *(PULONG)(Esp + 8); } else { /* Build segmented EIP */ TrapFrame->Eip = *(PUSHORT)Esp; TrapFrame->SegCs = *(PUSHORT)(Esp + 2); /* Set new ESP */ TrapFrame->HardwareEsp += 6; /* Get EFLAGS */ EFlags = *(PUSHORT)(Esp + 4); } /* Mask out EFlags */ EFlags &= ~(EFLAGS_IOPL + EFLAGS_VIF + EFLAGS_NESTED_TASK + EFLAGS_VIP); V86EFlags = EFlags; /* Check for VME support */ ASSERT(KeI386VirtualIntExtensions == FALSE); /* Add V86 and Interrupt flag */ EFlags |= EFLAGS_V86_MASK | EFLAGS_INTERRUPT_MASK; /* Update EFlags in trap frame */ TrapEFlags = TrapFrame->EFlags; TrapFrame->EFlags = (TrapFrame->EFlags & EFLAGS_VIP) | EFlags; /* Check if ESP0 needs to be fixed up */ if (!(TrapEFlags & EFLAGS_V86_MASK)) Ki386AdjustEsp0(TrapFrame); /* Update the V8086 EFlags state */ KiVdmClearVdmEFlags(EFLAGS_INTERRUPT_MASK); KiVdmSetVdmEFlags(V86EFlags); /* Build flat EIP and check if this is the BOP instruction */ Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip; if (*(PUSHORT)Eip == 0xC4C4) { /* Dispatch the BOP */ VdmDispatchBop(TrapFrame); } else { /* FIXME: Check for VDM interrupts */ DPRINT("FIXME: Check for VDM interrupts\n"); } /* We're done */ return TRUE; }