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?re... ============================================================================== --- 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.templat... ============================================================================== --- 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?r... ============================================================================== --- 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