In SMM, we skip CR restore. The CR should always be right
and should no be touched.
mDoFarReturnFlag is changed to mSmmFlag to indicate all
difference between normal mode and SMM.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Yao, Jiewen" <jiewen....@intel.com>
Cc: "Fan, Jeff" <jeff....@intel.com>
Cc: "Kinney, Michael D" <michael.d.kin...@intel.com>
---
 .../Library/CpuExceptionHandlerLib/CpuExceptionCommon.h   |  2 +-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c  |  2 +-
 .../CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S     | 14 ++++++++++++--
 .../CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm   | 14 ++++++++++++--
 .../Library/CpuExceptionHandlerLib/SecPeiCpuException.c   |  2 +-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c  |  2 +-
 .../CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S      | 15 +++++++++++++--
 .../CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm    | 14 ++++++++++++--
 8 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index b28e9c5..9fc0bd5 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -42,7 +42,7 @@ typedef struct {
 
 extern CONST UINT32                mErrorCodeFlag;
 extern CONST UINTN                 mImageAlignSize;
-extern CONST UINTN                 mDoFarReturnFlag;
+extern CONST UINTN                 mSmmFlag;
 extern RESERVED_VECTORS_DATA       *mReservedVectors;
 
 /**
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
index 6739a2c..c11fb96 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
@@ -17,7 +17,7 @@
 #include <Library/DebugLib.h>
 #include <Library/MemoryAllocationLib.h>
 
-CONST UINTN    mDoFarReturnFlag  = 0;
+CONST UINTN    mSmmFlag  = 0;
 
 extern SPIN_LOCK                   mDisplayMessageSpinLock;
 extern EFI_CPU_INTERRUPT_HANDLER   *mExternalInterruptHandler;
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
index 3676809..8d65e76 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
@@ -26,7 +26,7 @@ ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
 ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
 
 #EXTRN ASM_PFX(mErrorCodeFlag):DWORD           # Error code flags for 
exceptions
-#EXTRN ASM_PFX(mDoFarReturnFlag):DWORD         # Do far return flag
+#EXTRN ASM_PFX(mSmmFlag):DWORD                 # Is it handler for SMM?
 
 .text
 
@@ -456,6 +456,7 @@ ErrorCodeAndVectorOnStack:
     popl    %ebx                         # retore value of ebx that was 
overwritten
                                          # by CPUID 
     movl    %cr4, %eax
+    movl    %eax, %ecx
     pushl   %eax                         # push cr4 firstly
     testl   $BIT24, %edx                 # Test for FXSAVE/FXRESTOR support
     jz      L1
@@ -465,7 +466,10 @@ L1:
     jz      L2
     orl     $BIT3, %eax                  # Set CR4.DE
 L2:    
+    cmpl    %ecx, %eax
+    jz      Cr4Done
     movl    %eax, %cr4
+Cr4Done:
     movl    %cr3, %eax
     pushl   %eax
     movl    %cr2, %eax
@@ -536,6 +540,11 @@ L4:
 #; or debuggers set breakpoint in interrupt/exception context
     addl    $24, %esp
 
+    cmpl    $0, ASM_PFX(mSmmFlag)   # Check if need skip WriteCr
+    jz      CrRestore
+    addl    $20, %esp
+    jmp     CrDone
+CrRestore:
 #; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
     popl    %eax
     movl    %eax, %cr0
@@ -546,6 +555,7 @@ L4:
     movl    %eax, %cr3
     popl    %eax
     movl    %eax, %cr4
+CrDone:
 
 #; UINT32  EFlags;
     popl    20(%ebp)
@@ -595,7 +605,7 @@ ErrorCode:
     jmp     *-12(%esp)
 
 DoReturn:
-    cmpl    $0, ASM_PFX(mDoFarReturnFlag)
+    cmpl    $0, ASM_PFX(mSmmFlag)
     jz      DoIret
     pushl   8(%esp)       # save EFLAGS
     addl    $16, %esp
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
index 12bbec0..177bdd9 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
@@ -31,7 +31,7 @@ CommonExceptionHandler             PROTO   C
 .data
 
 EXTRN mErrorCodeFlag:DWORD            ; Error code flags for exceptions
-EXTRN mDoFarReturnFlag:DWORD          ; Do far return flag
+EXTRN mSmmFlag:DWORD                  ; Is it handler for SMM?
 
 .code
 
@@ -256,6 +256,7 @@ ErrorCodeAndVectorOnStack:
                         ; are supported
     pop     ebx         ; retore value of ebx that was overwritten by CPUID 
     mov     eax, cr4
+    mov     ecx, eax
     push    eax         ; push cr4 firstly
     test    edx, BIT24  ; Test for FXSAVE/FXRESTOR support
     jz      @F
@@ -265,7 +266,10 @@ ErrorCodeAndVectorOnStack:
     jz      @F
     or      eax, BIT3   ; Set CR4.DE
 @@:    
+    cmp     eax, ecx
+    jz      Cr4Done
     mov     cr4, eax
+Cr4Done:
     mov     eax, cr3
     push    eax
     mov     eax, cr2
@@ -337,6 +341,11 @@ ErrorCodeAndVectorOnStack:
 ;; or debuggers set breakpoint in interrupt/exception context
     add     esp, 4 * 6
 
+    cmp     mSmmFlag, 0   ; Check if need skip WriteCr
+    jz      CrRestore
+    add     esp, 4 * 5
+    jmp     CrDone
+CrRestore:
 ;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
     pop     eax
     mov     cr0, eax
@@ -347,6 +356,7 @@ ErrorCodeAndVectorOnStack:
     mov     cr3, eax
     pop     eax
     mov     cr4, eax
+CrDone:
 
 ;; UINT32  EFlags;
     pop     dword ptr [ebp + 5 * 4]
@@ -396,7 +406,7 @@ ErrorCode:
     jmp     dword ptr [esp - 12]
 
 DoReturn:    
-    cmp     mDoFarReturnFlag, 0   ; Check if need to do far return instead of 
IRET
+    cmp     mSmmFlag, 0  ; Check if need to do far return instead of IRET
     jz      DoIret
     push    [esp + 8]    ; save EFLAGS
     add     esp, 16
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
index 7e94e38..a40e916 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
@@ -19,7 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 // Image Aglinment size for SEC/PEI phase
 //
 CONST UINTN    mImageAlignSize   = 4;
-CONST UINTN    mDoFarReturnFlag  = 0;
+CONST UINTN    mSmmFlag  = 0;
 
 /**
   Common exception handler.
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c
index 40f1250..cf9c8e0 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c
@@ -15,7 +15,7 @@
 #include <PiSmm.h>
 #include "CpuExceptionCommon.h"
 
-CONST UINTN   mDoFarReturnFlag   = 1; 
+CONST UINTN   mSmmFlag   = 1;
 
 /**
   Initializes all CPU exceptions entries and provides the default exception 
handlers.
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
index 6b62f09..be2ce1f 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
@@ -25,7 +25,7 @@
 ASM_GLOBAL ASM_PFX(CommonExceptionHandler)
 
 #EXTRN ASM_PFX(mErrorCodeFlag):DWORD    # Error code flags for exceptions
-#EXTRN ASM_PFX(mDoFarReturnFlag):QWORD  # Do far return flag
+#EXTRN ASM_PFX(mSmmFlag):QWORD          # Is it handler for SMM?
 .text
 
 #ifdef __APPLE__
@@ -233,8 +233,12 @@ CommonInterruptEntry_al_0000:
     movq    %cr8, %rax
     pushq   %rax
     movq    %cr4, %rax
+    movq    %rax, %rcx
     orq     $0x208, %rax 
+    cmpq    %rcx, %rax
+    jz      Cr4Done
     movq    %rax, %cr4 
+Cr4Done:
     pushq   %rax
     mov     %cr3, %rax 
     pushq   %rax
@@ -296,6 +300,12 @@ CommonInterruptEntry_al_0000:
 #; or debuggers set breakpoint in interrupt/exception context
     addq    $48, %rsp
 
+    movq    ASM_PFX(mSmmFlag)(%rip), %rax
+    cmpq    $0, %rax          # Check if need skip WriteCr
+    jz      CrRestore
+    addq    $48, %rsp
+    jmp     CrDone
+CrRestore:
 #; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
     popq    %rax
     movq    %rax, %cr0
@@ -308,6 +318,7 @@ CommonInterruptEntry_al_0000:
     movq    %rax, %cr4
     popq    %rax
     movq    %rax, %cr8
+CrDone:
 
 #; UINT64  RFlags;
     popq    40(%rbp)
@@ -366,7 +377,7 @@ ErrorCode:
 
 DoReturn:
     pushq   %rax
-    movq    ASM_PFX(mDoFarReturnFlag)(%rip), %rax
+    movq    ASM_PFX(mSmmFlag)(%rip), %rax
     cmpq    $0, %rax          # Check if need to do far return instead of IRET
     popq    %rax
     jz      DoIret
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
index cd21ec4..a923aec 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
@@ -26,7 +26,7 @@
 externdef CommonExceptionHandler:near
 
 EXTRN mErrorCodeFlag:DWORD    ; Error code flags for exceptions
-EXTRN mDoFarReturnFlag:QWORD  ; Do far return flag
+EXTRN mSmmFlag:QWORD          ; Is it handler for SMM?
 
 data SEGMENT
 
@@ -214,8 +214,12 @@ NoErrorCode:
     mov     rax, cr8
     push    rax
     mov     rax, cr4
+    mov     rcx, rax
     or      rax, 208h
+    cmp     rax, rcx
+    jz      Cr4Done
     mov     cr4, rax
+Cr4Done:
     push    rax
     mov     rax, cr3
     push    rax
@@ -278,6 +282,11 @@ NoErrorCode:
 ;; or debuggers set breakpoint in interrupt/exception context
     add     rsp, 8 * 6
 
+    cmp     mSmmFlag, 0   ; Check if need skip WriteCr
+    jz      CrRestore
+    add     esp, 8 * 6
+    jmp     CrDone
+CrRestore:
 ;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
     pop     rax
     mov     cr0, rax
@@ -290,6 +299,7 @@ NoErrorCode:
     mov     cr4, rax
     pop     rax
     mov     cr8, rax
+CrDone:
 
 ;; UINT64  RFlags;
     pop     qword ptr [rbp + 40]
@@ -347,7 +357,7 @@ ErrorCode:
     jmp     qword ptr [rsp - 24]
 
 DoReturn:
-    cmp     mDoFarReturnFlag, 0   ; Check if need to do far return instead of 
IRET
+    cmp     mSmmFlag, 0       ; Check if need to do far return instead of IRET
     jz      DoIret
     push    rax
     mov     rax, rsp          ; save old RSP to rax
-- 
1.9.5.msysgit.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to