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 273