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 { 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 */ 164 if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql); 165 } 166 167 VOID 168 NTAPI 169 KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, 170 IN PKEXCEPTION_FRAME ExceptionFrame, 171 IN OUT PCONTEXT Context) 172 { 173 ULONG ContextFlags; 174 KIRQL OldIrql; 175 176 /* Do this at APC_LEVEL */ 177 OldIrql = KeGetCurrentIrql(); 178 if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql); 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 ((TrapFrame->SegCs & MODE_MASK) != KernelMode)) 212 { 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 */ 264 Context->SegDs = KGDT64_R3_DATA | RPL_MASK; 265 Context->SegEs = KGDT64_R3_DATA | RPL_MASK; 266 Context->SegFs = KGDT64_R3_CMTEB | RPL_MASK; 267 Context->SegGs = KGDT64_R3_DATA | RPL_MASK; 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 */ 292 if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql); 293 } 294 295