[MMIXER] Fix additional data size initialization for different audio formats (#6753)
[reactos.git] / ntoskrnl / ke / amd64 / context.c
index 239a697..3c345f8 100644 (file)
@@ -24,80 +24,101 @@ KeContextToTrapFrame(IN PCONTEXT Context,
 {
     KIRQL OldIrql;
 
+    /* Make sure we have an amd64 context, then remove the flag */
+    ASSERT(ContextFlags & CONTEXT_AMD64);
+    ContextFlags &= ~CONTEXT_AMD64;
+
     /* Do this at APC_LEVEL */
     OldIrql = KeGetCurrentIrql();
     if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
 
     /* Handle integer registers */
-    if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+    if (ContextFlags & CONTEXT_INTEGER)
     {
         TrapFrame->Rax = Context->Rax;
-        TrapFrame->Rbx = Context->Rbx;
         TrapFrame->Rcx = Context->Rcx;
         TrapFrame->Rdx = Context->Rdx;
-        TrapFrame->Rsi = Context->Rsi;
-        TrapFrame->Rdi = Context->Rdi;
         TrapFrame->Rbp = Context->Rbp;
         TrapFrame->R8 = Context->R8;
         TrapFrame->R9 = Context->R9;
         TrapFrame->R10 = Context->R10;
         TrapFrame->R11 = Context->R11;
-        ExceptionFrame->R12 = Context->R12;
-        ExceptionFrame->R13 = Context->R13;
-        ExceptionFrame->R14 = Context->R14;
-        ExceptionFrame->R15 = Context->R15;
+        if (ExceptionFrame)
+        {
+            ExceptionFrame->Rbx = Context->Rbx;
+            ExceptionFrame->Rsi = Context->Rsi;
+            ExceptionFrame->Rdi = Context->Rdi;
+            ExceptionFrame->R12 = Context->R12;
+            ExceptionFrame->R13 = Context->R13;
+            ExceptionFrame->R14 = Context->R14;
+            ExceptionFrame->R15 = Context->R15;
+        }
     }
 
     /* Handle floating point registers */
-    if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
-        CONTEXT_FLOATING_POINT) && (Context->SegCs & MODE_MASK))
+    if (ContextFlags & CONTEXT_FLOATING_POINT)
     {
+        TrapFrame->MxCsr = Context->MxCsr;
         TrapFrame->Xmm0 = Context->Xmm0;
         TrapFrame->Xmm1 = Context->Xmm1;
         TrapFrame->Xmm2 = Context->Xmm2;
         TrapFrame->Xmm3 = Context->Xmm3;
         TrapFrame->Xmm4 = Context->Xmm4;
         TrapFrame->Xmm5 = Context->Xmm5;
-        ExceptionFrame->Xmm6 = Context->Xmm6;
-        ExceptionFrame->Xmm7 = Context->Xmm7;
-        ExceptionFrame->Xmm8 = Context->Xmm8;
-        ExceptionFrame->Xmm9 = Context->Xmm9;
-        ExceptionFrame->Xmm10 = Context->Xmm10;
-        ExceptionFrame->Xmm11 = Context->Xmm11;
-        ExceptionFrame->Xmm12 = Context->Xmm12;
-        ExceptionFrame->Xmm13 = Context->Xmm13;
-        ExceptionFrame->Xmm14 = Context->Xmm14;
-        ExceptionFrame->Xmm15 = Context->Xmm15;
+        if (ExceptionFrame)
+        {
+            ExceptionFrame->Xmm6 = Context->Xmm6;
+            ExceptionFrame->Xmm7 = Context->Xmm7;
+            ExceptionFrame->Xmm8 = Context->Xmm8;
+            ExceptionFrame->Xmm9 = Context->Xmm9;
+            ExceptionFrame->Xmm10 = Context->Xmm10;
+            ExceptionFrame->Xmm11 = Context->Xmm11;
+            ExceptionFrame->Xmm12 = Context->Xmm12;
+            ExceptionFrame->Xmm13 = Context->Xmm13;
+            ExceptionFrame->Xmm14 = Context->Xmm14;
+            ExceptionFrame->Xmm15 = Context->Xmm15;
+        }
     }
 
     /* Handle control registers */
-    if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
+    if (ContextFlags & CONTEXT_CONTROL)
     {
-        /* Check if this was a Kernel Trap */
-        if (Context->SegCs == KGDT64_R0_CODE)
+        /* RIP, RSP, EFLAGS */
+        TrapFrame->Rip = Context->Rip;
+        TrapFrame->Rsp = Context->Rsp;
+        TrapFrame->EFlags = Context->EFlags;
+
+        if ((Context->SegCs & MODE_MASK) == KernelMode)
         {
             /* Set valid selectors */
             TrapFrame->SegCs = KGDT64_R0_CODE;
             TrapFrame->SegSs = KGDT64_R0_DATA;
+
+            /* Set valid EFLAGS */
+            TrapFrame->EFlags &= (EFLAGS_USER_SANITIZE | EFLAGS_INTERRUPT_MASK);
         }
         else
         {
             /* Copy selectors */
             TrapFrame->SegCs = Context->SegCs;
+            if (TrapFrame->SegCs != (KGDT64_R3_CODE | RPL_MASK))
+            {
+                TrapFrame->SegCs = (KGDT64_R3_CMCODE | RPL_MASK);
+            }
+
             TrapFrame->SegSs = Context->SegSs;
-        }
 
-        /* RIP, RSP, EFLAGS */
-        TrapFrame->Rip = Context->Rip;
-        TrapFrame->Rsp = Context->Rsp;
-        TrapFrame->EFlags = Context->EFlags;
+            /* Set valid EFLAGS */
+            TrapFrame->EFlags &= EFLAGS_USER_SANITIZE;
+            TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
+        }
     }
 
     /* Handle segment selectors */
-    if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
+    if (ContextFlags & CONTEXT_SEGMENTS)
     {
         /* Check if this was a Kernel Trap */
-        if (Context->SegCs == KGDT64_R0_CODE)
+        if ((Context->SegCs & MODE_MASK) == KernelMode)
         {
             /* Set valid selectors */
             TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
@@ -116,8 +137,7 @@ KeContextToTrapFrame(IN PCONTEXT Context,
     }
 
     /* Handle debug registers */
-    if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
-        CONTEXT_DEBUG_REGISTERS)
+    if (ContextFlags & CONTEXT_DEBUG_REGISTERS)
     {
         /* Copy the debug registers */
         TrapFrame->Dr0 = Context->Dr0;
@@ -126,6 +146,18 @@ KeContextToTrapFrame(IN PCONTEXT Context,
         TrapFrame->Dr3 = Context->Dr3;
         TrapFrame->Dr6 = Context->Dr6;
         TrapFrame->Dr7 = Context->Dr7;
+
+        if ((Context->SegCs & MODE_MASK) != KernelMode)
+        {
+            if (TrapFrame->Dr0 > (ULONG64)MmHighestUserAddress)
+                TrapFrame->Dr0 = 0;
+            if (TrapFrame->Dr1 > (ULONG64)MmHighestUserAddress)
+                TrapFrame->Dr1 = 0;
+            if (TrapFrame->Dr2 > (ULONG64)MmHighestUserAddress)
+                TrapFrame->Dr2 = 0;
+            if (TrapFrame->Dr3 > (ULONG64)MmHighestUserAddress)
+                TrapFrame->Dr3 = 0;
+        }
     }
 
     /* Restore IRQL */
@@ -138,59 +170,72 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
                      IN PKEXCEPTION_FRAME ExceptionFrame,
                      IN OUT PCONTEXT Context)
 {
+    ULONG ContextFlags;
     KIRQL OldIrql;
 
     /* Do this at APC_LEVEL */
     OldIrql = KeGetCurrentIrql();
     if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
 
+    /* Make sure we have an amd64 context, then remove the flag */
+    ContextFlags = Context->ContextFlags;
+    ASSERT(ContextFlags & CONTEXT_AMD64);
+    ContextFlags &= ~CONTEXT_AMD64;
+
     /* Handle integer registers */
-    if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+    if (ContextFlags & CONTEXT_INTEGER)
     {
         Context->Rax = TrapFrame->Rax;
-        Context->Rbx = TrapFrame->Rbx;
         Context->Rcx = TrapFrame->Rcx;
         Context->Rdx = TrapFrame->Rdx;
-        Context->Rsi = TrapFrame->Rsi;
-        Context->Rdi = TrapFrame->Rdi;
         Context->Rbp = TrapFrame->Rbp;
         Context->R8 = TrapFrame->R8;
         Context->R9 = TrapFrame->R9;
         Context->R10 = TrapFrame->R10;
         Context->R11 = TrapFrame->R11;
-        Context->R12 = ExceptionFrame->R12;
-        Context->R13 = ExceptionFrame->R13;
-        Context->R14 = ExceptionFrame->R14;
-        Context->R15 = ExceptionFrame->R15;
+
+        if (ExceptionFrame)
+        {
+            Context->Rbx = ExceptionFrame->Rbx;
+            Context->Rsi = ExceptionFrame->Rsi;
+            Context->Rdi = ExceptionFrame->Rdi;
+            Context->R12 = ExceptionFrame->R12;
+            Context->R13 = ExceptionFrame->R13;
+            Context->R14 = ExceptionFrame->R14;
+            Context->R15 = ExceptionFrame->R15;
+        }
     }
 
     /* Handle floating point registers */
-    if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
-        CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
+    if (ContextFlags & CONTEXT_FLOATING_POINT)
     {
+        Context->MxCsr = TrapFrame->MxCsr;
         Context->Xmm0 = TrapFrame->Xmm0;
         Context->Xmm1 = TrapFrame->Xmm1;
         Context->Xmm2 = TrapFrame->Xmm2;
         Context->Xmm3 = TrapFrame->Xmm3;
         Context->Xmm4 = TrapFrame->Xmm4;
         Context->Xmm5 = TrapFrame->Xmm5;
-        Context->Xmm6 = ExceptionFrame->Xmm6;
-        Context->Xmm7 = ExceptionFrame->Xmm7;
-        Context->Xmm8 = ExceptionFrame->Xmm8;
-        Context->Xmm9 = ExceptionFrame->Xmm9;
-        Context->Xmm10 = ExceptionFrame->Xmm10;
-        Context->Xmm11 = ExceptionFrame->Xmm11;
-        Context->Xmm12 = ExceptionFrame->Xmm12;
-        Context->Xmm13 = ExceptionFrame->Xmm13;
-        Context->Xmm14 = ExceptionFrame->Xmm14;
-        Context->Xmm15 = ExceptionFrame->Xmm15;
+        if (ExceptionFrame)
+        {
+            Context->Xmm6 = ExceptionFrame->Xmm6;
+            Context->Xmm7 = ExceptionFrame->Xmm7;
+            Context->Xmm8 = ExceptionFrame->Xmm8;
+            Context->Xmm9 = ExceptionFrame->Xmm9;
+            Context->Xmm10 = ExceptionFrame->Xmm10;
+            Context->Xmm11 = ExceptionFrame->Xmm11;
+            Context->Xmm12 = ExceptionFrame->Xmm12;
+            Context->Xmm13 = ExceptionFrame->Xmm13;
+            Context->Xmm14 = ExceptionFrame->Xmm14;
+            Context->Xmm15 = ExceptionFrame->Xmm15;
+        }
     }
 
     /* Handle control registers */
-    if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
+    if (ContextFlags & CONTEXT_CONTROL)
     {
         /* Check if this was a Kernel Trap */
-        if (TrapFrame->SegCs == KGDT64_R0_CODE)
+        if ((TrapFrame->SegCs & MODE_MASK) == KernelMode)
         {
             /* Set valid selectors */
             Context->SegCs = KGDT64_R0_CODE;
@@ -210,10 +255,10 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
     }
 
     /* Handle segment selectors */
-    if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
+    if (ContextFlags & CONTEXT_SEGMENTS)
     {
         /* Check if this was a Kernel Trap */
-        if (TrapFrame->SegCs == KGDT64_R0_CODE)
+        if ((TrapFrame->SegCs & MODE_MASK) == KernelMode)
         {
             /* Set valid selectors */
             Context->SegDs = KGDT64_R3_DATA | RPL_MASK;
@@ -232,8 +277,7 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
     }
 
     /* Handle debug registers */
-    if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
-        CONTEXT_DEBUG_REGISTERS)
+    if (ContextFlags & CONTEXT_DEBUG_REGISTERS)
     {
         /* Copy the debug registers */
         Context->Dr0 = TrapFrame->Dr0;
@@ -248,3 +292,29 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
     if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
 }
 
+VOID
+RtlSetUnwindContext(
+    _In_ PCONTEXT Context,
+    _In_ DWORD64 TargetFrame);
+
+VOID
+KiSetTrapContextInternal(
+    _Out_ PKTRAP_FRAME TrapFrame,
+    _In_ PCONTEXT Context,
+    _In_ KPROCESSOR_MODE RequestorMode)
+{
+    ULONG64 TargetFrame;
+
+    /* Save the volatile register context in the trap frame */
+    KeContextToTrapFrame(Context,
+                         NULL,
+                         TrapFrame,
+                         Context->ContextFlags,
+                         RequestorMode);
+
+    /* The target frame is MAX_SYSCALL_PARAM_SIZE bytes before the trap frame */
+    TargetFrame = (ULONG64)TrapFrame - MAX_SYSCALL_PARAM_SIZE ;
+
+    /* Set the nonvolatiles on the stack */
+    RtlSetUnwindContext(Context, TargetFrame);
+}