Author: aandrejevic Date: Fri Nov 15 02:32:08 2013 New Revision: 60995
URL: http://svn.reactos.org/svn/reactos?rev=60995&view=rev Log: [FAST486] - Fix the privilege checks. - Store the CPL in a special field, so that it doesn't get mixed up with the lowest 2 bits of real mode selectors while switching into protected mode. - Reset the exception count after a successful ISR call. - In Fast486OpcodeGroup0F01, check for prefix overrides after parsing the Mod-Reg-R/M, which might add a SS: prefix override in some cases.
Modified: branches/ntvdm/include/reactos/libs/fast486/fast486.h branches/ntvdm/lib/fast486/common.c branches/ntvdm/lib/fast486/common.inl branches/ntvdm/lib/fast486/fast486.c branches/ntvdm/lib/fast486/opgroups.c
Modified: branches/ntvdm/include/reactos/libs/fast486/fast486.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/include/reactos/libs/fast4... ============================================================================== --- branches/ntvdm/include/reactos/libs/fast486/fast486.h [iso-8859-1] (original) +++ branches/ntvdm/include/reactos/libs/fast486/fast486.h [iso-8859-1] Fri Nov 15 02:32:08 2013 @@ -394,6 +394,7 @@ FAST486_REG InstPtr, SavedInstPtr; FAST486_FLAGS_REG Flags; FAST486_TABLE_REG Gdtr, Idtr, Ldtr, Tss; + UCHAR Cpl; ULONG ControlRegisters[FAST486_NUM_CTRL_REGS]; ULONG DebugRegisters[FAST486_NUM_DBG_REGS]; ULONG ExceptionCount;
Modified: branches/ntvdm/lib/fast486/common.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/common.c?rev=6... ============================================================================== --- branches/ntvdm/lib/fast486/common.c [iso-8859-1] (original) +++ branches/ntvdm/lib/fast486/common.c [iso-8859-1] Fri Nov 15 02:32:08 2013 @@ -65,7 +65,8 @@ return FALSE; }
- if (GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl) + if ((!InstFetch && (GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl)) + || (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl)) { Fast486Exception(State, FAST486_EXCEPTION_GP); return FALSE; @@ -132,7 +133,8 @@ return FALSE; }
- if (GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl) + if ((GET_SEGMENT_RPL(CachedDescriptor->Selector) > CachedDescriptor->Dpl) + || (Fast486GetCurrentPrivLevel(State) > CachedDescriptor->Dpl)) { Fast486Exception(State, FAST486_EXCEPTION_GP); return FALSE; @@ -330,8 +332,18 @@ && (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)) { /* Push the error code */ - Fast486StackPush(State, ErrorCode); - } + if (!Fast486StackPush(State, ErrorCode)) + { + /* + * If this function failed, that means Fast486Exception + * was called again, so just return in this case. + */ + return; + } + } + + /* Reset the exception count */ + State->ExceptionCount = 0; }
/* EOF */
Modified: branches/ntvdm/lib/fast486/common.inl URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/common.inl?rev... ============================================================================== --- branches/ntvdm/lib/fast486/common.inl [iso-8859-1] (original) +++ branches/ntvdm/lib/fast486/common.inl [iso-8859-1] Fri Nov 15 02:32:08 2013 @@ -27,16 +27,8 @@ INT Fast486GetCurrentPrivLevel(PFAST486_STATE State) { - if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) - { - /* In protected mode, return the RPL of the CS */ - return GET_SEGMENT_RPL(State->SegmentRegs[FAST486_REG_CS].Selector); - } - else - { - /* Real mode is always in supervisor mode */ - return 0; - } + /* Return the CPL, or 3 if we're in virtual 8086 mode */ + return (!State->Flags.Vm) ? State->Cpl : 3; }
FORCEINLINE @@ -464,7 +456,10 @@ else if (Segment == FAST486_REG_CS) { /* Loading the code segment */ - // TODO: NOT IMPLEMENTED + // TODO: Implement security checks, call gates, etc... + + /* Update CPL */ + State->Cpl = GET_SEGMENT_RPL(Selector); } else { @@ -478,7 +473,7 @@ }
if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl) - && (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl)) + || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl)) { Fast486Exception(State, FAST486_EXCEPTION_GP); return FALSE;
Modified: branches/ntvdm/lib/fast486/fast486.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/fast486.c?rev=... ============================================================================== --- branches/ntvdm/lib/fast486/fast486.c [iso-8859-1] (original) +++ branches/ntvdm/lib/fast486/fast486.c [iso-8859-1] Fri Nov 15 02:32:08 2013 @@ -238,6 +238,9 @@ /* Initialize the registers */ State->Flags.AlwaysSet = 1; State->InstPtr.LowWord = 0xFFF0; + + /* Set the CPL to 0 */ + State->Cpl = 0;
/* Initialize segments */ for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
Modified: branches/ntvdm/lib/fast486/opgroups.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/opgroups.c?rev... ============================================================================== --- branches/ntvdm/lib/fast486/opgroups.c [iso-8859-1] (original) +++ branches/ntvdm/lib/fast486/opgroups.c [iso-8859-1] Fri Nov 15 02:32:08 2013 @@ -1668,17 +1668,17 @@ NO_LOCK_PREFIX(); TOGGLE_ADSIZE(AddressSize);
+ if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) + { + /* Exception occurred */ + return FALSE; + } + /* Check for the segment override */ if (State->PrefixFlags & FAST486_PREFIX_SEG) { /* Use the override segment instead */ Segment = State->SegmentOverride; - } - - if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) - { - /* Exception occurred */ - return FALSE; }
/* Check which operation this is */