Author: tkreuzer
Date: Sat Feb 4 11:01:19 2012
New Revision: 55404
URL:
http://svn.reactos.org/svn/reactos?rev=55404&view=rev
Log:
[ASM/AMD64]
- Add multiple amd64 asm constant and structure offset definitions
- Add more unwind information to the amd64 trap entry code
- Add IRQL check, APC check and segment sanitize code to trap entry/exit
Modified:
trunk/reactos/include/asm/genincdata.c
trunk/reactos/include/asm/ksamd64.template.h
trunk/reactos/include/asm/trapamd64.inc
Modified: trunk/reactos/include/asm/genincdata.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/asm/genincdata.c?r…
==============================================================================
--- trunk/reactos/include/asm/genincdata.c [iso-8859-1] (original)
+++ trunk/reactos/include/asm/genincdata.c [iso-8859-1] Sat Feb 4 11:01:19 2012
@@ -15,6 +15,16 @@
#include <windbgkd.h>
#include <wdbgexts.h>
#include <kddll.h>
+
+#ifdef _M_AMD64
+enum
+{
+ P1Home = 1 * sizeof(PVOID),
+ P2Home = 2 * sizeof(PVOID),
+ P3Home = 3 * sizeof(PVOID),
+ P4Home = 4 * sizeof(PVOID),
+};
+#endif
// FIXME: where to put this?
typedef struct _FIBER /* Field offsets: */
Modified: trunk/reactos/include/asm/ksamd64.template.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/asm/ksamd64.templa…
==============================================================================
--- trunk/reactos/include/asm/ksamd64.template.h [iso-8859-1] (original)
+++ trunk/reactos/include/asm/ksamd64.template.h [iso-8859-1] Sat Feb 4 11:01:19 2012
@@ -112,10 +112,10 @@
CONSTANT(EXCEPTION_ALIGNMENT_CHECK),
HEADER("Argument Home Address"),
-OFFSET(P1Home, CONTEXT, P1Home),
-OFFSET(P2Home, CONTEXT, P1Home),
-OFFSET(P3Home, CONTEXT, P1Home),
-OFFSET(P4Home, CONTEXT, P1Home),
+CONSTANT(P1Home),
+CONSTANT(P2Home),
+CONSTANT(P3Home),
+CONSTANT(P4Home),
HEADER("CONTEXT"),
OFFSET(CONTEXT_P1Home, CONTEXT, P1Home),
@@ -377,53 +377,55 @@
//OFFSET(PcNumber, KPCR, Number),
//OFFSET(PcInterruptRequest, KPCR, InterruptRequest),
//OFFSET(PcIdleHalt, KPCR, IdleHalt),
-//OFFSET(PcCurrentThread, KPCR, CurrentThread),
+OFFSET(PcCurrentThread, KIPCR, Prcb.CurrentThread),
//OFFSET(PcNextThread, KPCR, NextThread),
//OFFSET(PcIdleThread, KPCR, IdleThread),
//OFFSET(PcIpiFrozen, KPCR, IpiFrozen),
//OFFSET(PcNestingLevel, KPCR, NestingLevel),
-//OFFSET(PcRspBase, KPCR, RspBase),
+OFFSET(PcRspBase, KIPCR, Prcb.RspBase),
//OFFSET(PcPrcbLock, KPCR, PrcbLock),
+OFFSET(PcSetMember, KIPCR, Prcb.SetMember),
#if 0
-OFFSET(PcSetMember, KPCR, SetMember),
-OFFSET(PcCr0, KPCR, Cr0),
-OFFSET(PcCr2, KPCR, Cr2),
-OFFSET(PcCr3, KPCR, Cr3),
-OFFSET(PcCr4, KPCR, Cr4),
-OFFSET(PcKernelDr0, KPCR, KernelDr0),
-OFFSET(PcKernelDr1, KPCR, KernelDr1),
-OFFSET(PcKernelDr2, KPCR, KernelDr2),
-OFFSET(PcKernelDr3, KPCR, KernelDr3),
-OFFSET(PcKernelDr7, KPCR, KernelDr7),
-OFFSET(PcGdtrLimit, KPCR, GdtrLimit),
-OFFSET(PcGdtrBase, KPCR, GdtrBase),
-OFFSET(PcIdtrLimit, KPCR, IdtrLimit),
-OFFSET(PcIdtrBase, KPCR, IdtrBase),
-OFFSET(PcTr, KPCR, Tr),
-OFFSET(PcLdtr, KPCR, Ldtr),
-OFFSET(PcDebugControl, KPCR, DebugControl),
-OFFSET(PcLastBranchToRip, KPCR, LastBranchToRip),
-OFFSET(PcLastBranchFromRip, KPCR, LastBranchFromRip),
-OFFSET(PcLastExceptionToRip, KPCR, LastExceptionToRip),
-OFFSET(PcLastExceptionFromRip, KPCR, LastExceptionFromRip),
-OFFSET(PcCr8, KPCR, Cr8),
-OFFSET(PcCpuType, KPCR, CpuType),
-OFFSET(PcCpuID, KPCR, CpuID),
-OFFSET(PcCpuStep, KPCR, CpuStep),
-OFFSET(PcCpuVendor, KPCR, CpuVendor),
-OFFSET(PcVirtualApicAssist, KPCR, VirtualApicAssist),
-OFFSET(PcCFlushSize, KPCR, CFlushSize),
-OFFSET(PcDeferredReadyListHead, KPCR, DeferredReadyListHead),
-OFFSET(PcSystemCalls, KPCR, SystemCalls),
-OFFSET(PcDpcRoutineActive, KPCR, DpcRoutineActive),
-OFFSET(PcInterruptCount, KPCR, InterruptCount),
-OFFSET(PcDebuggerSavedIRQL, KPCR, DebuggerSavedIRQL),
-OFFSET(PcTickOffset, KPCR, TickOffset),
-OFFSET(PcMasterOffset, KPCR, MasterOffset),
-OFFSET(PcSkipTick, KPCR, SkipTick),
-OFFSET(PcStartCycles, KPCR, StartCycles),
-SIZE(ProcessorControlRegisterLength, KPCR),
+OFFSET(PcCr0, KIPCR, Prcb.Cr0),
+OFFSET(PcCr2, KIPCR, Prcb.Cr2),
+OFFSET(PcCr3, KIPCR, Prcb.Cr3),
+OFFSET(PcCr4, KIPCR, Prcb.Cr4),
+OFFSET(PcKernelDr0, KIPCR, Prcb.KernelDr0),
+OFFSET(PcKernelDr1, KIPCR, Prcb.KernelDr1),
+OFFSET(PcKernelDr2, KIPCR, Prcb.KernelDr2),
+OFFSET(PcKernelDr3, KIPCR, Prcb.KernelDr3),
+OFFSET(PcKernelDr7, KIPCR, Prcb.KernelDr7),
+OFFSET(PcGdtrLimit, KIPCR, Prcb.GdtrLimit),
+OFFSET(PcGdtrBase, KIPCR, Prcb.GdtrBase),
+OFFSET(PcIdtrLimit, KIPCR, IdtrLimit),
+OFFSET(PcIdtrBase, KIPCR, IdtrBase),
+OFFSET(PcTr, KIPCR, Tr),
+OFFSET(PcLdtr, KIPCR, Ldtr),
+OFFSET(PcDebugControl, KIPCR, DebugControl),
+OFFSET(PcLastBranchToRip, KIPCR, LastBranchToRip),
+OFFSET(PcLastBranchFromRip, KIPCR, LastBranchFromRip),
+OFFSET(PcLastExceptionToRip, KIPCR, LastExceptionToRip),
+OFFSET(PcLastExceptionFromRip, KIPCR, LastExceptionFromRip),
+OFFSET(PcCr8, KIPCR, Cr8),
#endif
+OFFSET(PcCpuType, KIPCR, Prcb.CpuType),
+OFFSET(PcCpuID, KIPCR, Prcb.CpuID),
+OFFSET(PcCpuStep, KIPCR, Prcb.CpuStep),
+OFFSET(PcCpuVendor, KIPCR, Prcb.CpuVendor),
+OFFSET(PcCFlushSize, KIPCR, Prcb.CFlushSize),
+OFFSET(PcDeferredReadyListHead, KIPCR, Prcb.DeferredReadyListHead),
+OFFSET(PcSystemCalls, KIPCR, Prcb.KeSystemCalls),
+OFFSET(PcDpcRoutineActive, KIPCR, Prcb.DpcRoutineActive),
+OFFSET(PcInterruptCount, KIPCR, Prcb.InterruptCount),
+OFFSET(PcDebuggerSavedIRQL, KIPCR, Prcb.DebuggerSavedIRQL),
+OFFSET(PcTickOffset, KIPCR, Prcb.TickOffset),
+OFFSET(PcMasterOffset, KIPCR, Prcb.MasterOffset),
+OFFSET(PcSkipTick, KIPCR, Prcb.SkipTick),
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+OFFSET(PcVirtualApicAssist, KIPCR, Prcb.VirtualApicAssist),
+OFFSET(PcStartCycles, KIPCR, Prcb.StartCycles),
+#endif
+SIZE(ProcessorControlRegisterLength, KIPCR),
HEADER("KPROCESSOR_STATE"),
OFFSET(PsSpecialRegisters, KPROCESSOR_STATE, SpecialRegisters),
@@ -578,4 +580,33 @@
OFFSET(EXCEPTION_RECORD_NumberParameters, EXCEPTION_RECORD, NumberParameters),
OFFSET(EXCEPTION_RECORD_ExceptionInformation, EXCEPTION_RECORD, ExceptionInformation),
+HEADER("KTHREAD"),
OFFSET(KTHREAD_WAIT_IRQL, KTHREAD, WaitIrql),
+OFFSET(KTHREAD_TrapFrame, KTHREAD, TrapFrame),
+OFFSET(KTHREAD_PreviousMode, KTHREAD, PreviousMode),
+OFFSET(KTHREAD_KernelStack, KTHREAD, KernelStack),
+OFFSET(KTHREAD_UserApcPending, KTHREAD, ApcState.UserApcPending),
+
+HEADER("KINTERRUPT"),
+
+OFFSET(KINTERRUPT_Type, KINTERRUPT, Type),
+OFFSET(KINTERRUPT_Size, KINTERRUPT, Size),
+OFFSET(KINTERRUPT_InterruptListEntry, KINTERRUPT, InterruptListEntry),
+OFFSET(KINTERRUPT_ServiceRoutine, KINTERRUPT, ServiceRoutine),
+OFFSET(KINTERRUPT_ServiceContext, KINTERRUPT, ServiceContext),
+OFFSET(KINTERRUPT_SpinLock, KINTERRUPT, SpinLock),
+OFFSET(KINTERRUPT_TickCount, KINTERRUPT, TickCount),
+OFFSET(KINTERRUPT_ActualLock, KINTERRUPT, ActualLock),
+OFFSET(KINTERRUPT_DispatchAddress, KINTERRUPT, DispatchAddress),
+OFFSET(KINTERRUPT_Vector, KINTERRUPT, Vector),
+OFFSET(KINTERRUPT_Irql, KINTERRUPT, Irql),
+OFFSET(KINTERRUPT_SynchronizeIrql, KINTERRUPT, SynchronizeIrql),
+OFFSET(KINTERRUPT_FloatingSave, KINTERRUPT, FloatingSave),
+OFFSET(KINTERRUPT_Connected, KINTERRUPT, Connected),
+OFFSET(KINTERRUPT_Number, KINTERRUPT, Number),
+OFFSET(KINTERRUPT_ShareVector, KINTERRUPT, ShareVector),
+OFFSET(KINTERRUPT_Mode, KINTERRUPT, Mode),
+OFFSET(KINTERRUPT_ServiceCount, KINTERRUPT, ServiceCount),
+OFFSET(KINTERRUPT_DispatchCount, KINTERRUPT, DispatchCount),
+OFFSET(KINTERRUPT_TrapFrame, KINTERRUPT, TrapFrame),
+OFFSET(KINTERRUPT_DispatchCode, KINTERRUPT, DispatchCode),
Modified: trunk/reactos/include/asm/trapamd64.inc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/asm/trapamd64.inc?…
==============================================================================
--- trunk/reactos/include/asm/trapamd64.inc [iso-8859-1] (original)
+++ trunk/reactos/include/asm/trapamd64.inc [iso-8859-1] Sat Feb 4 11:01:19 2012
@@ -11,6 +11,7 @@
TF_HAS_ERROR_CODE = HEX(40)
TF_SEND_EOI = HEX(80)
//TF_SYSTEMSERVICE = (TRAPFLAG_VOLATILES or TRAPFLAG_DEBUG)
+TF_CHECKUSERAPC = HEX(100)
/*
* Stack Layout:
@@ -28,7 +29,7 @@
* EnterTrap - Allocate KTRAP_FRAME_LENGTH and save registers to it
*/
MACRO(EnterTrap, Flags)
- LOCAL dont_swap
+ LOCAL kernel_mode_entry
/* Save the trap flags for this trap */
CurrentTrapFlags = VAL(Flags)
@@ -45,21 +46,28 @@
/* Make room for a KTRAP_FRAME */
sub rsp, (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME)
.allocstack (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME)
- .endprolog
/* Save rbp and rax */
mov [rsp + KTRAP_FRAME_Rbp], rbp
+ .savereg rbp, KTRAP_FRAME_Rbp
mov [rsp + KTRAP_FRAME_Rax], rax
+ .savereg rax, KTRAP_FRAME_Rax
/* Point rbp to the KTRAP_FRAME */
lea rbp, [rsp]
+ .setframe rbp, 0
if (Flags AND TF_NONVOLATILES)
/* Save non-volatile registers */
mov [rbp + KTRAP_FRAME_Rbx], rbx
+ .savereg rbx, KTRAP_FRAME_Rbx
mov [rbp + KTRAP_FRAME_Rdi], rdi
+ .savereg rdi, KTRAP_FRAME_Rdi
mov [rbp + KTRAP_FRAME_Rsi], rsi
- endif
+ .savereg rsi, KTRAP_FRAME_Rsi
+ endif
+
+ .endprolog
if (Flags AND TF_VOLATILES)
/* Save volatile registers */
@@ -89,19 +97,25 @@
mov [rbp + KTRAP_FRAME_SegGs], gs
endif
- /* Save previous mode and swap gs when it was UserMode */
+ /* Save previous mode and check if it was user mode */
mov ax, [rbp + KTRAP_FRAME_SegCs]
and al, 1
mov [rbp + KTRAP_FRAME_PreviousMode], al
- jz dont_swap
+ jz kernel_mode_entry
+
+ /* Set sane segments */
+ mov ax, (KGDT64_R3_DATA or RPL_MASK)
+ mov ds, ax
+ mov es, ax
swapgs
-dont_swap:
-
- if (Flags AND TF_IRQL)
+
+kernel_mode_entry:
+
+// if (Flags AND TF_IRQL)
/* Save previous irql */
mov rax, cr8
mov [rbp + KTRAP_FRAME_PreviousIrql], al
- endif
+// endif
if (Flags AND TF_DEBUG)
/* Save debug registers */
@@ -127,7 +141,16 @@
* ExitTrap - Restore registers and free stack space
*/
MACRO(ExitTrap, Flags)
- LOCAL dont_swap_back
+ LOCAL kernel_mode_return
+
+#if DBG
+ /* Check previous irql */
+ mov rax, cr8
+ cmp [rbp + KTRAP_FRAME_PreviousIrql], al
+ je .irql_ok
+ int 3
+ .irql_ok:
+#endif
if (Flags AND TF_SEGMENTS)
/* Restore segment selectors */
@@ -142,10 +165,22 @@
mov cr8, rax
endif
- test byte ptr [rbp + KTRAP_FRAME_PreviousMode], 1
- jz dont_swap_back
+ /* Check if we came from user mode */
+ test byte ptr [rbp + KTRAP_FRAME_SegCs], 1
+ jz kernel_mode_return
+
+ if (Flags AND TF_CHECKUSERAPC)
+ /* Load current thread into r10 */
+ mov r10, gs:[PcCurrentThread]
+ cmp byte ptr [r10 + KTHREAD_UserApcPending], 0
+ jne KiExitToUserApc
+
+ endif
+
+ /* Swap gs to user mode */
swapgs
-dont_swap_back:
+
+kernel_mode_return:
if (Flags AND TF_NONVOLATILES)
/* Restore non-volatile registers */
@@ -204,6 +239,6 @@
/* Leave */
ExitTrap Flags
- ENDFUNC &Trap
+ ENDFUNC
ENDM