From de74279d5b1e045eeeddf43a414b003fffa5af17 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 4 Feb 2012 11:01:19 +0000 Subject: [PATCH] [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 svn path=/trunk/; revision=55404 --- reactos/include/asm/genincdata.c | 10 +++ reactos/include/asm/ksamd64.template.h | 119 ++++++++++++++++--------- reactos/include/asm/trapamd64.inc | 61 ++++++++++--- 3 files changed, 133 insertions(+), 57 deletions(-) diff --git a/reactos/include/asm/genincdata.c b/reactos/include/asm/genincdata.c index 48577f1939b..2f55a40efd9 100644 --- a/reactos/include/asm/genincdata.c +++ b/reactos/include/asm/genincdata.c @@ -16,6 +16,16 @@ #include #include +#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: */ { /* 32 bit 64 bit */ diff --git a/reactos/include/asm/ksamd64.template.h b/reactos/include/asm/ksamd64.template.h index 88b96633f11..2fa4e71fd40 100644 --- a/reactos/include/asm/ksamd64.template.h +++ b/reactos/include/asm/ksamd64.template.h @@ -112,10 +112,10 @@ CONSTANT(EXCEPTION_NPX_ERROR), 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(PcHalReserved, KPCR, HalReserved), //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_ExceptionAddress, EXCEPTION_RECORD, ExceptionAddress), 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), diff --git a/reactos/include/asm/trapamd64.inc b/reactos/include/asm/trapamd64.inc index 23df5b50930..86cc94a7216 100644 --- a/reactos/include/asm/trapamd64.inc +++ b/reactos/include/asm/trapamd64.inc @@ -11,6 +11,7 @@ TF_SAVE_ALL = (TF_VOLATILES OR TF_NONVOLATILES OR TF_XMM OR TF_SEGME 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 @@ TF_SEND_EOI = HEX(80) * 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,22 +46,29 @@ MACRO(EnterTrap, Flags) /* 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 + .savereg rsi, KTRAP_FRAME_Rsi endif + .endprolog + if (Flags AND TF_VOLATILES) /* Save volatile registers */ mov [rbp + KTRAP_FRAME_Rcx], rcx @@ -89,19 +97,25 @@ MACRO(EnterTrap, Flags) 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 - swapgs -dont_swap: + jz kernel_mode_entry - if (Flags AND TF_IRQL) + /* Set sane segments */ + mov ax, (KGDT64_R3_DATA or RPL_MASK) + mov ds, ax + mov es, ax + swapgs + +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 @@ ENDM * 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 @@ MACRO(ExitTrap, Flags) 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 @@ MACRO(TRAP_ENTRY, Trap, Flags) /* Leave */ ExitTrap Flags - ENDFUNC &Trap + ENDFUNC ENDM