From b1b70208549ee1819252cbe99987928faf656f65 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Wed, 30 Sep 2015 21:08:31 +0000 Subject: [PATCH] [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. svn path=/trunk/; revision=69420 --- reactos/lib/fast486/common.c | 80 +++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/reactos/lib/fast486/common.c b/reactos/lib/fast486/common.c index daf73467254..bc31292bec9 100644 --- a/reactos/lib/fast486/common.c +++ b/reactos/lib/fast486/common.c @@ -313,7 +313,13 @@ Fast486InterruptInternal(PFAST486_STATE State, 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 @@ Fast486InterruptInternal(PFAST486_STATE State, } /* Clear NT */ - State->Flags.Nt = FALSE; + State->Flags.Nt = FALSE; if (OldVm) { @@ -497,6 +503,8 @@ Fast486InterruptInternal(PFAST486_STATE State, /* Push the instruction pointer */ if (!Fast486StackPushInternal(State, GateSize, OldEip)) return FALSE; +Finish: + if (PushErrorCode) { /* Push the error code */ @@ -908,15 +916,45 @@ Fast486TaskSwitch(PFAST486_STATE State, FAST486_TASK_SWITCH_TYPE Type, USHORT Se 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 @@ Fast486TaskSwitch(PFAST486_STATE State, FAST486_TASK_SWITCH_TYPE Type, USHORT Se 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 */