mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- Finish the work around for the Pentium cmpxchg8b lock errata: We detected the errata and allocated the 7 first IDT entries on a write protected page, but the final piece of the work around, detecting the write fault ti the Invalid Opcode handler, was missing. Implemented this in the page fault handler to detect and dispatch the write fault to the Invalid Opcode handler.
- Fix the "fix" of un-protecting the 7 IDT entries on P5 in HAL's BIOS call code when setting the custom Invalid Opcode handler. The IDT was unprotected but the write protection wasn't reapplied after the BIOS call, breaking the work around. Other: - KdDebuggerEnabled is a BOOLEAN, so don't do a dword compare in KeUpdateSystemTime. - Use better comment for the hack where we always allow page faults to be handled, even if they the fault occured with interrupts disabled. svn path=/trunk/; revision=43958
This commit is contained in:
parent
66afccbaeb
commit
422721748d
4 changed files with 60 additions and 8 deletions
|
@ -109,7 +109,11 @@ HalpSwitchToRealModeTrapHandlers(VOID)
|
|||
ULONG Handler;
|
||||
PHARDWARE_PTE IdtPte;
|
||||
|
||||
/* On i586, the first 7 entries of IDT are write-protected, unprotect them. */ // Nasty hto hack
|
||||
/*
|
||||
* On P5, the first 7 entries of the IDT are write protected to work around
|
||||
* the cmpxchg8b lock errata. Unprotect them here so we can set our custom
|
||||
* invalid op-code handler.
|
||||
*/
|
||||
if (KeGetCurrentPrcb()->CpuType == 5)
|
||||
{
|
||||
IdtPte = GetPteAddress(((PKIPCR)KeGetPcr())->IDT);
|
||||
|
@ -160,6 +164,8 @@ VOID
|
|||
NTAPI
|
||||
HalpRestoreTrapHandlers(VOID)
|
||||
{
|
||||
PHARDWARE_PTE IdtPte;
|
||||
|
||||
/* We're back, restore the handlers we over-wrote */
|
||||
((PKIPCR)KeGetPcr())->IDT[13].ExtendedOffset =
|
||||
(USHORT)((HalpGpfHandler >> 16) & 0xFFFF);
|
||||
|
@ -167,6 +173,16 @@ HalpRestoreTrapHandlers(VOID)
|
|||
((PKIPCR)KeGetPcr())->IDT[6].ExtendedOffset =
|
||||
(USHORT)((HalpBopHandler >> 16) & 0xFFFF);
|
||||
((PKIPCR)KeGetPcr())->IDT[6].Offset = (USHORT)HalpBopHandler;
|
||||
|
||||
/* On P5, restore the write protection for the first 7 IDT entries */
|
||||
if (KeGetCurrentPrcb()->CpuType == 5)
|
||||
{
|
||||
IdtPte = GetPteAddress(((PKIPCR)KeGetPcr())->IDT);
|
||||
IdtPte->Write = 0;
|
||||
|
||||
/* Flush the TLB by resetting CR3 */
|
||||
__writecr3(__readcr3());
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -197,7 +213,7 @@ HalpUnmapRealModeMemory(VOID)
|
|||
Pte = GetPteAddress((PVOID)i);
|
||||
Pte->Valid = 0;
|
||||
Pte->Write = 0;
|
||||
//Pte->Owner = 0; // Missing this?
|
||||
Pte->Owner = 0;
|
||||
Pte->PageFrameNumber = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ HalpReboot(VOID)
|
|||
/* Enable warm reboot */
|
||||
((PUSHORT)ZeroPageMapping)[0x239] = 0x1234;
|
||||
|
||||
/* Lock CMOS Access */
|
||||
/* Lock CMOS Access (and disable interrupts) */
|
||||
HalpAcquireSystemHardwareSpinLock();
|
||||
|
||||
/* Setup control register B */
|
||||
|
|
|
@ -114,7 +114,7 @@ _KeUpdateRunTime@8:
|
|||
|
||||
/* Check if the debugger is enabled */
|
||||
cmp byte ptr __KdDebuggerEnabled, 0
|
||||
je ResetDpcTime
|
||||
jz ResetDpcTime
|
||||
|
||||
/* Breakpoint */
|
||||
call _DbgBreakPoint@0
|
||||
|
@ -338,7 +338,7 @@ TimerExpired:
|
|||
|
||||
DebugCheck:
|
||||
/* Check if the debugger is enabled */
|
||||
cmp dword ptr __KdDebuggerEnabled, 0
|
||||
cmp byte ptr __KdDebuggerEnabled, 0
|
||||
jnz DebuggerEnabled
|
||||
|
||||
/* Check if this was a full tick */
|
||||
|
|
|
@ -947,6 +947,7 @@ _KiTrap6:
|
|||
/* Enter V86 Trap */
|
||||
V86_TRAP_PROLOG kit6_a, kit6_v
|
||||
|
||||
VdmOpCodeFault:
|
||||
/* Not yet supported (Invalid OPCODE from V86) */
|
||||
UNHANDLED_PATH
|
||||
|
||||
|
@ -957,6 +958,7 @@ NotV86UD:
|
|||
/* Enter trap */
|
||||
TRAP_PROLOG kit6_a, kit6_t
|
||||
|
||||
DispatchLockErrata:
|
||||
/* Check if this happened in kernel mode */
|
||||
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
|
||||
jz KmodeOpcode
|
||||
|
@ -1949,14 +1951,21 @@ _KiTrap14:
|
|||
NoFixUp:
|
||||
mov edi, cr2
|
||||
|
||||
/* REACTOS Mm Hack of Doom */
|
||||
/* Check if this processor has the cmpxchg8b lock errata */
|
||||
cmp byte ptr _KiI386PentiumLockErrataPresent, 0
|
||||
jnz HandleLockErrata
|
||||
|
||||
NotLockErrata:
|
||||
/* HACK: Handle page faults with interrupts disabled */
|
||||
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
|
||||
je HandlePf
|
||||
|
||||
/* Enable interrupts and check if we got here with interrupts disabled */
|
||||
sti
|
||||
/* test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
|
||||
jz IllegalState */
|
||||
#ifdef HACK_ABOVE_FIXED
|
||||
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
|
||||
jz IllegalState
|
||||
#endif
|
||||
|
||||
HandlePf:
|
||||
/* Send trap frame and check if this is kernel-mode or usermode */
|
||||
|
@ -2075,6 +2084,33 @@ VdmAlertGpf:
|
|||
|
||||
/* FIXME: NOT SUPPORTED */
|
||||
UNHANDLED_PATH
|
||||
|
||||
HandleLockErrata:
|
||||
|
||||
/* Fail if this isn't a write fault */
|
||||
test word ptr [ebp+KTRAP_FRAME_ERROR_CODE], 0x4
|
||||
jnz NotLockErrata
|
||||
|
||||
/* Also make sure the page fault is for IDT entry 6 */
|
||||
mov eax, PCR[KPCR_IDT]
|
||||
add eax, 0x30
|
||||
cmp eax, edi
|
||||
jne NotLockErrata
|
||||
|
||||
/*
|
||||
* This is a write fault to the Invalid Opcode handler entry.
|
||||
* We assume this is the lock errata and not a real write fault.
|
||||
*/
|
||||
|
||||
/* Clear the error code */
|
||||
and dword ptr [ebp+KTRAP_FRAME_ERROR_CODE], 0
|
||||
|
||||
/* Check if this happened in V86 mode */
|
||||
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
|
||||
jnz VdmOpCodeFault
|
||||
|
||||
/* Dispatch this to the invalid opcode handler */
|
||||
jmp DispatchLockErrata
|
||||
.endfunc
|
||||
|
||||
.func KiTrap0F
|
||||
|
|
Loading…
Reference in a new issue