Author: aandrejevic Date: Wed Sep 30 21:08:31 2015 New Revision: 69420
URL: http://svn.reactos.org/svn/reactos?rev=69420&view=rev Log: [FAST486] - Don't forget to push the error code when the exception handler is a task gate. - Use SS0/ESP0, SS1/ESP1, or SS2/ESP2 for ring 0/1/2 code task CALLs.
Modified: trunk/reactos/lib/fast486/common.c
Modified: trunk/reactos/lib/fast486/common.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.c?rev=69... ============================================================================== --- trunk/reactos/lib/fast486/common.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.c [iso-8859-1] Wed Sep 30 21:08:31 2015 @@ -313,7 +313,13 @@ if (IdtEntry->Type == FAST486_TASK_GATE_SIGNATURE) { /* Task call */ - return Fast486TaskSwitch(State, FAST486_TASK_CALL, IdtEntry->Selector); + if (!Fast486TaskSwitch(State, FAST486_TASK_CALL, IdtEntry->Selector)) + { + /* Exception occurred */ + return FALSE; + } + + goto Finish; }
/* Check if the interrupt handler is more privileged or if we're in V86 mode */ @@ -428,7 +434,7 @@ }
/* Clear NT */ - State->Flags.Nt = FALSE; + State->Flags.Nt = FALSE;
if (OldVm) { @@ -496,6 +502,8 @@
/* Push the instruction pointer */ if (!Fast486StackPushInternal(State, GateSize, OldEip)) return FALSE; + +Finish:
if (PushErrorCode) { @@ -908,15 +916,45 @@ State->GeneralRegs[FAST486_REG_ECX].Long = NewTss.Ecx; State->GeneralRegs[FAST486_REG_EDX].Long = NewTss.Edx; State->GeneralRegs[FAST486_REG_EBX].Long = NewTss.Ebx; - State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp; State->GeneralRegs[FAST486_REG_EBP].Long = NewTss.Ebp; State->GeneralRegs[FAST486_REG_ESI].Long = NewTss.Esi; State->GeneralRegs[FAST486_REG_EDI].Long = NewTss.Edi; NewEs = NewTss.Es; NewCs = NewTss.Cs; - NewSs = NewTss.Ss; NewDs = NewTss.Ds; NewLdtr = NewTss.Ldtr; + + if (Type == FAST486_TASK_CALL && State->Cpl < 3) + { + switch (State->Cpl) + { + case 0: + { + State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp0; + NewSs = NewTss.Ss0; + break; + } + + case 1: + { + State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp1; + NewSs = NewTss.Ss1; + break; + } + + case 2: + { + State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp2; + NewSs = NewTss.Ss2; + break; + } + } + } + else + { + State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp; + NewSs = NewTss.Ss; + } } else { @@ -926,15 +964,45 @@ State->GeneralRegs[FAST486_REG_ECX].LowWord = NewLegacyTss->Cx; State->GeneralRegs[FAST486_REG_EDX].LowWord = NewLegacyTss->Dx; State->GeneralRegs[FAST486_REG_EBX].LowWord = NewLegacyTss->Bx; - State->GeneralRegs[FAST486_REG_ESP].LowWord = NewLegacyTss->Sp; State->GeneralRegs[FAST486_REG_EBP].LowWord = NewLegacyTss->Bp; State->GeneralRegs[FAST486_REG_ESI].LowWord = NewLegacyTss->Si; State->GeneralRegs[FAST486_REG_EDI].LowWord = NewLegacyTss->Di; NewEs = NewLegacyTss->Es; NewCs = NewLegacyTss->Cs; - NewSs = NewLegacyTss->Ss; NewDs = NewLegacyTss->Ds; NewLdtr = NewLegacyTss->Ldtr; + + if (Type == FAST486_TASK_CALL && State->Cpl < 3) + { + switch (State->Cpl) + { + case 0: + { + State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp0; + NewSs = NewLegacyTss->Ss0; + break; + } + + case 1: + { + State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp1; + NewSs = NewLegacyTss->Ss1; + break; + } + + case 2: + { + State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp2; + NewSs = NewLegacyTss->Ss2; + break; + } + } + } + else + { + State->GeneralRegs[FAST486_REG_ESP].Long = NewLegacyTss->Sp; + NewSs = NewLegacyTss->Ss; + } }
/* Set the NT flag if nesting */