[NTOS:PS] On x64 don't fail in NtSetInformationProcess with ProcessUserModeIOPL infor...
[reactos.git] / ntoskrnl / ke / amd64 / context.c
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
17 VOID
18 NTAPI
19 KeContextToTrapFrame(IN PCONTEXT Context,
20 IN OUT PKEXCEPTION_FRAME ExceptionFrame,
21 IN OUT PKTRAP_FRAME TrapFrame,
22 IN ULONG ContextFlags,
23 IN KPROCESSOR_MODE PreviousMode)
24 {
25 KIRQL OldIrql;
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 */
32 OldIrql = KeGetCurrentIrql();
33 if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
34
35 /* Handle integer registers */
36 if (ContextFlags & CONTEXT_INTEGER)
37 {
38 TrapFrame->Rax = Context->Rax;
39 TrapFrame->Rbx = Context->Rbx;
40 TrapFrame->Rcx = Context->Rcx;
41 TrapFrame->Rdx = Context->Rdx;
42 TrapFrame->Rsi = Context->Rsi;
43 TrapFrame->Rdi = Context->Rdi;
44 TrapFrame->Rbp = Context->Rbp;
45 TrapFrame->R8 = Context->R8;
46 TrapFrame->R9 = Context->R9;
47 TrapFrame->R10 = Context->R10;
48 TrapFrame->R11 = Context->R11;
49 if (ExceptionFrame)
50 {
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 ((Context->SegCs & MODE_MASK) != KernelMode))
61 {
62 TrapFrame->MxCsr = Context->MxCsr;
63 TrapFrame->Xmm0 = Context->Xmm0;
64 TrapFrame->Xmm1 = Context->Xmm1;
65 TrapFrame->Xmm2 = Context->Xmm2;
66 TrapFrame->Xmm3 = Context->Xmm3;
67 TrapFrame->Xmm4 = Context->Xmm4;
68 TrapFrame->Xmm5 = Context->Xmm5;
69 if (ExceptionFrame)
70 {
71 ExceptionFrame->Xmm6 = Context->Xmm6;
72 ExceptionFrame->Xmm7 = Context->Xmm7;
73 ExceptionFrame->Xmm8 = Context->Xmm8;
74 ExceptionFrame->Xmm9 = Context->Xmm9;
75 ExceptionFrame->Xmm10 = Context->Xmm10;
76 ExceptionFrame->Xmm11 = Context->Xmm11;
77 ExceptionFrame->Xmm12 = Context->Xmm12;
78 ExceptionFrame->Xmm13 = Context->Xmm13;
79 ExceptionFrame->Xmm14 = Context->Xmm14;
80 ExceptionFrame->Xmm15 = Context->Xmm15;
81 }
82 }
83
84 /* Handle control registers */
85 if (ContextFlags & CONTEXT_CONTROL)
86 {
87 /* Check if this was a Kernel Trap */
88 if ((Context->SegCs & MODE_MASK) == KernelMode)
89 {
90 /* Set valid selectors */
91 TrapFrame->SegCs = KGDT64_R0_CODE;
92 TrapFrame->SegSs = KGDT64_R0_DATA;
93 }
94 else
95 {
96 /* Copy selectors */
97 TrapFrame->SegCs = Context->SegCs;
98 TrapFrame->SegSs = Context->SegSs;
99 }
100
101 /* RIP, RSP, EFLAGS */
102 TrapFrame->Rip = Context->Rip;
103 TrapFrame->Rsp = Context->Rsp;
104 TrapFrame->EFlags = Context->EFlags;
105 }
106
107 /* Handle segment selectors */
108 if (ContextFlags & CONTEXT_SEGMENTS)
109 {
110 /* Check if this was a Kernel Trap */
111 if ((Context->SegCs & MODE_MASK) == KernelMode)
112 {
113 /* Set valid selectors */
114 TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
115 TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
116 TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
117 TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
118 }
119 else
120 {
121 /* Copy selectors */
122 TrapFrame->SegDs = Context->SegDs;
123 TrapFrame->SegEs = Context->SegEs;
124 TrapFrame->SegFs = Context->SegFs;
125 TrapFrame->SegGs = Context->SegGs;
126 }
127 }
128
129 /* Handle debug registers */
130 if (ContextFlags & CONTEXT_DEBUG_REGISTERS)
131 {
132 /* Copy the debug registers */
133 TrapFrame->Dr0 = Context->Dr0;
134 TrapFrame->Dr1 = Context->Dr1;
135 TrapFrame->Dr2 = Context->Dr2;
136 TrapFrame->Dr3 = Context->Dr3;
137 TrapFrame->Dr6 = Context->Dr6;
138 TrapFrame->Dr7 = Context->Dr7;
139 }
140
141 /* Restore IRQL */
142 if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
143 }
144
145 VOID
146 NTAPI
147 KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
148 IN PKEXCEPTION_FRAME ExceptionFrame,
149 IN OUT PCONTEXT Context)
150 {
151 ULONG ContextFlags;
152 KIRQL OldIrql;
153
154 /* Do this at APC_LEVEL */
155 OldIrql = KeGetCurrentIrql();
156 if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
157
158 /* Make sure we have an amd64 context, then remove the flag */
159 ContextFlags = Context->ContextFlags;
160 ASSERT(ContextFlags & CONTEXT_AMD64);
161 ContextFlags &= ~CONTEXT_AMD64;
162
163 /* Handle integer registers */
164 if (ContextFlags & CONTEXT_INTEGER)
165 {
166 Context->Rax = TrapFrame->Rax;
167 Context->Rbx = TrapFrame->Rbx;
168 Context->Rcx = TrapFrame->Rcx;
169 Context->Rdx = TrapFrame->Rdx;
170 Context->Rsi = TrapFrame->Rsi;
171 Context->Rdi = TrapFrame->Rdi;
172 Context->Rbp = TrapFrame->Rbp;
173 Context->R8 = TrapFrame->R8;
174 Context->R9 = TrapFrame->R9;
175 Context->R10 = TrapFrame->R10;
176 Context->R11 = TrapFrame->R11;
177
178 if (ExceptionFrame)
179 {
180 Context->R12 = ExceptionFrame->R12;
181 Context->R13 = ExceptionFrame->R13;
182 Context->R14 = ExceptionFrame->R14;
183 Context->R15 = ExceptionFrame->R15;
184 }
185 }
186
187 /* Handle floating point registers */
188 if ((ContextFlags & CONTEXT_FLOATING_POINT) &&
189 ((TrapFrame->SegCs & MODE_MASK) != KernelMode))
190 {
191 Context->Xmm0 = TrapFrame->Xmm0;
192 Context->Xmm1 = TrapFrame->Xmm1;
193 Context->Xmm2 = TrapFrame->Xmm2;
194 Context->Xmm3 = TrapFrame->Xmm3;
195 Context->Xmm4 = TrapFrame->Xmm4;
196 Context->Xmm5 = TrapFrame->Xmm5;
197 if (ExceptionFrame)
198 {
199 Context->Xmm6 = ExceptionFrame->Xmm6;
200 Context->Xmm7 = ExceptionFrame->Xmm7;
201 Context->Xmm8 = ExceptionFrame->Xmm8;
202 Context->Xmm9 = ExceptionFrame->Xmm9;
203 Context->Xmm10 = ExceptionFrame->Xmm10;
204 Context->Xmm11 = ExceptionFrame->Xmm11;
205 Context->Xmm12 = ExceptionFrame->Xmm12;
206 Context->Xmm13 = ExceptionFrame->Xmm13;
207 Context->Xmm14 = ExceptionFrame->Xmm14;
208 Context->Xmm15 = ExceptionFrame->Xmm15;
209 }
210 }
211
212 /* Handle control registers */
213 if (ContextFlags & CONTEXT_CONTROL)
214 {
215 /* Check if this was a Kernel Trap */
216 if ((TrapFrame->SegCs & MODE_MASK) == KernelMode)
217 {
218 /* Set valid selectors */
219 Context->SegCs = KGDT64_R0_CODE;
220 Context->SegSs = KGDT64_R0_DATA;
221 }
222 else
223 {
224 /* Copy selectors */
225 Context->SegCs = TrapFrame->SegCs;
226 Context->SegSs = TrapFrame->SegSs;
227 }
228
229 /* Copy RIP, RSP, EFLAGS */
230 Context->Rip = TrapFrame->Rip;
231 Context->Rsp = TrapFrame->Rsp;
232 Context->EFlags = TrapFrame->EFlags;
233 }
234
235 /* Handle segment selectors */
236 if (ContextFlags & CONTEXT_SEGMENTS)
237 {
238 /* Check if this was a Kernel Trap */
239 if ((TrapFrame->SegCs & MODE_MASK) == KernelMode)
240 {
241 /* Set valid selectors */
242 Context->SegDs = KGDT64_R3_DATA | RPL_MASK;
243 Context->SegEs = KGDT64_R3_DATA | RPL_MASK;
244 Context->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
245 Context->SegGs = KGDT64_R3_DATA | RPL_MASK;
246 }
247 else
248 {
249 /* Copy selectors */
250 Context->SegDs = TrapFrame->SegDs;
251 Context->SegEs = TrapFrame->SegEs;
252 Context->SegFs = TrapFrame->SegFs;
253 Context->SegGs = TrapFrame->SegGs;
254 }
255 }
256
257 /* Handle debug registers */
258 if (ContextFlags & CONTEXT_DEBUG_REGISTERS)
259 {
260 /* Copy the debug registers */
261 Context->Dr0 = TrapFrame->Dr0;
262 Context->Dr1 = TrapFrame->Dr1;
263 Context->Dr2 = TrapFrame->Dr2;
264 Context->Dr3 = TrapFrame->Dr3;
265 Context->Dr6 = TrapFrame->Dr6;
266 Context->Dr7 = TrapFrame->Dr7;
267 }
268
269 /* Restore IRQL */
270 if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
271 }
272