ReactOS  0.4.10-dev-238-gc84f398
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 
17 VOID
18 NTAPI
20  IN OUT PKEXCEPTION_FRAME ExceptionFrame,
21  IN OUT PKTRAP_FRAME TrapFrame,
22  IN ULONG ContextFlags,
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
148  IN PKEXCEPTION_FRAME ExceptionFrame,
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 
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define IN
Definition: typedefs.h:38
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define MODE_MASK
Definition: orders.h:326
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define KGDT64_R3_CMTEB
Definition: ketypes.h:78
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
#define CONTEXT_AMD64
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1371
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define KGDT64_R3_DATA
Definition: ketypes.h:75
#define RPL_MASK
Definition: ketypes.h:69
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define CONTEXT_CONTROL
Definition: compat.h:265
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define KGDT64_R0_CODE
Definition: ketypes.h:72
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:147
#define CONTEXT_FLOATING_POINT
Definition: compat.h:267
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define KGDT64_R0_DATA
Definition: ketypes.h:73
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define CONTEXT_INTEGER
Definition: compat.h:266
#define CONTEXT_DEBUG_REGISTERS
Definition: compat.h:268