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