Author: ion
Date: Fri Dec 29 21:49:00 2006
New Revision: 25238
URL:
http://svn.reactos.org/svn/reactos?rev=25238&view=rev
Log:
- Fix critical bugs in exception handling: Unwinding was completely broken, using the
wrong SEH protector to detect collided unwinding. The correct protector itself also had a
broken check.
- Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring
Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and
validation of segments, flags and debug registers. Among other things, IOPL is now
respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly
being called. This completely fixes exception handling being totally broken and crashing
firefox installer, mirc, and other applications.
- Rewrite the page fault handler base code in assembly instead of relying on a broken C
routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList
and faults in the system handler code. Rewrite MmAccessFault to be the main function that
calls out to other sub-fault functions, and use the same prototype as NT.
- Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256
entries.
- Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines.
- Remove all int3 and breakpoints from trap handlers, and replace them with a much better
"UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message
with the line of code that's unhandled. This is to clearly tell the user that
something is unhandled, instead of nesting infinite exceptions due to the int3.
- Fix a bug in INT_PROLOG.
- Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext.
- Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros
and functions to protect against DR-vulnerabilites as well as to properly account for each
active hardware breakpoint in a per-thread fashion by using the dispatcher header.
- Allow CR0_EM when running in a VDM.
- Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also
speed it up by manual copying instead of a memory move.
- Properly give IOPL 3 to user-mode threads if they requested it.
- Detect GPF during GPF.
- Detect pagefault with a trap-frame spread over two or more pages and nested.
- Properly sanitize and set correct trap frame in KiInitailizeUserApc.
- Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL.
- Fix assert in VdmSwapContext, as well as Code Selector check which was broken.
- Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list.
- Update Kernel Fun.
- BUGBUG: Temporaily hack VMWare to detection to always detect VMWare.
Removed:
trunk/reactos/ntoskrnl/mm/i386/memsafe.s
trunk/reactos/ntoskrnl/mm/i386/pfault.c
Modified:
trunk/reactos/base/setup/vmwinst/vmwinst.c
trunk/reactos/dll/ntdll/def/ntdll.def
trunk/reactos/include/ndk/asm.h
trunk/reactos/include/ndk/rtlfuncs.h
trunk/reactos/lib/rtl/i386/except_asm.s
trunk/reactos/lib/rtl/i386/exception.c
trunk/reactos/lib/rtl/rtlp.h
trunk/reactos/lib/rtl/thread.c
trunk/reactos/ntoskrnl/KrnlFun.c
trunk/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S
trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
trunk/reactos/ntoskrnl/include/internal/i386/ke.h
trunk/reactos/ntoskrnl/include/internal/ke.h
trunk/reactos/ntoskrnl/include/internal/ke_x.h
trunk/reactos/ntoskrnl/include/internal/mm.h
trunk/reactos/ntoskrnl/include/internal/ob.h
trunk/reactos/ntoskrnl/ke/i386/cpu.c
trunk/reactos/ntoskrnl/ke/i386/exp.c
trunk/reactos/ntoskrnl/ke/i386/trap.s
trunk/reactos/ntoskrnl/ke/i386/usercall.c
trunk/reactos/ntoskrnl/mm/mdl.c
trunk/reactos/ntoskrnl/mm/mm.c
trunk/reactos/ntoskrnl/ntoskrnl.rbuild
trunk/reactos/ntoskrnl/ob/oblife.c
trunk/reactos/ntoskrnl/ob/obref.c
trunk/reactos/ntoskrnl/vdm/vdmexec.c
Modified: trunk/reactos/base/setup/vmwinst/vmwinst.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/vmwinst/vmwinst…
==============================================================================
--- trunk/reactos/base/setup/vmwinst/vmwinst.c (original)
+++ trunk/reactos/base/setup/vmwinst/vmwinst.c Fri Dec 29 21:49:00 2006
@@ -68,7 +68,7 @@
return EXCEPTION_CONTINUE_EXECUTION;
}
-static BOOL
+BOOL
DetectVMware(int *Version)
{
int magic, ver;
@@ -1010,7 +1010,7 @@
{
PVOID ExceptionHandler;
- int Version;
+ //int Version;
WCHAR *lc;
hAppInstance = hInstance;
@@ -1024,9 +1024,9 @@
return 1;
}
- if(!DetectVMware(&Version))
- {
- return 1;
+ //if(!DetectVMware(&Version))
+ {
+ //return 1;
}
/* unregister the handler */
Modified: trunk/reactos/dll/ntdll/def/ntdll.def
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/def/ntdll.def?re…
==============================================================================
--- trunk/reactos/dll/ntdll/def/ntdll.def (original)
+++ trunk/reactos/dll/ntdll/def/ntdll.def Fri Dec 29 21:49:00 2006
@@ -67,6 +67,7 @@
NtAccessCheck@32
NtAccessCheckAndAuditAlarm@44
NtAddAtom@12
+NtAddBootEntry@8
NtAdjustGroupsToken@24
NtAdjustPrivilegesToken@24
NtAlertResumeThread@8
Modified: trunk/reactos/include/ndk/asm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/asm.h?rev=2523…
==============================================================================
--- trunk/reactos/include/ndk/asm.h (original)
+++ trunk/reactos/include/ndk/asm.h Fri Dec 29 21:49:00 2006
@@ -169,6 +169,7 @@
#define KPCR_STALL_SCALE_FACTOR 0x4C
#define KPCR_SET_MEMBER 0x48
#define KPCR_NUMBER 0x51
+#define KPCR_VDM_ALERT 0x54
#define KPCR_PRCB_DATA 0x120
#define KPCR_CURRENT_THREAD 0x124
#define KPCR_PRCB_NEXT_THREAD 0x128
@@ -473,9 +474,13 @@
#endif
//
-// DR7 Values
-//
+// DR6 and 7 Masks
+//
+#define DR6_LEGAL 0xE00F
+#define DR7_LEGAL 0xFFFF0155
+#define DR7_ACTIVE 0x55
#define DR7_RESERVED_MASK 0xDC00
+#define DR7_OVERRIDE_MASK 0xF0000
//
// Usermode callout frame definitions
@@ -491,6 +496,10 @@
//
#ifdef __ASM__
#define STATUS_ACCESS_VIOLATION 0xC0000005
+#define STATUS_IN_PAGE_ERROR 0xC0000006
+#define STATUS_GUARD_PAGE_VIOLATION 0x80000001
+#define STATUS_STACK_OVERFLOW 0xC00000FD
+#define KI_EXCEPTION_ACCESS_VIOLATION 0x10000004
#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
#define STATUS_NO_CALLBACK_ACTIVE 0xC0000258
#define STATUS_CALLBACK_POP_STACK 0xC0000423
Modified: trunk/reactos/include/ndk/rtlfuncs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtlfuncs.h?rev…
==============================================================================
--- trunk/reactos/include/ndk/rtlfuncs.h (original)
+++ trunk/reactos/include/ndk/rtlfuncs.h Fri Dec 29 21:49:00 2006
@@ -1893,9 +1893,9 @@
IN HANDLE ProcessHandle,
IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN BOOLEAN CreateSuspended,
- IN LONG StackZeroBits,
- IN ULONG StackReserve,
- IN ULONG StackCommit,
+ IN ULONG StackZeroBits,
+ IN SIZE_T StackReserve,
+ IN SIZE_T StackCommit,
IN PTHREAD_START_ROUTINE StartAddress,
IN PVOID Parameter,
IN OUT PHANDLE ThreadHandle,
Modified: trunk/reactos/lib/rtl/i386/except_asm.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/i386/except_asm.s?…
==============================================================================
--- trunk/reactos/lib/rtl/i386/except_asm.s (original)
+++ trunk/reactos/lib/rtl/i386/except_asm.s Fri Dec 29 21:49:00 2006
@@ -134,7 +134,7 @@
.globl _RtlpExecuteHandlerForUnwind@20
_RtlpExecuteHandlerForUnwind@20:
/* Copy the routine in EDX */
- mov edx, offset _RtlpExceptionProtector
+ mov edx, offset _RtlpUnwindProtector
.endfunc
.func RtlpExecuteHandler@20
@@ -243,7 +243,7 @@
/* Put the exception record in ECX and check the Flags */
mov ecx, [esp+4]
test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWINDING +
EXCEPTION_EXIT_UNWIND
- jnz .return
+ jz .return
/* Save the frame in ECX and Context in EDX */
mov ecx, [esp+8]
Modified: trunk/reactos/lib/rtl/i386/exception.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/i386/exception.c?r…
==============================================================================
--- trunk/reactos/lib/rtl/i386/exception.c (original)
+++ trunk/reactos/lib/rtl/i386/exception.c Fri Dec 29 21:49:00 2006
@@ -10,29 +10,8 @@
/* INCLUDES *****************************************************************/
#include <rtl.h>
-
#define NDEBUG
#include <debug.h>
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-VOID
-NTAPI
-RtlpGetStackLimits(PULONG_PTR StackBase,
- PULONG_PTR StackLimit);
-
-PEXCEPTION_REGISTRATION_RECORD
-NTAPI
-RtlpGetExceptionList(VOID);
-
-VOID
-NTAPI
-RtlpSetExceptionList(PEXCEPTION_REGISTRATION_RECORD NewExceptionList);
-
-typedef struct _DISPATCHER_CONTEXT
-{
- PEXCEPTION_REGISTRATION_RECORD RegistrationPointer;
-} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
/* PUBLIC FUNCTIONS **********************************************************/
@@ -100,7 +79,6 @@
sizeof(*RegistrationFrame));
/* Call the handler */
- DPRINT1("Calling handler: %p\n", RegistrationFrame->Handler);
Disposition = RtlpExecuteHandlerForException(ExceptionRecord,
RegistrationFrame,
Context,
@@ -192,7 +170,7 @@
IN PVOID ReturnValue)
{
PEXCEPTION_REGISTRATION_RECORD RegistrationFrame, OldFrame;
- DISPATCHER_CONTEXT DispatcherContext;
+ DISPATCHER_CONTEXT DispatcherContext;
EXCEPTION_RECORD ExceptionRecord2, ExceptionRecord3;
EXCEPTION_DISPOSITION Disposition;
ULONG_PTR StackLow, StackHigh;
@@ -306,7 +284,7 @@
&DispatcherContext,
RegistrationFrame->
Handler);
- switch (Disposition)
+ switch(Disposition)
{
/* Continue searching */
case ExceptionContinueSearch:
Modified: trunk/reactos/lib/rtl/rtlp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/rtlp.h?rev=25238&a…
==============================================================================
--- trunk/reactos/lib/rtl/rtlp.h (original)
+++ trunk/reactos/lib/rtl/rtlp.h Fri Dec 29 21:49:00 2006
@@ -15,6 +15,24 @@
#else
#define PAGED_CODE_RTL()
#endif
+
+VOID
+NTAPI
+RtlpGetStackLimits(PULONG_PTR StackBase,
+ PULONG_PTR StackLimit);
+
+PEXCEPTION_REGISTRATION_RECORD
+NTAPI
+RtlpGetExceptionList(VOID);
+
+VOID
+NTAPI
+RtlpSetExceptionList(PEXCEPTION_REGISTRATION_RECORD NewExceptionList);
+
+typedef struct _DISPATCHER_CONTEXT
+{
+ PEXCEPTION_REGISTRATION_RECORD RegistrationPointer;
+} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
/* These provide support for sharing code between User and Kernel RTL */
PVOID
@@ -112,7 +130,7 @@
NTSTATUS
NTAPI
DebugService(IN ULONG Service,
- IN PCVOID Buffer,
+ IN const void* Buffer,
IN ULONG Length,
IN PVOID Argument1,
IN PVOID Argument2);
Modified: trunk/reactos/lib/rtl/thread.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/thread.c?rev=25238…
==============================================================================
--- trunk/reactos/lib/rtl/thread.c (original)
+++ trunk/reactos/lib/rtl/thread.c Fri Dec 29 21:49:00 2006
@@ -3,7 +3,7 @@
* PROJECT: ReactOS system libraries
* PURPOSE: Rtl user thread functions
* FILE: lib/rtl/thread.c
- * PROGRAMERS:
+ * PROGRAMERS:
* Alex Ionescu (alex(a)relsoft.net)
* Eric Kohl
* KJK::Hyperion
@@ -21,60 +21,54 @@
NTSTATUS
NTAPI
-RtlpCreateUserStack(HANDLE hProcess,
- ULONG StackReserve,
- ULONG StackCommit,
- ULONG StackZeroBits,
- PINITIAL_TEB InitialTeb)
+RtlpCreateUserStack(IN HANDLE hProcess,
+ IN SIZE_T StackReserve OPTIONAL,
+ IN SIZE_T StackCommit OPTIONAL,
+ IN ULONG StackZeroBits OPTIONAL,
+ OUT PINITIAL_TEB InitialTeb)
{
NTSTATUS Status;
SYSTEM_BASIC_INFORMATION SystemBasicInfo;
PIMAGE_NT_HEADERS Headers;
ULONG_PTR Stack = 0;
BOOLEAN UseGuard = FALSE;
-
- DPRINT("RtlpCreateUserStack\n");
-
+ ULONG Dummy, GuardPageSize;
+
/* Get some memory information */
- Status = NtQuerySystemInformation(SystemBasicInformation,
+ Status = ZwQuerySystemInformation(SystemBasicInformation,
&SystemBasicInfo,
sizeof(SYSTEM_BASIC_INFORMATION),
NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failure to query system info\n");
- return Status;
- }
-
+ if (!NT_SUCCESS(Status)) return Status;
+
/* Use the Image Settings if we are dealing with the current Process */
if (hProcess == NtCurrentProcess())
{
/* Get the Image Headers */
Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
- DPRINT("Headers: %p\n", Headers);
-
+
/* If we didn't get the parameters, find them ourselves */
- StackReserve = (StackReserve) ?
- StackReserve : Headers->OptionalHeader.SizeOfStackReserve;
- StackCommit = (StackCommit) ?
- StackCommit : Headers->OptionalHeader.SizeOfStackCommit;
+ if (!StackReserve) StackReserve = Headers->OptionalHeader.
+ SizeOfStackReserve;
+ if (!StackCommit) StackCommit = Headers->OptionalHeader.
+ SizeOfStackCommit;
}
else
{
/* Use the System Settings if needed */
- StackReserve = (StackReserve) ? StackReserve :
- SystemBasicInfo.AllocationGranularity;
- StackCommit = (StackCommit) ? StackCommit : SystemBasicInfo.PageSize;
- }
-
+ if (!StackReserve) StackReserve = SystemBasicInfo.AllocationGranularity;
+ if (!StackCommit) StackCommit = SystemBasicInfo.PageSize;
+ }
+
/* Align everything to Page Size */
StackReserve = ROUND_UP(StackReserve, SystemBasicInfo.AllocationGranularity);
StackCommit = ROUND_UP(StackCommit, SystemBasicInfo.PageSize);
- #if 1 // FIXME: Remove once Guard Page support is here
+
+ // FIXME: Remove once Guard Page support is here
+ #if 1
StackCommit = StackReserve;
#endif
- DPRINT("StackReserve: %lx, StackCommit: %lx\n", StackReserve,
StackCommit);
-
+
/* Reserve memory for the stack */
Status = ZwAllocateVirtualMemory(hProcess,
(PVOID*)&Stack,
@@ -82,33 +76,26 @@
&StackReserve,
MEM_RESERVE,
PAGE_READWRITE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failure to reserve stack\n");
- return Status;
- }
-
+ if (!NT_SUCCESS(Status)) return Status;
+
/* Now set up some basic Initial TEB Parameters */
InitialTeb->PreviousStackBase = NULL;
InitialTeb->PreviousStackLimit = NULL;
InitialTeb->AllocatedStackBase = (PVOID)Stack;
InitialTeb->StackBase = (PVOID)(Stack + StackReserve);
-
+
/* Update the Stack Position */
Stack += StackReserve - StackCommit;
-
+
/* Check if we will need a guard page */
if (StackReserve > StackCommit)
{
+ /* Remove a page to set as guard page */
Stack -= SystemBasicInfo.PageSize;
StackCommit += SystemBasicInfo.PageSize;
UseGuard = TRUE;
}
-
- DPRINT("AllocatedBase: %p, StackBase: %p, Stack: %lx, StackCommit: %lx\n",
- InitialTeb->AllocatedStackBase, InitialTeb->StackBase, Stack,
- StackCommit);
-
+
/* Allocate memory for the stack */
Status = ZwAllocateVirtualMemory(hProcess,
(PVOID*)&Stack,
@@ -116,75 +103,68 @@
&StackCommit,
MEM_COMMIT,
PAGE_READWRITE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failure to allocate stack\n");
- return Status;
- }
-
+ if (!NT_SUCCESS(Status)) return Status;
+
/* Now set the current Stack Limit */
InitialTeb->StackLimit = (PVOID)Stack;
- DPRINT("StackLimit: %lx\n", Stack);
-
+
/* Create a guard page */
if (UseGuard)
{
- ULONG GuardPageSize = SystemBasicInfo.PageSize;
- ULONG Dummy;
-
- /* Attempt maximum space possible */
+ /* Attempt maximum space possible */
+ GuardPageSize = SystemBasicInfo.PageSize;
Status = ZwProtectVirtualMemory(hProcess,
(PVOID*)&Stack,
&GuardPageSize,
PAGE_GUARD | PAGE_READWRITE,
&Dummy);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failure to create guard page\n");
- return Status;
- }
-
+ if (!NT_SUCCESS(Status)) return Status;
+
/* Update the Stack Limit keeping in mind the Guard Page */
InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit -
GuardPageSize);
- DPRINT1("StackLimit: %lx\n", Stack);
- }
-
+ }
+
/* We are done! */
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+RtlpFreeUserStack(IN HANDLE Process,
+ IN PINITIAL_TEB InitialTeb)
+{
+ ULONG Dummy = 0;
+ NTSTATUS Status;
+
+ /* Free the Stack */
+ Status = ZwFreeVirtualMemory(Process,
+ &InitialTeb->AllocatedStackBase,
+ &Dummy,
+ MEM_RELEASE);
+
+ /* Clear the initial TEB */
+ RtlZeroMemory(InitialTeb, sizeof(INITIAL_TEB));
return Status;
}
-NTSTATUS
-NTAPI
-RtlpFreeUserStack(HANDLE hProcess,
- PINITIAL_TEB InitialTeb)
-{
- ULONG Dummy = 0;
-
- /* Free the Stack */
- return ZwFreeVirtualMemory(hProcess,
- &InitialTeb->AllocatedStackBase,
- &Dummy,
- MEM_RELEASE);
-}
-
/* FUNCTIONS ***************************************************************/
/*
@implemented
*/
-NTSTATUS
-NTAPI
-RtlCreateUserThread(HANDLE ProcessHandle,
- PSECURITY_DESCRIPTOR SecurityDescriptor,
- BOOLEAN CreateSuspended,
- LONG StackZeroBits,
- ULONG StackReserve,
- ULONG StackCommit,
- PTHREAD_START_ROUTINE StartAddress,
- PVOID Parameter,
- PHANDLE ThreadHandle,
- PCLIENT_ID ClientId)
+NTSTATUS
+NTAPI
+RtlCreateUserThread(IN HANDLE ProcessHandle,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
+ IN BOOLEAN CreateSuspended,
+ IN ULONG StackZeroBits OPTIONAL,
+ IN SIZE_T StackReserve OPTIONAL,
+ IN SIZE_T StackCommit OPTIONAL,
+ IN PTHREAD_START_ROUTINE StartAddress,
+ IN PVOID Parameter OPTIONAL,
+ OUT PHANDLE ThreadHandle OPTIONAL,
+ OUT PCLIENT_ID ClientId OPTIONAL)
{
NTSTATUS Status;
HANDLE Handle;
@@ -192,37 +172,27 @@
INITIAL_TEB InitialTeb;
OBJECT_ATTRIBUTES ObjectAttributes;
CONTEXT Context;
-
- DPRINT("RtlCreateUserThread: (hProcess: %p, Suspended: %d,"
- "ZeroBits: %lx, StackReserve: %lx, StackCommit: %lx,"
- "StartAddress: %p, Parameter: %p)\n", ProcessHandle,
- CreateSuspended, StackZeroBits, StackReserve, StackCommit,
- StartAddress, Parameter);
-
+
/* First, we'll create the Stack */
Status = RtlpCreateUserStack(ProcessHandle,
StackReserve,
StackCommit,
StackZeroBits,
&InitialTeb);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failure to create User Stack\n");
- return Status;
- }
-
+ if (!NT_SUCCESS(Status)) return Status;
+
/* Next, we'll set up the Initial Context */
RtlInitializeContext(ProcessHandle,
&Context,
Parameter,
StartAddress,
InitialTeb.StackBase);
-
+
/* We are now ready to create the Kernel Thread Object */
- InitializeObjectAttributes(&ObjectAttributes,
- NULL,
- 0,
- NULL,
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ 0,
+ NULL,
SecurityDescriptor);
Status = ZwCreateThread(&Handle,
THREAD_ALL_ACCESS,
@@ -234,18 +204,16 @@
CreateSuspended);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failure to create Thread\n");
-
/* Free the stack */
RtlpFreeUserStack(ProcessHandle, &InitialTeb);
}
else
{
- DPRINT("Thread created: %p\n", Handle);
+ /* Return thread data */
if (ThreadHandle) *ThreadHandle = Handle;
if (ClientId) *ClientId = ThreadCid;
}
-
+
/* Return success or the previous failure */
return Status;
}
@@ -262,10 +230,7 @@
IN PTHREAD_START_ROUTINE ThreadStartAddress,
IN PINITIAL_TEB InitialTeb)
{
- DPRINT("RtlInitializeContext: (hProcess: %p, ThreadContext: %p, Teb:
%p\n",
- ProcessHandle, ThreadContext, InitialTeb);
-
- /*
+ /*
* Set the Initial Registers
* This is based on NT's default values -- crazy apps might expect this...
*/
@@ -276,27 +241,27 @@
ThreadContext->Edx = 3;
ThreadContext->Esi = 4;
ThreadContext->Edi = 5;
-
+
/* Set the Selectors */
ThreadContext->SegGs = 0;
- ThreadContext->SegFs = KGDT_R3_TEB | RPL_MASK;
- ThreadContext->SegEs = KGDT_R3_DATA | RPL_MASK;
- ThreadContext->SegDs = KGDT_R3_DATA | RPL_MASK;
- ThreadContext->SegCs = KGDT_R3_CODE | RPL_MASK;
- ThreadContext->SegSs = KGDT_R3_DATA | RPL_MASK;
-
+ ThreadContext->SegFs = KGDT_R3_TEB;
+ ThreadContext->SegEs = KGDT_R3_DATA;
+ ThreadContext->SegDs = KGDT_R3_DATA;
+ ThreadContext->SegSs = KGDT_R3_DATA;
+ ThreadContext->SegCs = KGDT_R3_CODE;
+
/* Enable Interrupts */
- ThreadContext->EFlags = 0x200; /*X86_EFLAGS_IF */
-
+ ThreadContext->EFlags = EFLAGS_INTERRUPT_MASK;
+
/* Settings passed */
ThreadContext->Eip = (ULONG)ThreadStartAddress;
ThreadContext->Esp = (ULONG)InitialTeb;
-
+
/* Only the basic Context is initialized */
- ThreadContext->ContextFlags = CONTEXT_CONTROL |
- CONTEXT_INTEGER |
+ ThreadContext->ContextFlags = CONTEXT_CONTROL |
+ CONTEXT_INTEGER |
CONTEXT_SEGMENTS;
-
+
/* Set up ESP to the right value */
ThreadContext->Esp -= sizeof(PVOID);
ZwWriteVirtualMemory(ProcessHandle,
@@ -304,7 +269,7 @@
(PVOID)&ThreadStartParam,
sizeof(PVOID),
NULL);
-
+
/* Push it down one more notch for RETEIP */
ThreadContext->Esp -= sizeof(PVOID);
}
@@ -312,13 +277,13 @@
/*
* @implemented
*/
-VOID
-NTAPI
+VOID
+NTAPI
RtlExitUserThread(NTSTATUS Status)
{
/* Call the Loader and tell him to notify the DLLs */
LdrShutdownThread();
-
+
/* Shut us down */
NtCurrentTeb()->FreeStackOnTermination = TRUE;
NtTerminateThread(NtCurrentThread(), Status);
@@ -327,8 +292,8 @@
/*
@implemented
*/
-VOID
-NTAPI
+VOID
+NTAPI
RtlFreeUserThreadStack(HANDLE ProcessHandle,
HANDLE ThreadHandle)
{
@@ -336,19 +301,15 @@
THREAD_BASIC_INFORMATION ThreadBasicInfo;
ULONG Dummy, Size = 0;
PVOID StackLocation;
-
+
/* Query the Basic Info */
Status = NtQueryInformationThread(ThreadHandle,
ThreadBasicInformation,
&ThreadBasicInfo,
sizeof(THREAD_BASIC_INFORMATION),
NULL);
- if (!NT_SUCCESS(Status) || !ThreadBasicInfo.TebBaseAddress)
- {
- DPRINT1("Could not query info, or TEB is NULL\n");
- return;
- }
-
+ if (!NT_SUCCESS(Status) || !ThreadBasicInfo.TebBaseAddress) return;
+
/* Get the deallocation stack */
Status = NtReadVirtualMemory(ProcessHandle,
&((PTEB)ThreadBasicInfo.TebBaseAddress)->
@@ -356,12 +317,8 @@
&StackLocation,
sizeof(PVOID),
&Dummy);
- if (!NT_SUCCESS(Status) || !StackLocation)
- {
- DPRINT1("Could not read Deallocation Base\n");
- return;
- }
-
+ if (!NT_SUCCESS(Status) || !StackLocation) return;
+
/* Free it */
NtFreeVirtualMemory(ProcessHandle, &StackLocation, &Size, MEM_RELEASE);
}
Modified: trunk/reactos/ntoskrnl/KrnlFun.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=252…
==============================================================================
--- trunk/reactos/ntoskrnl/KrnlFun.c (original)
+++ trunk/reactos/ntoskrnl/KrnlFun.c Fri Dec 29 21:49:00 2006
@@ -10,31 +10,32 @@
//
//
// Ob:
-// - Fix bug related to Deferred Loading (don't requeue active work item).
// - Add Directory Lock.
+// - Strengthen code with debug checks and assertions.
+// - Fix FIXMEs/commented out code.
+//
+// Ex:
+// - Fixup existing code that talks to Ke.
+// - Implement Generic Callback mechanism.
+// - Use pushlocks for handle implementation.
+//
+// Lpc:
+// - Figure out why NTLPC-processes won't die anymore.
+//
+// Ke1:
+// - Implement KiInitMachineDependent.
+// - Implement Privileged Instruction Handler in Umode GPF.
//
// Fstub:
// - Implement IoAssignDriveLetters using mount manager support.
//
-// Ke:
-// - Figure out why the DPC stack doesn't really work.
-// - Fix SEH/Page Fault + Exceptions!? Weird exception bugs!
+// Hal:
+// - Use APC and DPC Interrupt Dispatchers.
+// - CMOS Initialization and CMOS Spinlock.
+//
+// Ke2:
// - New optimized table-based tick-hashed timer implementation.
// - New Thread Scheduler based on 2003.
-// - Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion.
-//
-// Hal:
-// - New IRQL Implementation.
-// - CMOS Initialization and CMOS Spinlock.
-// - Report resource usage to kernel (HalReportResourceUsage).
-//
-// Lpc:
-// - Activate new NTLPC and delete old implementation.
-// - Figure out why LPC-processes won't die anymore.
-//
-// Ex:
-// - Implement Generic Callback mechanism.
-// - Use pushlocks for handle implementation.
//
// Kd:
// - Implement KD Kernel Debugging and WinDBG support.
@@ -45,3 +46,30 @@
//
///////////////////////////////////////////////////////////////////////////////
+// REACTOS GUIDANCE PLAN
+//
________________________________________________________________________________________________________
+// /
\
+// | OB, PS, LPC, DBGK, IO => Almost entirely fixed interaction with Ke/Ex.
| |
+// | SE => Not looked at. Interaction with Ps/Io is minimal and currently hacked away.
Preserve. |J|
+// | EX => Needs re-visiting (in trunk). Do callbacks/push locks for interaction with
Ps. |A|
+// | KD/KDBG => Laptop has special version of ROS without these components. Commit in
branch. |N|
+// | INIT => Boot sequence still needs work in terms of interaction with Ke and CPU
features. | |
+// | || || || || || || || || || || ||
|| |F|
+// | \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
\/ |E|
+// | HAL => Needs APC/DPC/IRQL implementation fixed ASAP in terms of interaction with
Ke. |B|
+// | FSTUB => Needs IoAssignDriveLetters fixed ASAP but not critical to Ke/Ex.
Interacts with Io. | |
+// | || || || || || || || || || || ||
|| |M|
+// | \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
\/ |A|
+// | CM => TOTAL REWRITE.
|R|
+// | || || || || || || || || || || ||
|| | |
+// | || || || || || || || || || || ||
|| |A|
+// | \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
\/ |P|
+// | KE => Timer Rewrite + Thread Scheduler Rewrite.
|R|
+// | || || || || || || || || || || ||
|| |I|
+// | || || || || || || || || || || ||
|| |L|
+// | || || || || || || || || || || ||
|| | |
+// | \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
\/ |M|
+// | MM => TOTAL REWRITE.
|A|
+// |
|Y|
+//
\________________________________________________________________________________________________________/
+//
Modified: trunk/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/i386/fastinter…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S (original)
+++ trunk/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S Fri Dec 29 21:49:00 2006
@@ -381,6 +381,9 @@
*/
.global @ExInterlockedPopEntrySList@8
.global @InterlockedPopEntrySList@4
+.global _ExpInterlockedPopEntrySListResume@0
+.global _ExpInterlockedPopEntrySListFault@0
+.global _ExpInterlockedPopEntrySListEnd@0
@ExInterlockedPopEntrySList@8:
@InterlockedPopEntrySList@4:
@@ -392,10 +395,10 @@
mov ebp, ecx
/* Get sequence number and link pointer */
+_ExpInterlockedPopEntrySListResume@0:
mov edx, [ebp+4]
mov eax, [ebp]
-1:
/* Check if the list is empty */
or eax, eax
jz 2f
@@ -404,9 +407,11 @@
lea ecx, [edx-1]
/* Get next pointer and do the exchange */
+_ExpInterlockedPopEntrySListFault@0:
mov ebx, [eax]
+_ExpInterlockedPopEntrySListEnd@0:
LOCK cmpxchg8b [ebp]
- jnz 1b
+ jnz _ExpInterlockedPopEntrySListResume@0
/* Restore registers and return */
2:
Modified: trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S (original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S Fri Dec 29 21:49:00 2006
@@ -66,6 +66,30 @@
#endif
//
+// @name UNHANDLED_PATH
+//
+// This macro TODO
+//
+// @param None
+//
+// @remark None.
+//
+.macro UNHANDLED_PATH
+ /* Get EIP */
+ call $+5
+ pop eax
+
+ /* Print debug message */
+ push eax
+ push offset _UnhandledMsg
+ call _DbgPrint
+ add esp, 8
+
+ /* Loop indefinitely */
+ jmp $
+.endm
+
+//
// @name IDT
//
// This macro creates an IDT entry for the given handler
@@ -182,7 +206,6 @@
push offset V86DebugMsg
call _DbgPrint
add esp, 8
- int 3
jmp $
.endm
@@ -511,7 +534,7 @@
/* Check if this was kernel mode */
1:
- cmp dword ptr [esp+KTRAP_FRAME_CS], KGDT_R0_CODE
+ cmp word ptr [esp+KTRAP_FRAME_CS], KGDT_R0_CODE
jz 1f
/* Set segments */
@@ -947,7 +970,7 @@
/* Assert the saved exception list */
or edx, edx
jnz 1f
- int 3
+ UNHANDLED_PATH
1:
#endif
@@ -962,7 +985,7 @@
/* Assert the saved previous mode */
cmp ecx, -1
jnz 1f
- int 3
+ UNHANDLED_PATH
1:
#endif
@@ -976,7 +999,7 @@
mov ecx, [esp+KTRAP_FRAME_PREVIOUS_MODE]
cmp ecx, -1
jz 1f
- int 3
+ UNHANDLED_PATH
1:
#endif
.endif
@@ -1111,7 +1134,7 @@
add dword ptr [esp+KTRAP_FRAME_DEBUGARGMARK], 0xBADB0D00
6:
- int 3
+ UNHANDLED_PATH
jmp 5b
#endif
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h Fri Dec 29 21:49:00 2006
@@ -41,11 +41,7 @@
#define X86_EXT_FEATURE_SSE3 0x00000001 /* SSE3 extension present */
#define X86_EXT_FEATURE_3DNOW 0x40000000 /* 3DNOW! extension present */
-#define DR7_ACTIVE 0x00000055 /* If any of these bits are set, a Dr is
active */
-
#define FRAME_EDITED 0xFFF8
-
-#define WE_DO_NOT_SPEAK_ABOUT_THE_V86_HACK 1
#ifndef __ASM__
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h Fri Dec 29 21:49:00 2006
@@ -130,6 +130,8 @@
extern PVOID KeUserCallbackDispatcher;
extern PVOID KeUserExceptionDispatcher;
extern PVOID KeRaiseUserExceptionDispatcher;
+extern UCHAR KiDebugRegisterTrapOffsets[9];
+extern UCHAR KiDebugRegisterContextOffsets[9];
/* MACROS *************************************************************************/
Modified: trunk/reactos/ntoskrnl/include/internal/ke_x.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke_x.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke_x.h Fri Dec 29 21:49:00 2006
@@ -5,6 +5,86 @@
* PURPOSE: Internal Inlined Functions for the Kernel
* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
*/
+
+//
+// Thread Dispatcher Header DebugActive Mask
+//
+#define DR_MASK(x) 1 << x
+#define DR_ACTIVE_MASK 0x10
+#define DR_REG_MASK 0x4F
+
+//
+// Sanitizes a selector
+//
+FORCEINLINE
+ULONG
+Ke386SanitizeSeg(IN ULONG Cs,
+ IN KPROCESSOR_MODE Mode)
+{
+ //
+ // Check if we're in kernel-mode, and force CPL 0 if so.
+ // Otherwise, force CPL 3.
+ //
+ return ((Mode == KernelMode) ?
+ (Cs & (0xFFFF & ~RPL_MASK)) :
+ (RPL_MASK | (Cs & 0xFFFF)));
+}
+
+//
+// Sanitizes EFLAGS
+//
+FORCEINLINE
+ULONG
+Ke386SanitizeFlags(IN ULONG Eflags,
+ IN KPROCESSOR_MODE Mode)
+{
+ //
+ // Check if we're in kernel-mode, and sanitize EFLAGS if so.
+ // Otherwise, also force interrupt mask on.
+ //
+ return ((Mode == KernelMode) ?
+ (Eflags & (EFLAGS_USER_SANITIZE | EFLAGS_INTERRUPT_MASK)) :
+ (EFLAGS_INTERRUPT_MASK | (Eflags & EFLAGS_USER_SANITIZE)));
+}
+
+//
+// Gets a DR register from a CONTEXT structure
+//
+FORCEINLINE
+PVOID
+KiDrFromContext(IN ULONG Dr,
+ IN PCONTEXT Context)
+{
+ return *(PVOID*)((ULONG_PTR)Context + KiDebugRegisterContextOffsets[Dr]);
+}
+
+//
+// Gets a DR register from a KTRAP_FRAME structure
+//
+FORCEINLINE
+PVOID*
+KiDrFromTrapFrame(IN ULONG Dr,
+ IN PKTRAP_FRAME TrapFrame)
+{
+ return (PVOID*)((ULONG_PTR)TrapFrame + KiDebugRegisterTrapOffsets[Dr]);
+}
+
+//
+//
+//
+FORCEINLINE
+PVOID
+Ke386SanitizeDr(IN PVOID DrAddress,
+ IN KPROCESSOR_MODE Mode)
+{
+ //
+ // Check if we're in kernel-mode, and return the address directly if so.
+ // Otherwise, make sure it's not inside the kernel-mode address space.
+ // If it is, then clear the address.
+ //
+ return ((Mode == KernelMode) ? DrAddress :
+ (DrAddress <= MM_HIGHEST_USER_ADDRESS) ? DrAddress : 0);
+}
//
// Enters a Guarded Region
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/mm.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h Fri Dec 29 21:49:00 2006
@@ -686,17 +686,10 @@
NTSTATUS
NTAPI
MmAccessFault(
- KPROCESSOR_MODE Mode,
- ULONG_PTR Address,
- BOOLEAN FromMdl
-);
-
-NTSTATUS
-NTAPI
-MmNotPresentFault(
- KPROCESSOR_MODE Mode,
- ULONG_PTR Address,
- BOOLEAN FromMdl
+ IN BOOLEAN StoreInstruction,
+ IN PVOID Address,
+ IN KPROCESSOR_MODE Mode,
+ IN PVOID TrapInformation
);
/* anonmem.c *****************************************************************/
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ob.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h Fri Dec 29 21:49:00 2006
@@ -188,9 +188,10 @@
// Object Lifetime Functions
//
VOID
-FASTCALL
+NTAPI
ObpDeleteObject(
- IN PVOID Object
+ IN PVOID Object,
+ IN BOOLEAN CalledFromWorkerThread
);
LONG
Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/cpu.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/cpu.c Fri Dec 29 21:49:00 2006
@@ -29,17 +29,17 @@
/* The TSS to use for NMI Fault Traps (INT 0x2) */
UCHAR KiNMITSS[KTSS_IO_MAPS];
-/* The Boot GDT (FIXME: should have more entries */
-KGDTENTRY KiBootGdt[12] =
+/* The Boot GDT */
+KGDTENTRY KiBootGdt[256] =
{
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_NULL */
- {0xffff, 0x0000, {{0x00, 0x9a, 0xcf, 0x00}}}, /* KGDT_R0_CODE */
- {0xffff, 0x0000, {{0x00, 0x92, 0xcf, 0x00}}}, /* KGDT_R0_DATA */
- {0xffff, 0x0000, {{0x00, 0xfa, 0xcf, 0x00}}}, /* KGDT_R3_CODE */
- {0xffff, 0x0000, {{0x00, 0xf2, 0xcf, 0x00}}}, /* KGDT_R3_DATA*/
+ {0xffff, 0x0000, {{0x00, 0x9b, 0xcf, 0x00}}}, /* KGDT_R0_CODE */
+ {0xffff, 0x0000, {{0x00, 0x93, 0xcf, 0x00}}}, /* KGDT_R0_DATA */
+ {0xffff, 0x0000, {{0x00, 0xfb, 0xcf, 0x00}}}, /* KGDT_R3_CODE */
+ {0xffff, 0x0000, {{0x00, 0xf3, 0xcf, 0x00}}}, /* KGDT_R3_DATA*/
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_TSS */
- {0x0fff, 0x0000, {{0x00, 0x92, 0x00, 0xff}}}, /* KGDT_R0_PCR */
- {0x0fff, 0x0000, {{0x00, 0xf2, 0x00, 0x00}}}, /* KGDT_R3_TEB */
+ {0x0fff, 0x0000, {{0x00, 0x93, 0xc0, 0xff}}}, /* KGDT_R0_PCR */
+ {0x0fff, 0x0000, {{0x00, 0xf3, 0x40, 0x00}}}, /* KGDT_R3_TEB */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_UNUSED */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_LDT */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_DF_TSS */
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/exp.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/exp.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/exp.c Fri Dec 29 21:49:00 2006
@@ -14,6 +14,36 @@
#define NDEBUG
#include <debug.h>
+/* GLOBALS *******************************************************************/
+
+/* DR Registers in the CONTEXT structure */
+UCHAR KiDebugRegisterContextOffsets[9] =
+{
+ FIELD_OFFSET(CONTEXT, Dr0),
+ FIELD_OFFSET(CONTEXT, Dr1),
+ FIELD_OFFSET(CONTEXT, Dr2),
+ FIELD_OFFSET(CONTEXT, Dr3),
+ 0,
+ 0,
+ FIELD_OFFSET(CONTEXT, Dr6),
+ FIELD_OFFSET(CONTEXT, Dr7),
+ 0,
+};
+
+/* DR Registers in the KTRAP_FRAME structure */
+UCHAR KiDebugRegisterTrapOffsets[9] =
+{
+ FIELD_OFFSET(KTRAP_FRAME, Dr0),
+ FIELD_OFFSET(KTRAP_FRAME, Dr1),
+ FIELD_OFFSET(KTRAP_FRAME, Dr2),
+ FIELD_OFFSET(KTRAP_FRAME, Dr3),
+ 0,
+ 0,
+ FIELD_OFFSET(KTRAP_FRAME, Dr6),
+ FIELD_OFFSET(KTRAP_FRAME, Dr7),
+ 0,
+};
+
/* FUNCTIONS *****************************************************************/
_SEH_DEFINE_LOCALS(KiCopyInfo)
@@ -51,6 +81,101 @@
KiIdt[i].Selector = KiIdt[i].ExtendedOffset;
KiIdt[i].ExtendedOffset = FlippedSelector;
}
+}
+
+ULONG
+FASTCALL
+KiUpdateDr7(IN ULONG Dr7)
+{
+ ULONG DebugMask = KeGetCurrentThread()->DispatcherHeader.DebugActive;
+
+ /* Check if debugging is enabled */
+ if (DebugMask & DR_ACTIVE_MASK)
+ {
+ /* Sanity checks */
+ ASSERT((DebugMask & DR_REG_MASK) != 0);
+ ASSERT((Dr7 & ~DR7_RESERVED_MASK) == DR7_OVERRIDE_MASK);
+ return 0;
+ }
+
+ /* Return DR7 itself */
+ return Dr7;
+}
+
+BOOLEAN
+FASTCALL
+KiRecordDr7(OUT PULONG Dr7Ptr,
+ OUT PULONG DrMask)
+{
+ ULONG NewMask, Mask;
+ UCHAR Result;
+
+ /* Check if the caller gave us a mask */
+ if (!DrMask)
+ {
+ /* He didn't use the one from the thread */
+ Mask = KeGetCurrentThread()->DispatcherHeader.DebugActive;
+ }
+ else
+ {
+ /* He did, read it */
+ Mask = *DrMask;
+ }
+
+ /* Sanity check */
+ ASSERT((*Dr7Ptr & DR7_RESERVED_MASK) == 0);
+
+ /* Check if DR7 is empty */
+ NewMask = Mask;
+ if (!(*Dr7Ptr))
+ {
+ /* Assume failure */
+ Result = FALSE;
+
+ /* Check the DR mask */
+ NewMask &= 0x7F;
+ if (NewMask & DR_REG_MASK)
+ {
+ /* Set the active mask */
+ NewMask |= DR_ACTIVE_MASK;
+
+ /* Set DR7 override */
+ *DrMask = DR7_OVERRIDE_MASK;
+ }
+ else
+ {
+ /* Sanity check */
+ ASSERT(NewMask == 0);
+ }
+ }
+ else
+ {
+ /* Check if we have a mask or not */
+ Result = NewMask ? TRUE: FALSE;
+
+ /* Update the mask to disable debugging */
+ NewMask &= ~DR_ACTIVE_MASK;
+ NewMask |= 0x80;
+ }
+
+ /* Check if caller wants the new mask */
+ if (DrMask)
+ {
+ /* Update it */
+ *DrMask = NewMask;
+ }
+ else
+ {
+ /* Check if the mask changed */
+ if (Mask != NewMask)
+ {
+ /* Update it */
+ KeGetCurrentThread()->DispatcherHeader.DebugActive = NewMask;
+ }
+ }
+
+ /* Return the result */
+ return Result;
}
ULONG
@@ -192,6 +317,8 @@
ULONG i;
BOOLEAN V86Switch = FALSE;
KIRQL OldIrql = APC_LEVEL;
+ ULONG DrMask = 0;
+ PVOID SafeDr;
/* Do this at APC_LEVEL */
if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
@@ -207,8 +334,8 @@
V86Switch = TRUE;
}
- /* Copy EFLAGS. FIXME: Needs to be sanitized */
- TrapFrame->EFlags = Context->EFlags;
+ /* Copy EFLAGS and sanitize them*/
+ TrapFrame->EFlags = Ke386SanitizeFlags(Context->EFlags, PreviousMode);
/* Copy EBP and EIP */
TrapFrame->Ebp = Context->Ebp;
@@ -222,14 +349,14 @@
}
else
{
- /* We weren't in V86, so sanitize the CS (FIXME!) */
- TrapFrame->SegCs = Context->SegCs;
+ /* We weren't in V86, so sanitize the CS */
+ TrapFrame->SegCs = Ke386SanitizeSeg(Context->SegCs, PreviousMode);
/* Don't let it under 8, that's invalid */
if ((PreviousMode != KernelMode) && (TrapFrame->SegCs < 8))
{
/* Force it to User CS */
- TrapFrame->SegCs = (KGDT_R3_CODE | RPL_MASK);
+ TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
}
}
@@ -261,7 +388,7 @@
/* Check if we were in V86 Mode */
if (TrapFrame->EFlags & EFLAGS_V86_MASK)
{
- /* Copy the V86 Segments directlry */
+ /* Copy the V86 Segments directly */
TrapFrame->V86Ds = Context->SegDs;
TrapFrame->V86Es = Context->SegEs;
TrapFrame->V86Fs = Context->SegFs;
@@ -272,12 +399,12 @@
/* For kernel mode, write the standard values */
TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
- TrapFrame->SegFs = Context->SegFs;
+ TrapFrame->SegFs = Ke386SanitizeSeg(Context->SegFs, PreviousMode);
TrapFrame->SegGs = 0;
}
else
{
- /* For user mode, return the values directlry */
+ /* For user mode, return the values directly */
TrapFrame->SegDs = Context->SegDs;
TrapFrame->SegEs = Context->SegEs;
TrapFrame->SegFs = Context->SegFs;
@@ -320,7 +447,13 @@
/* Mask out any invalid flags */
FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
- /* FIXME: Check if this is a VDM app */
+ /* Check if this is a VDM app */
+ if (PsGetCurrentProcess()->VdmObjects)
+ {
+ /* Allow the EM flag */
+ FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
+ (CR0_EM | CR0_MP);
+ }
}
}
@@ -373,16 +506,40 @@
}
else
{
- /* Just dump the Fn state in */
- RtlCopyMemory(&FxSaveArea->U.FnArea,
- &Context->FloatSave,
- sizeof(FNSAVE_FORMAT));
+ /* Copy the structure */
+ FxSaveArea->U.FnArea.ControlWord = Context->FloatSave.
+ ControlWord;
+ FxSaveArea->U.FnArea.StatusWord = Context->FloatSave.
+ StatusWord;
+ FxSaveArea->U.FnArea.TagWord = Context->FloatSave.TagWord;
+ FxSaveArea->U.FnArea.ErrorOffset = Context->FloatSave.
+ ErrorOffset;
+ FxSaveArea->U.FnArea.ErrorSelector = Context->FloatSave.
+ ErrorSelector;
+ FxSaveArea->U.FnArea.DataOffset = Context->FloatSave.
+ DataOffset;
+ FxSaveArea->U.FnArea.DataSelector = Context->FloatSave.
+ DataSelector;
+
+ /* Loop registers */
+ for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
+ {
+ /* Copy registers */
+ FxSaveArea->U.FnArea.RegisterArea[i] =
+ Context->FloatSave.RegisterArea[i];
+ }
}
/* Mask out any invalid flags */
FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
- /* FIXME: Check if this is a VDM app */
+ /* Check if this is a VDM app */
+ if (PsGetCurrentProcess()->VdmObjects)
+ {
+ /* Allow the EM flag */
+ FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
+ (CR0_EM | CR0_MP);
+ }
}
else
{
@@ -394,22 +551,37 @@
/* Handle the Debug Registers */
if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
{
- /* FIXME: All these should be sanitized */
- TrapFrame->Dr0 = Context->Dr0;
- TrapFrame->Dr1 = Context->Dr1;
- TrapFrame->Dr2 = Context->Dr2;
- TrapFrame->Dr3 = Context->Dr3;
- TrapFrame->Dr6 = Context->Dr6;
- TrapFrame->Dr7 = Context->Dr7;
-
- /* Check if usermode */
+ /* Loop DR registers */
+ for (i = 0; i < 4; i++)
+ {
+ /* Sanitize the context DR Address */
+ SafeDr = Ke386SanitizeDr(KiDrFromContext(i, Context), PreviousMode);
+
+ /* Save it in the trap frame */
+ *KiDrFromTrapFrame(i, TrapFrame) = SafeDr;
+
+ /* Check if this DR address is active and add it in the DR mask */
+ if (SafeDr) DrMask |= DR_MASK(i);
+ }
+
+ /* Now save and sanitize DR6 */
+ TrapFrame->Dr6 = Context->Dr6 & DR6_LEGAL;
+ if (TrapFrame->Dr6) DrMask |= DR_MASK(6);
+
+ /* Save and sanitize DR7 */
+ TrapFrame->Dr7 = Context->Dr7 & DR7_LEGAL;
+ KiRecordDr7(&TrapFrame->Dr7, &DrMask);
+
+ /* If we're in user-mode */
if (PreviousMode != KernelMode)
{
- /* Set the Debug Flag */
- KeGetCurrentThread()->DispatcherHeader.DebugActive =
- (Context->Dr7 & DR7_ACTIVE) ? TRUE: FALSE;
- }
- }
+ /* FIXME: Save the mask */
+ //KeGetCurrentThread()->DispatcherHeader.DebugActive = DrMask;
+ }
+ }
+
+ /* Check if thread has IOPL and force it enabled if so */
+ if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= 0x3000;
/* Restore IRQL */
if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
@@ -429,6 +601,7 @@
} FloatSaveBuffer;
FLOATING_SAVE_AREA *FloatSaveArea;
KIRQL OldIrql = APC_LEVEL;
+ ULONG i;
/* Do this at APC_LEVEL */
if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
@@ -550,10 +723,23 @@
KiFlushNPXState(NULL);
}
- /* Copy into the Context */
- RtlCopyMemory(&Context->FloatSave,
- FloatSaveArea,
- sizeof(FNSAVE_FORMAT));
+ /* Copy structure */
+ Context->FloatSave.ControlWord = FloatSaveArea->ControlWord;
+ Context->FloatSave.StatusWord = FloatSaveArea->StatusWord;
+ Context->FloatSave.TagWord = FloatSaveArea->TagWord;
+ Context->FloatSave.ErrorOffset = FloatSaveArea->ErrorOffset;
+ Context->FloatSave.ErrorSelector = FloatSaveArea->ErrorSelector;
+ Context->FloatSave.DataOffset = FloatSaveArea->DataOffset;
+ Context->FloatSave.DataSelector = FloatSaveArea->DataSelector;
+ Context->FloatSave.Cr0NpxState = FxSaveArea->Cr0NpxState;
+
+ /* Loop registers */
+ for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
+ {
+ /* Copy them */
+ Context->FloatSave.RegisterArea[i] =
+ FloatSaveArea->RegisterArea[i];
+ }
}
else
{
@@ -566,24 +752,26 @@
if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
CONTEXT_DEBUG_REGISTERS)
{
- /* Copy the debug registers */
- Context->Dr0 = TrapFrame->Dr0;
- Context->Dr1 = TrapFrame->Dr1;
- Context->Dr2 = TrapFrame->Dr2;
- Context->Dr3 = TrapFrame->Dr3;
- Context->Dr6 = TrapFrame->Dr6;
-
- /* For user-mode, only set DR7 if a debugger is active */
- if (((TrapFrame->SegCs & MODE_MASK) ||
- (TrapFrame->EFlags & EFLAGS_V86_MASK)) &&
- (KeGetCurrentThread()->DispatcherHeader.DebugActive))
- {
- /* Copy it over */
- Context->Dr7 = TrapFrame->Dr7;
+ /* Make sure DR7 is valid */
+ if (TrapFrame->Dr7 & ~DR7_RESERVED_MASK)
+ {
+ /* Copy the debug registers */
+ Context->Dr0 = TrapFrame->Dr0;
+ Context->Dr1 = TrapFrame->Dr1;
+ Context->Dr2 = TrapFrame->Dr2;
+ Context->Dr3 = TrapFrame->Dr3;
+ Context->Dr6 = TrapFrame->Dr6;
+
+ /* Update DR7 */
+ //Context->Dr7 = KiUpdateDr7(TrapFrame->Dr7);
}
else
{
- /* Clear it */
+ /* Otherwise clear DR registers */
+ Context->Dr0 =
+ Context->Dr1 =
+ Context->Dr3 =
+ Context->Dr6 =
Context->Dr7 = 0;
}
}
@@ -757,13 +945,13 @@
KiEspToTrapFrame(TrapFrame, NewStack - 2 * sizeof(ULONG_PTR));
/* Force correct segments */
- TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
- TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
- TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
- TrapFrame->SegFs = KGDT_R3_TEB | RPL_MASK;
+ TrapFrame->SegCs = Ke386SanitizeSeg(KGDT_R3_CODE, PreviousMode);
+ TrapFrame->SegDs = Ke386SanitizeSeg(KGDT_R3_DATA, PreviousMode);
+ TrapFrame->SegEs = Ke386SanitizeSeg(KGDT_R3_DATA, PreviousMode);
+ TrapFrame->SegFs = Ke386SanitizeSeg(KGDT_R3_TEB, PreviousMode);
TrapFrame->SegGs = 0;
- /* Set EIP to the User-mode Dispathcer */
+ /* Set EIP to the User-mode Dispatcher */
TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher;
_SEH_LEAVE;
}
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s Fri Dec 29 21:49:00 2006
@@ -87,13 +87,17 @@
_UnexpectedMsg:
.asciz "\n\x7\x7!!! Unexpected Interrupt %02lx !!!\n"
+_UnhandledMsg:
+ .asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"
+
/* SOFTWARE INTERRUPT SERVICES ***********************************************/
.text
_KiGetTickCount:
_KiCallbackReturn:
_KiRaiseAssertion:
- int 3
+ /* FIXME: TODO */
+ UNHANDLED_PATH
.func KiSystemService
Dr_kss: DR_TRAP_FIXUP
@@ -144,6 +148,7 @@
/* Check if we should flush the User Batch */
xor ebx, ebx
+ReadBatch:
or ebx, [ecx+TEB_GDI_BATCH_COUNT]
jz NotWin32K
@@ -432,8 +437,8 @@
iret
AbiosExit:
- /* Not yet supported */
- int 3
+ /* FIXME: TODO */
+ UNHANDLED_PATH
.func KiDebugService
Dr_kids: DR_TRAP_FIXUP
@@ -672,6 +677,13 @@
/* HARDWARE TRAP HANDLERS ****************************************************/
+.func KiFixupFrame
+_KiFixupFrame:
+
+ /* TODO: Routine to fixup a KTRAP_FRAME when faulting from a syscall. */
+ UNHANDLED_PATH
+.endfunc
+
.func KiTrap0
Dr_kit0: DR_TRAP_FIXUP
V86_kit0: V86_TRAP_FIXUP
@@ -710,7 +722,8 @@
/* We don't support this yet! */
V86Int0:
- int 3
+ /* FIXME: TODO */
+ UNHANDLED_PATH
.endfunc
.func KiTrap1
@@ -754,7 +767,7 @@
jz EnableInterrupts
/* We don't support VDM! */
- int 3
+ UNHANDLED_PATH
.endfunc
.globl _KiTrap2
@@ -813,7 +826,7 @@
jz EnableInterrupts3
/* We don't support VDM! */
- int 3
+ UNHANDLED_PATH
.endfunc
.func KiTrap4
@@ -855,7 +868,7 @@
/* We don't support this yet! */
V86Int4:
- int 3
+ UNHANDLED_PATH
.endfunc
.func KiTrap5
@@ -901,7 +914,7 @@
/* We don't support this yet! */
V86Int5:
- int 3
+ UNHANDLED_PATH
.endfunc
.func KiTrap6
@@ -917,8 +930,7 @@
V86_TRAP_PROLOG kit6
/* Not yet supported (Invalid OPCODE from V86) */
- int 3
- jmp $
+ UNHANDLED_PATH
NotV86UD:
/* Push error code */
@@ -993,8 +1005,7 @@
IsVdmOpcode:
/* Unhandled yet */
- int 3
- jmp $
+ UNHANDLED_PATH
/* Return to caller */
jmp _Kei386EoiHelper@0
@@ -1302,8 +1313,7 @@
jz HandleUserNpx
/* V86 NPX not handled */
- int 3
- jmp $
+ UNHANDLED_PATH
EmulationEnabled:
/* Did this come from kernel-mode? */
@@ -1456,7 +1466,7 @@
jnz NoReflect
/* FIXME: TODO */
- int 3
+ UNHANDLED_PATH
NoReflect:
@@ -1485,9 +1495,21 @@
test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jnz UserModeGpf
- /* FIXME: Check for GPF during GPF */
+ /* Check if we have a VDM alert */
+ cmp dword ptr fs:[KPCR_VDM_ALERT], 0
+ jnz VdmAlertGpf
+
+ /* Check for GPF during GPF */
+ mov eax, [ebp+KTRAP_FRAME_EIP]
+ cmp eax, offset CheckPrivilegedInstruction
+ jbe KmodeGpf
+ cmp eax, offset CheckPrivilegedInstruction2
+
+ /* FIXME: TODO */
+ UNHANDLED_PATH
/* Get the opcode and trap frame */
+KmodeGpf:
mov eax, [ebp+KTRAP_FRAME_EIP]
mov eax, [eax]
mov edx, [ebp+KTRAP_FRAME_EBP]
@@ -1573,8 +1595,7 @@
MsrCheck:
/* FIXME: Handle RDMSR/WRMSR */
- int 3
- jmp $
+ UNHANDLED_PATH
NotIretGpf:
@@ -1606,7 +1627,6 @@
lea eax, [ebp+KTRAP_FRAME_ESP]
cmp edx, eax
jz HandleSegPop
- int 3
/* Handle segment POP fault by setting it to 0 */
HandleSegPop:
@@ -1620,26 +1640,239 @@
UserModeGpf:
- /* FIXME: Unhandled */
- int 3
- jmp $
+ /* If the previous mode was kernel, raise a fatal exception */
+ mov eax, 13
+ test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
+ jz _KiSystemFatalException
+
+ /* Get the process and check which CS this came from */
+ mov ebx, fs:[KPCR_CURRENT_THREAD]
+ mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
+ cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
+ jz CheckVdmGpf
+
+ /* Check if this is a VDM */
+ cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
+ jnz DispatchV86Gpf
+
+ /* Enable interrupts and check if we have an error code */
+ sti
+ cmp word ptr [ebp+KTRAP_FRAME_ERROR_CODE], 0
+ jnz SetException
+ jmp CheckPrivilegedInstruction
+
+HandleSegPop2:
+ /* Update EIP (will be updated below again) */
+ add dword ptr [ebp+KTRAP_FRAME_EIP], 1
+
+HandleBop4:
+ /* Clear the segment, update EIP and ESP */
+ mov dword ptr [edx], 0
+ add dword ptr [ebp+KTRAP_FRAME_EIP], 1
+ add dword ptr [ebp+KTRAP_FRAME_ESP], 4
+ jmp _Kei386EoiHelper@0
+
+CheckVdmGpf:
+ /* Check if this is a VDM */
+ cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
+ jz CheckPrivilegedInstruction
+
+ /* Check what kind of instruction this is */
+ mov eax, [ebp+KTRAP_FRAME_EIP]
+ mov eax, [eax]
+
+ /* FIXME: Check for BOP4 */
+
+ /* Check if this is POP FS */
+ mov edx, ebp
+ add edx, KTRAP_FRAME_FS
+ cmp ax, 0xA10F
+ jz HandleSegPop2
+
+ /* Check if this is POP GS */
+ add edx, KTRAP_FRAME_GS - KTRAP_FRAME_FS
+ cmp ax, 0xA90F
+ jz HandleSegPop2
+
+CheckPrivilegedInstruction:
+ /* FIXME */
+ UNHANDLED_PATH
+
+CheckPrivilegedInstruction2:
+ /* FIXME */
+ UNHANDLED_PATH
+
+SetException:
+ /* FIXME */
+ UNHANDLED_PATH
+
+DispatchV86Gpf:
+ /* FIXME */
+ UNHANDLED_PATH
.endfunc
.func KiTrap14
Dr_kit14: DR_TRAP_FIXUP
V86_kit14: V86_TRAP_FIXUP
_KiTrap14:
+
/* Enter trap */
TRAP_PROLOG kit14
- /* Call the C exception handler */
- push 14
+ /* Check if we have a VDM alert */
+ cmp dword ptr fs:[KPCR_VDM_ALERT], 0
+ jnz VdmAlertGpf
+
+ /* Get the current thread */
+ mov edi, fs:[KPCR_CURRENT_THREAD]
+
+ /* Get the stack address of the frame */
+ lea eax, [esp+KTRAP_FRAME_LENGTH+NPX_FRAME_LENGTH]
+ sub eax, [edi+KTHREAD_INITIAL_STACK]
+ jz NoFixUp
+
+ /* This isn't the base frame, check if it's the second */
+ cmp eax, -KTRAP_FRAME_EFLAGS
+ jb NoFixUp
+
+ /* Check if we have a TEB */
+ mov eax, fs:[KPCR_TEB]
+ or eax, eax
+ jle NoFixUp
+
+ /* Fixup the frame */
+ call _KiFixupFrame
+
+ /* Save CR2 */
+NoFixUp:
+ mov edi, cr2
+
+ /* ROS HACK: Sometimes we get called with INTS DISABLED! WTF? */
+ 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
+
+HandlePf:
+ /* Send trap frame and check if this is kernel-mode or usermode */
push ebp
- call _KiPageFaultHandler
- add esp, 8
-
- /* Return to caller */
+ mov eax, [ebp+KTRAP_FRAME_CS]
+ and eax, MODE_MASK
+ push eax
+
+ /* Send faulting address and check if this is read or write */
+ push edi
+ mov eax, [ebp+KTRAP_FRAME_ERROR_CODE]
+ and eax, 1
+ push eax
+
+ /* Call the access fault handler */
+ call _MmAccessFault@16
+ test eax, eax
+ jl AccessFail
+
+ /* Access fault handled, return to caller */
jmp _Kei386EoiHelper@0
+
+AccessFail:
+ /* First check if this is a fault in the S-LIST functions */
+ mov ecx, offset _ExpInterlockedPopEntrySListFault@0
+ cmp [ebp+KTRAP_FRAME_EIP], ecx
+ jz SlistFault
+
+ /* Check if this is a fault in the syscall handler */
+ mov ecx, offset CopyParams
+ cmp [ebp+KTRAP_FRAME_EIP], ecx
+ jz SysCallCopyFault
+ mov ecx, offset ReadBatch
+ cmp [ebp+KTRAP_FRAME_EIP], ecx
+ jnz CheckVdmPf
+
+ /* FIXME: TODO */
+ UNHANDLED_PATH
+ jmp _Kei386EoiHelper@0
+
+SysCallCopyFault:
+ /* FIXME: TODO */
+ UNHANDLED_PATH
+ jmp _Kei386EoiHelper@0
+
+ /* Check if the fault occured in a V86 mode */
+CheckVdmPf:
+ mov ecx, [ebp+KTRAP_FRAME_ERROR_CODE]
+ and ecx, 1
+ shr ecx, 1
+ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
+ jnz VdmPF
+
+ /* Check if the fault occured in a VDM */
+ mov esi, fs:[KPCR_CURRENT_THREAD]
+ mov esi, [esi+KTHREAD_APCSTATE_PROCESS]
+ cmp dword ptr [esi+EPROCESS_VDM_OBJECTS], 0
+ jz CheckStatus
+
+ /* Check if we this was in kernel-mode */
+ test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
+ jz CheckStatus
+ cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
+ jz CheckStatus
+
+VdmPF:
+ /* FIXME: TODO */
+ UNHANDLED_PATH
+
+ /* Save EIP and check what kind of status failure we got */
+CheckStatus:
+ mov esi, [ebp+KTRAP_FRAME_EIP]
+ cmp eax, STATUS_ACCESS_VIOLATION
+ je AccessViol
+ cmp eax, STATUS_GUARD_PAGE_VIOLATION
+ je SpecialCode
+ cmp eax, STATUS_STACK_OVERFLOW
+ je SpecialCode
+
+ /* Setup an in-page exception to dispatch */
+ mov edx, ecx
+ mov ebx, esi
+ mov esi, edi
+ mov ecx, 3
+ mov edi, eax
+ mov eax, STATUS_IN_PAGE_ERROR
+ call _CommonDispatchException
+
+AccessViol:
+ /* Use more proper status code */
+ mov eax, KI_EXCEPTION_ACCESS_VIOLATION
+
+SpecialCode:
+ /* Setup a normal page fault exception */
+ mov ebx, esi
+ mov edx, ecx
+ mov esi, edi
+ jmp _DispatchTwoParam
+
+SlistFault:
+ /* FIXME: TODO */
+ UNHANDLED_PATH
+
+IllegalState:
+
+ /* This is completely illegal, bugcheck the system */
+ push ebp
+ push esi
+ push ecx
+ push eax
+ push edi
+ push IRQL_NOT_LESS_OR_EQUAL
+ call _KeBugCheckWithTf@24
+
+VdmAlertGpf:
+
+ /* FIXME: NOT SUPPORTED */
+ UNHANDLED_PATH
.endfunc
.func KiTrap0F
@@ -1752,8 +1985,7 @@
add esp, [eax+KTHREAD_INITIAL_STACK]
/* Switch to good stack segment */
- /* TODO */
- int 3
+ UNHANDLED_PATH
.endfunc
/* UNEXPECTED INTERRUPT HANDLERS **********************************************/
@@ -1867,7 +2099,7 @@
jz Return
/* FIXME: Schedule new thread */
- int 3
+ UNHANDLED_PATH
Return:
/* All done */
@@ -1904,7 +2136,7 @@
_KiChainedDispatch2ndLvl@0:
/* Not yet supported */
- int 3
+ UNHANDLED_PATH
.endfunc
.func KiChainedDispatch@0
Modified: trunk/reactos/ntoskrnl/ke/i386/usercall.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/usercall.…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/usercall.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/usercall.c Fri Dec 29 21:49:00 2006
@@ -71,7 +71,7 @@
_SEH_DECLARE_LOCALS(KiCopyInfo);
/* Don't deliver APCs in V86 mode */
- if (TrapFrame->EFlags & X86_EFLAGS_VM) return;
+ if (TrapFrame->EFlags & EFLAGS_V86_MASK) return;
/* Save the full context */
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
@@ -102,22 +102,19 @@
TrapFrame->HardwareEsp = Stack;
/* Setup Ring 3 state */
- TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
- TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK;
- TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
- TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
+ TrapFrame->SegCs = Ke386SanitizeSeg(KGDT_R3_CODE, UserMode);
+ TrapFrame->HardwareSegSs = Ke386SanitizeSeg(KGDT_R3_DATA, UserMode);
+ TrapFrame->SegDs = Ke386SanitizeSeg(KGDT_R3_DATA, UserMode);
+ TrapFrame->SegEs = Ke386SanitizeSeg(KGDT_R3_DATA, UserMode);
+ TrapFrame->SegFs = Ke386SanitizeSeg(KGDT_R3_TEB, UserMode);
TrapFrame->SegGs = 0;
+ TrapFrame->ErrCode = 0;
/* Sanitize EFLAGS */
- TrapFrame->EFlags = Context.EFlags & EFLAGS_USER_SANITIZE;
- TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
-
- /* Check if user-mode has IO privileges */
- if (KeGetCurrentThread()->Iopl)
- {
- /* Enable them*/
- TrapFrame->EFlags |= (0x3000);
- }
+ TrapFrame->EFlags = Ke386SanitizeFlags(Context.EFlags, UserMode);
+
+ /* Check if thread has IOPL and force it enabled if so */
+ if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= 0x3000;
/* Setup the stack */
*(PULONG_PTR)(Stack + 0 * sizeof(ULONG_PTR)) = (ULONG_PTR)NormalRoutine;
Removed: trunk/reactos/ntoskrnl/mm/i386/memsafe.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/i386/memsafe.s…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/i386/memsafe.s (original)
+++ trunk/reactos/ntoskrnl/mm/i386/memsafe.s (removed)
@@ -1,17 +1,0 @@
-.globl @MmSafeReadPtr@4
-.globl _MmSafeReadPtrStart
-.globl _MmSafeReadPtrEnd
-
-/*****************************************************************************/
-
- /*
- * PVOID FASTCALL MmSafeReadPtr(PVOID Source)
- */
-@MmSafeReadPtr@4:
-_MmSafeReadPtrStart:
- /*
- * If we incur a pagefault, eax will be set NULL
- */
- movl (%ecx),%eax
-_MmSafeReadPtrEnd:
- ret
Removed: trunk/reactos/ntoskrnl/mm/i386/pfault.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/i386/pfault.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/i386/pfault.c (original)
+++ trunk/reactos/ntoskrnl/mm/i386/pfault.c (removed)
@@ -1,135 +1,0 @@
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/mm/i386/pfault.c
- * PURPOSE: Paging file functions
- *
- * PROGRAMMERS: David Welch (welch(a)mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* EXTERNS *******************************************************************/
-
-extern VOID MmSafeReadPtrStart(VOID);
-extern VOID MmSafeReadPtrEnd(VOID);
-
-
-extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address);
-extern ULONG KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2);
-
-extern BOOLEAN Ke386NoExecute;
-
-/* FUNCTIONS *****************************************************************/
-
-ULONG KiPageFaultHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
-{
- ULONG_PTR cr2;
- NTSTATUS Status;
- KPROCESSOR_MODE Mode;
- EXCEPTION_RECORD Er;
-
- ASSERT(ExceptionNr == 14);
-
- /* get the faulting address */
- cr2 = __readcr2();
- Tf->DbgArgPointer = cr2;
-
- /* it's safe to enable interrupts after cr2 has been saved */
- if (Tf->EFlags & (X86_EFLAGS_VM|X86_EFLAGS_IF))
- {
- _enable();
- }
-
- if (cr2 >= (ULONG_PTR)MmSystemRangeStart)
- {
- /* check for an invalid page directory in kernel mode */
- if (!(Tf->ErrCode & 0x5) &&
Mmi386MakeKernelPageTableGlobal((PVOID)cr2))
- {
- return 0;
- }
-
- /* check for non executable memory in kernel mode */
- if (Ke386NoExecute && Tf->ErrCode & 0x10)
- {
- KEBUGCHECKWITHTF(ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY, 0, 0, 0, 0, Tf);
- }
- }
-
- Mode = Tf->ErrCode & 0x4 ? UserMode : KernelMode;
-
- /* handle the fault */
- if (Tf->ErrCode & 0x1)
- {
- Status = MmAccessFault(Mode, cr2, FALSE);
- }
- else
- {
- Status = MmNotPresentFault(Mode, cr2, FALSE);
- }
-
- /* handle the return for v86 mode */
- if (Tf->EFlags & X86_EFLAGS_VM)
- {
- if (!NT_SUCCESS(Status))
- {
- /* FIXME: This should use ->VdmObjects */
- if(!PsGetCurrentProcess()->Pcb.Unused)
- {
- *((PKV86M_TRAP_FRAME)Tf)->regs->PStatus =
STATUS_NONCONTINUABLE_EXCEPTION;
- }
- return 1;
- }
- return 0;
- }
-
- if (Mode == KernelMode)
- {
- if (!NT_SUCCESS(Status))
- {
- if (Tf->Eip >= (ULONG_PTR)MmSafeReadPtrStart &&
- Tf->Eip < (ULONG_PTR)MmSafeReadPtrEnd)
- {
- Tf->Eip = (ULONG_PTR)MmSafeReadPtrEnd;
- Tf->Eax = 0;
- return 0;
- }
- }
- }
- else
- {
- if (KeGetCurrentThread()->ApcState.UserApcPending)
- {
- KIRQL oldIrql;
-
- KeRaiseIrql(APC_LEVEL, &oldIrql);
- KiDeliverApc(UserMode, NULL, NULL);
- KeLowerIrql(oldIrql);
- }
- }
-
- if (NT_SUCCESS(Status))
- {
- return 0;
- }
-
- Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
- Er.ExceptionFlags = 0;
- Er.ExceptionRecord = NULL;
- Er.ExceptionAddress = (PVOID)Tf->Eip;
- Er.NumberParameters = 2;
- Er.ExceptionInformation[0] = Tf->ErrCode & 0x1;
- Er.ExceptionInformation[1] = (ULONG)cr2;
-
- /* FIXME: Which exceptions are noncontinuable? */
- Er.ExceptionFlags = 0;
-
- KiDispatchException(&Er, 0, Tf, Mode, TRUE);
- return 0;
-}
-
Modified: trunk/reactos/ntoskrnl/mm/mdl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mdl.c?rev=2523…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mdl.c (original)
+++ trunk/reactos/ntoskrnl/mm/mdl.c Fri Dec 29 21:49:00 2006
@@ -433,7 +433,7 @@
if (!MmIsPagePresent(NULL, Address))
{
- Status = MmNotPresentFault(Mode, (ULONG_PTR)Address, TRUE);
+ Status = MmAccessFault(FALSE, Address, Mode, NULL);
if (!NT_SUCCESS(Status))
{
for (j = 0; j < i; j++)
@@ -457,7 +457,7 @@
if ((Operation == IoWriteAccess || Operation == IoModifyAccess) &&
(!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE)))
{
- Status = MmAccessFault(Mode, (ULONG_PTR)Address, TRUE);
+ Status = MmAccessFault(TRUE, Address, Mode, NULL);
if (!NT_SUCCESS(Status))
{
for (j = 0; j < i; j++)
Modified: trunk/reactos/ntoskrnl/mm/mm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mm.c?rev=25238…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mm.c (original)
+++ trunk/reactos/ntoskrnl/mm/mm.c Fri Dec 29 21:49:00 2006
@@ -75,9 +75,9 @@
NTSTATUS
NTAPI
-MmAccessFault(KPROCESSOR_MODE Mode,
- ULONG_PTR Address,
- BOOLEAN FromMdl)
+MmpAccessFault(KPROCESSOR_MODE Mode,
+ ULONG_PTR Address,
+ BOOLEAN FromMdl)
{
PMADDRESS_SPACE AddressSpace;
MEMORY_AREA* MemoryArea;
@@ -109,7 +109,7 @@
{
DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode, Address);
DbgPrint("%s:%d\n",__FILE__,__LINE__);
- return(STATUS_UNSUCCESSFUL);
+ return(STATUS_ACCESS_VIOLATION);
}
AddressSpace = MmGetKernelAddressSpace();
}
@@ -131,13 +131,13 @@
{
MmUnlockAddressSpace(AddressSpace);
}
- return (STATUS_UNSUCCESSFUL);
+ return (STATUS_ACCESS_VIOLATION);
}
switch (MemoryArea->Type)
{
case MEMORY_AREA_SYSTEM:
- Status = STATUS_UNSUCCESSFUL;
+ Status = STATUS_ACCESS_VIOLATION;
break;
case MEMORY_AREA_PAGED_POOL:
@@ -152,15 +152,15 @@
break;
case MEMORY_AREA_VIRTUAL_MEMORY:
- Status = STATUS_UNSUCCESSFUL;
+ Status = STATUS_ACCESS_VIOLATION;
break;
case MEMORY_AREA_SHARED_DATA:
- Status = STATUS_UNSUCCESSFUL;
+ Status = STATUS_ACCESS_VIOLATION;
break;
default:
- Status = STATUS_UNSUCCESSFUL;
+ Status = STATUS_ACCESS_VIOLATION;
break;
}
}
@@ -170,32 +170,6 @@
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
- }
- return(Status);
-}
-
-NTSTATUS
-NTAPI
-MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked)
-{
- NTSTATUS Status;
- PFN_TYPE AllocatedPage;
- Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage);
- if (!NT_SUCCESS(Status))
- {
- MmUnlockAddressSpace(MmGetKernelAddressSpace());
- Status = MmRequestPageMemoryConsumer(MC_PPOOL, TRUE, &AllocatedPage);
- MmLockAddressSpace(MmGetKernelAddressSpace());
- }
- Status =
- MmCreateVirtualMapping(NULL,
- (PVOID)PAGE_ROUND_DOWN(Address),
- PAGE_READWRITE,
- &AllocatedPage,
- 1);
- if (Locked)
- {
- MmLockPage(AllocatedPage);
}
return(Status);
}
@@ -227,7 +201,7 @@
DPRINT("No current process\n");
if (Address < (ULONG_PTR)MmSystemRangeStart)
{
- return(STATUS_UNSUCCESSFUL);
+ return(STATUS_ACCESS_VIOLATION);
}
}
@@ -242,7 +216,7 @@
if (Mode != KernelMode)
{
CPRINT("Address: %x\n", Address);
- return(STATUS_UNSUCCESSFUL);
+ return(STATUS_ACCESS_VIOLATION);
}
AddressSpace = MmGetKernelAddressSpace();
}
@@ -268,7 +242,7 @@
{
MmUnlockAddressSpace(AddressSpace);
}
- return (STATUS_UNSUCCESSFUL);
+ return (STATUS_ACCESS_VIOLATION);
}
switch (MemoryArea->Type)
@@ -280,7 +254,7 @@
}
case MEMORY_AREA_SYSTEM:
- Status = STATUS_UNSUCCESSFUL;
+ Status = STATUS_ACCESS_VIOLATION;
break;
case MEMORY_AREA_SECTION_VIEW:
@@ -309,7 +283,7 @@
break;
default:
- Status = STATUS_UNSUCCESSFUL;
+ Status = STATUS_ACCESS_VIOLATION;
break;
}
}
@@ -322,6 +296,67 @@
}
return(Status);
}
+
+extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address);
+
+NTSTATUS
+NTAPI
+MmAccessFault(IN BOOLEAN StoreInstruction,
+ IN PVOID Address,
+ IN KPROCESSOR_MODE Mode,
+ IN PVOID TrapInformation)
+{
+ /* Cute little hack for ROS */
+ if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart)
+ {
+ /* Check for an invalid page directory in kernel mode */
+ if (Mmi386MakeKernelPageTableGlobal(Address))
+ {
+ /* All is well with the world */
+ return STATUS_SUCCESS;
+ }
+ }
+
+ /* Keep same old ReactOS Behaviour */
+ if (StoreInstruction)
+ {
+ /* Call access fault */
+ return MmpAccessFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE);
+ }
+ else
+ {
+ /* Call not present */
+ return MmNotPresentFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE :
TRUE);
+ }
+}
+
+NTSTATUS
+NTAPI
+MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked)
+{
+ NTSTATUS Status;
+ PFN_TYPE AllocatedPage;
+ Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage);
+ if (!NT_SUCCESS(Status))
+ {
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
+ Status = MmRequestPageMemoryConsumer(MC_PPOOL, TRUE, &AllocatedPage);
+ MmLockAddressSpace(MmGetKernelAddressSpace());
+ }
+ Status =
+ MmCreateVirtualMapping(NULL,
+ (PVOID)PAGE_ROUND_DOWN(Address),
+ PAGE_READWRITE,
+ &AllocatedPage,
+ 1);
+ if (Locked)
+ {
+ MmLockPage(AllocatedPage);
+ }
+ return(Status);
+}
+
+
/* Miscellanea functions: they may fit somewhere else */
Modified: trunk/reactos/ntoskrnl/ntoskrnl.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.rbuild?r…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl.rbuild (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl.rbuild Fri Dec 29 21:49:00 2006
@@ -257,9 +257,7 @@
<directory name="mm">
<if property="ARCH" value="i386">
<directory name="i386">
- <file>memsafe.s</file>
<file>page.c</file>
- <file>pfault.c</file>
</directory>
</if>
<file>anonmem.c</file>
Modified: trunk/reactos/ntoskrnl/ob/oblife.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/oblife.c (original)
+++ trunk/reactos/ntoskrnl/ob/oblife.c Fri Dec 29 21:49:00 2006
@@ -134,8 +134,9 @@
}
VOID
-FASTCALL
-ObpDeleteObject(IN PVOID Object)
+NTAPI
+ObpDeleteObject(IN PVOID Object,
+ IN BOOLEAN CalledFromWorkerThread)
{
POBJECT_HEADER Header;
POBJECT_TYPE ObjectType;
@@ -203,12 +204,15 @@
NTAPI
ObpReapObject(IN PVOID Parameter)
{
- POBJECT_HEADER ReapObject;
+ POBJECT_HEADER ReapObject = (PVOID)1;
PVOID NextObject;
/* Start reaping */
- while ((ReapObject = InterlockedExchangePointer(&ObpReaperList, NULL)))
- {
+ do
+ {
+ /* Get the reap object */
+ ReapObject = InterlockedExchangePointer(&ObpReaperList, ReapObject);
+
/* Start deletion loop */
do
{
@@ -216,12 +220,13 @@
NextObject = ReapObject->NextToFree;
/* Delete the object */
- ObpDeleteObject(&ReapObject->Body);
+ ObpDeleteObject(&ReapObject->Body, TRUE);
/* Move to the next one */
ReapObject = NextObject;
- } while (NextObject);
- }
+ } while ((NextObject) && (NextObject != (PVOID)1));
+ } while ((ObpReaperList != (PVOID)1) ||
+ (InterlockedCompareExchange((PLONG)&ObpReaperList, 0, 1) != 1));
}
/*++
Modified: trunk/reactos/ntoskrnl/ob/obref.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obref.c?rev=25…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obref.c (original)
+++ trunk/reactos/ntoskrnl/ob/obref.c Fri Dec 29 21:49:00 2006
@@ -50,21 +50,27 @@
VOID
NTAPI
-ObpDeferObjectDeletion(IN PVOID Object)
-{
- POBJECT_HEADER Header = OBJECT_TO_OBJECT_HEADER(Object);
-
- /* Add us to the list */
+ObpDeferObjectDeletion(IN POBJECT_HEADER Header)
+{
+ PVOID Entry, NewEntry;
+
+ /* Loop while trying to update the list */
do
{
- Header->NextToFree = ObpReaperList;
+ /* Get the current entry */
+ Entry = ObpReaperList;
+
+ /* Link our object to the list */
+ Header->NextToFree = Entry;
+ NewEntry = Header;
+
+ /* Update the list */
} while (InterlockedCompareExchangePointer(&ObpReaperList,
- Header,
- Header->NextToFree) !=
- Header->NextToFree);
-
- /* Queue the work item */
- ExQueueWorkItem(&ObpReaperWorkItem, DelayedWorkQueue);
+ NewEntry,
+ Entry) != Entry);
+
+ /* Queue the work item if needed */
+ if (!Entry) ExQueueWorkItem(&ObpReaperWorkItem, CriticalWorkQueue);
}
LONG
@@ -91,11 +97,7 @@
/* Check whether the object can now be deleted. */
NewCount = InterlockedExchangeAdd(&Header->PointerCount, -Count);
- if (!Count)
- {
- /* Add us to the deferred deletion list */
- ObpDeferObjectDeletion(Object);
- }
+ if (!Count) ObpDeferObjectDeletion(Header);
/* Return the current count */
return NewCount;
@@ -308,12 +310,12 @@
if (KeGetCurrentIrql() == PASSIVE_LEVEL)
{
/* Remove the object */
- ObpDeleteObject(Object);
+ ObpDeleteObject(Object, FALSE);
}
else
{
/* Add us to the deferred deletion list */
- ObpDeferObjectDeletion(Object);
+ ObpDeferObjectDeletion(Header);
}
}
@@ -325,11 +327,13 @@
NTAPI
ObDereferenceObjectDeferDelete(IN PVOID Object)
{
+ POBJECT_HEADER Header = OBJECT_TO_OBJECT_HEADER(Object);
+
/* Check whether the object can now be deleted. */
- if (!(InterlockedDecrement(&OBJECT_TO_OBJECT_HEADER(Object)->PointerCount)))
+ if (!InterlockedDecrement(&Header->PointerCount))
{
/* Add us to the deferred deletion list */
- ObpDeferObjectDeletion(Object);
+ ObpDeferObjectDeletion(Header);
}
}
Modified: trunk/reactos/ntoskrnl/vdm/vdmexec.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/vdm/vdmexec.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/vdm/vdmexec.c (original)
+++ trunk/reactos/ntoskrnl/vdm/vdmexec.c Fri Dec 29 21:49:00 2006
@@ -50,7 +50,7 @@
/* Make sure that we're at APC_LEVEL and that this is a valid frame */
ASSERT_IRQL(APC_LEVEL);
- ASSERT(TrapFrame->DbgArgMark = 0xBADB0D00);
+ ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00);
/* Check if this is a V86 frame */
if (TrapFrame->EFlags & EFLAGS_V86_MASK)
@@ -61,9 +61,9 @@
OutContext->SegEs = TrapFrame->V86Es;
OutContext->SegDs = TrapFrame->V86Ds;
}
- else if (TrapFrame->SegCs == (KGDT_R3_CODE | RPL_MASK))
- {
- /* This was user mode, copy segment registers */
+ else if (TrapFrame->SegCs != (KGDT_R3_CODE | RPL_MASK))
+ {
+ /* This was kernel mode, copy segment registers */
OutContext->SegGs = TrapFrame->SegGs;
OutContext->SegFs = TrapFrame->SegFs;
OutContext->SegEs = TrapFrame->SegEs;