ReactOS 0.4.16-dev-334-g4d9f67c
context.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: CONTEXT related functions
5 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
6 */
7
8/* INCLUDES ******************************************************************/
9
10#include <ntoskrnl.h>
11
12#define NDEBUG
13#include <debug.h>
14
15/* FUNCTIONS *****************************************************************/
16
17VOID
20 IN OUT PKEXCEPTION_FRAME ExceptionFrame,
21 IN OUT PKTRAP_FRAME TrapFrame,
22 IN ULONG ContextFlags,
24{
26
27 /* Make sure we have an amd64 context, then remove the flag */
28 ASSERT(ContextFlags & CONTEXT_AMD64);
29 ContextFlags &= ~CONTEXT_AMD64;
30
31 /* Do this at APC_LEVEL */
34
35 /* Handle integer registers */
36 if (ContextFlags & CONTEXT_INTEGER)
37 {
38 TrapFrame->Rax = Context->Rax;
39 TrapFrame->Rcx = Context->Rcx;
40 TrapFrame->Rdx = Context->Rdx;
41 TrapFrame->Rbp = Context->Rbp;
42 TrapFrame->R8 = Context->R8;
43 TrapFrame->R9 = Context->R9;
44 TrapFrame->R10 = Context->R10;
45 TrapFrame->R11 = Context->R11;
46 if (ExceptionFrame)
47 {
48 ExceptionFrame->Rbx = Context->Rbx;
49 ExceptionFrame->Rsi = Context->Rsi;
50 ExceptionFrame->Rdi = Context->Rdi;
51 ExceptionFrame->R12 = Context->R12;
52 ExceptionFrame->R13 = Context->R13;
53 ExceptionFrame->R14 = Context->R14;
54 ExceptionFrame->R15 = Context->R15;
55 }
56 }
57
58 /* Handle floating point registers */
59 if (ContextFlags & CONTEXT_FLOATING_POINT)
60 {
61 TrapFrame->MxCsr = Context->MxCsr;
62 TrapFrame->Xmm0 = Context->Xmm0;
63 TrapFrame->Xmm1 = Context->Xmm1;
64 TrapFrame->Xmm2 = Context->Xmm2;
65 TrapFrame->Xmm3 = Context->Xmm3;
66 TrapFrame->Xmm4 = Context->Xmm4;
67 TrapFrame->Xmm5 = Context->Xmm5;
68 if (ExceptionFrame)
69 {
70 ExceptionFrame->Xmm6 = Context->Xmm6;
71 ExceptionFrame->Xmm7 = Context->Xmm7;
72 ExceptionFrame->Xmm8 = Context->Xmm8;
73 ExceptionFrame->Xmm9 = Context->Xmm9;
74 ExceptionFrame->Xmm10 = Context->Xmm10;
75 ExceptionFrame->Xmm11 = Context->Xmm11;
76 ExceptionFrame->Xmm12 = Context->Xmm12;
77 ExceptionFrame->Xmm13 = Context->Xmm13;
78 ExceptionFrame->Xmm14 = Context->Xmm14;
79 ExceptionFrame->Xmm15 = Context->Xmm15;
80 }
81 }
82
83 /* Handle control registers */
84 if (ContextFlags & CONTEXT_CONTROL)
85 {
86 /* RIP, RSP, EFLAGS */
87 TrapFrame->Rip = Context->Rip;
88 TrapFrame->Rsp = Context->Rsp;
89 TrapFrame->EFlags = Context->EFlags;
90
91 if ((Context->SegCs & MODE_MASK) == KernelMode)
92 {
93 /* Set valid selectors */
94 TrapFrame->SegCs = KGDT64_R0_CODE;
95 TrapFrame->SegSs = KGDT64_R0_DATA;
96
97 /* Set valid EFLAGS */
98 TrapFrame->EFlags &= (EFLAGS_USER_SANITIZE | EFLAGS_INTERRUPT_MASK);
99 }
100 else
101 {
102 /* Copy selectors */
103 TrapFrame->SegCs = Context->SegCs;
104 if (TrapFrame->SegCs != (KGDT64_R3_CODE | RPL_MASK))
105 {
106 TrapFrame->SegCs = (KGDT64_R3_CMCODE | RPL_MASK);
107 }
108
109 TrapFrame->SegSs = Context->SegSs;
110
111 /* Set valid EFLAGS */
112 TrapFrame->EFlags &= EFLAGS_USER_SANITIZE;
113 TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
114 }
115 }
116
117 /* Handle segment selectors */
118 if (ContextFlags & CONTEXT_SEGMENTS)
119 {
120 /* Check if this was a Kernel Trap */
121 if ((Context->SegCs & MODE_MASK) == KernelMode)
122 {
123 /* Set valid selectors */
124 TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
125 TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
126 TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
127 TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
128 }
129 else
130 {
131 /* Copy selectors */
132 TrapFrame->SegDs = Context->SegDs;
133 TrapFrame->SegEs = Context->SegEs;
134 TrapFrame->SegFs = Context->SegFs;
135 TrapFrame->SegGs = Context->SegGs;
136 }
137 }
138
139 /* Handle debug registers */
140 if (ContextFlags & CONTEXT_DEBUG_REGISTERS)
141 {
142 /* Copy the debug registers */
143 TrapFrame->Dr0 = Context->Dr0;
144 TrapFrame->Dr1 = Context->Dr1;
145 TrapFrame->Dr2 = Context->Dr2;
146 TrapFrame->Dr3 = Context->Dr3;
147 TrapFrame->Dr6 = Context->Dr6;
148 TrapFrame->Dr7 = Context->Dr7;
149
150 if ((Context->SegCs & MODE_MASK) != KernelMode)
151 {
152 if (TrapFrame->Dr0 > (ULONG64)MmHighestUserAddress)
153 TrapFrame->Dr0 = 0;
154 if (TrapFrame->Dr1 > (ULONG64)MmHighestUserAddress)
155 TrapFrame->Dr1 = 0;
156 if (TrapFrame->Dr2 > (ULONG64)MmHighestUserAddress)
157 TrapFrame->Dr2 = 0;
158 if (TrapFrame->Dr3 > (ULONG64)MmHighestUserAddress)
159 TrapFrame->Dr3 = 0;
160 }
161 }
162
163 /* Restore IRQL */
165}
166
167VOID
168NTAPI
170 IN PKEXCEPTION_FRAME ExceptionFrame,
172{
173 ULONG ContextFlags;
175
176 /* Do this at APC_LEVEL */
179
180 /* Make sure we have an amd64 context, then remove the flag */
181 ContextFlags = Context->ContextFlags;
182 ASSERT(ContextFlags & CONTEXT_AMD64);
183 ContextFlags &= ~CONTEXT_AMD64;
184
185 /* Handle integer registers */
186 if (ContextFlags & CONTEXT_INTEGER)
187 {
188 Context->Rax = TrapFrame->Rax;
189 Context->Rcx = TrapFrame->Rcx;
190 Context->Rdx = TrapFrame->Rdx;
191 Context->Rbp = TrapFrame->Rbp;
192 Context->R8 = TrapFrame->R8;
193 Context->R9 = TrapFrame->R9;
194 Context->R10 = TrapFrame->R10;
195 Context->R11 = TrapFrame->R11;
196
197 if (ExceptionFrame)
198 {
199 Context->Rbx = ExceptionFrame->Rbx;
200 Context->Rsi = ExceptionFrame->Rsi;
201 Context->Rdi = ExceptionFrame->Rdi;
202 Context->R12 = ExceptionFrame->R12;
203 Context->R13 = ExceptionFrame->R13;
204 Context->R14 = ExceptionFrame->R14;
205 Context->R15 = ExceptionFrame->R15;
206 }
207 }
208
209 /* Handle floating point registers */
210 if (ContextFlags & CONTEXT_FLOATING_POINT)
211 {
212 Context->MxCsr = TrapFrame->MxCsr;
213 Context->Xmm0 = TrapFrame->Xmm0;
214 Context->Xmm1 = TrapFrame->Xmm1;
215 Context->Xmm2 = TrapFrame->Xmm2;
216 Context->Xmm3 = TrapFrame->Xmm3;
217 Context->Xmm4 = TrapFrame->Xmm4;
218 Context->Xmm5 = TrapFrame->Xmm5;
219 if (ExceptionFrame)
220 {
221 Context->Xmm6 = ExceptionFrame->Xmm6;
222 Context->Xmm7 = ExceptionFrame->Xmm7;
223 Context->Xmm8 = ExceptionFrame->Xmm8;
224 Context->Xmm9 = ExceptionFrame->Xmm9;
225 Context->Xmm10 = ExceptionFrame->Xmm10;
226 Context->Xmm11 = ExceptionFrame->Xmm11;
227 Context->Xmm12 = ExceptionFrame->Xmm12;
228 Context->Xmm13 = ExceptionFrame->Xmm13;
229 Context->Xmm14 = ExceptionFrame->Xmm14;
230 Context->Xmm15 = ExceptionFrame->Xmm15;
231 }
232 }
233
234 /* Handle control registers */
235 if (ContextFlags & CONTEXT_CONTROL)
236 {
237 /* Check if this was a Kernel Trap */
238 if ((TrapFrame->SegCs & MODE_MASK) == KernelMode)
239 {
240 /* Set valid selectors */
241 Context->SegCs = KGDT64_R0_CODE;
242 Context->SegSs = KGDT64_R0_DATA;
243 }
244 else
245 {
246 /* Copy selectors */
247 Context->SegCs = TrapFrame->SegCs;
248 Context->SegSs = TrapFrame->SegSs;
249 }
250
251 /* Copy RIP, RSP, EFLAGS */
252 Context->Rip = TrapFrame->Rip;
253 Context->Rsp = TrapFrame->Rsp;
254 Context->EFlags = TrapFrame->EFlags;
255 }
256
257 /* Handle segment selectors */
258 if (ContextFlags & CONTEXT_SEGMENTS)
259 {
260 /* Check if this was a Kernel Trap */
261 if ((TrapFrame->SegCs & MODE_MASK) == KernelMode)
262 {
263 /* Set valid selectors */
268 }
269 else
270 {
271 /* Copy selectors */
272 Context->SegDs = TrapFrame->SegDs;
273 Context->SegEs = TrapFrame->SegEs;
274 Context->SegFs = TrapFrame->SegFs;
275 Context->SegGs = TrapFrame->SegGs;
276 }
277 }
278
279 /* Handle debug registers */
280 if (ContextFlags & CONTEXT_DEBUG_REGISTERS)
281 {
282 /* Copy the debug registers */
283 Context->Dr0 = TrapFrame->Dr0;
284 Context->Dr1 = TrapFrame->Dr1;
285 Context->Dr2 = TrapFrame->Dr2;
286 Context->Dr3 = TrapFrame->Dr3;
287 Context->Dr6 = TrapFrame->Dr6;
288 Context->Dr7 = TrapFrame->Dr7;
289 }
290
291 /* Restore IRQL */
293}
294
295VOID
298 _In_ DWORD64 TargetFrame);
299
300VOID
302 _Out_ PKTRAP_FRAME TrapFrame,
304 _In_ KPROCESSOR_MODE RequestorMode)
305{
306 ULONG64 TargetFrame;
307
308 /* Save the volatile register context in the trap frame */
310 NULL,
311 TrapFrame,
312 Context->ContextFlags,
313 RequestorMode);
314
315 /* The target frame is MAX_SYSCALL_PARAM_SIZE bytes before the trap frame */
316 TargetFrame = (ULONG64)TrapFrame - MAX_SYSCALL_PARAM_SIZE ;
317
318 /* Set the nonvolatiles on the stack */
319 RtlSetUnwindContext(Context, TargetFrame);
320}
#define EFLAGS_INTERRUPT_MASK
Definition: SystemCall.c:11
#define MODE_MASK
Definition: orders.h:326
#define NULL
Definition: types.h:112
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
unsigned __int64 ULONG64
Definition: imports.h:198
#define KernelMode
Definition: asm.h:34
#define MAX_SYSCALL_PARAM_SIZE
Definition: asm.h:258
#define EFLAGS_USER_SANITIZE
Definition: ketypes.h:187
#define KGDT64_R3_CODE
Definition: ketypes.h:126
#define KGDT64_R0_CODE
Definition: ketypes.h:122
#define KGDT64_R3_DATA
Definition: ketypes.h:125
#define KGDT64_R3_CMCODE
Definition: ketypes.h:124
#define KGDT64_R3_CMTEB
Definition: ketypes.h:128
#define KGDT64_R0_DATA
Definition: ketypes.h:123
#define RPL_MASK
Definition: ketypes.h:119
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1373
#define CONTEXT_CONTROL
Definition: nt_native.h:1369
#define CONTEXT_INTEGER
Definition: nt_native.h:1370
#define CONTEXT_FLOATING_POINT
Definition: nt_native.h:1372
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1371
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:169
VOID KiSetTrapContextInternal(_Out_ PKTRAP_FRAME TrapFrame, _In_ PCONTEXT Context, _In_ KPROCESSOR_MODE RequestorMode)
Definition: context.c:301
VOID NTAPI KeContextToTrapFrame(IN PCONTEXT Context, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN OUT PKTRAP_FRAME TrapFrame, IN ULONG ContextFlags, IN KPROCESSOR_MODE PreviousMode)
Definition: context.c:19
VOID RtlSetUnwindContext(_In_ PCONTEXT Context, _In_ DWORD64 TargetFrame)
Definition: unwind.c:1115
PVOID MmHighestUserAddress
Definition: rtlcompat.c:29
#define CONTEXT_AMD64
uint64_t DWORD64
Definition: typedefs.h:67
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103