mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198 Add base support to handle #VC exceptions. Update the common exception handlers to invoke the VmgExitHandleVc () function of the VmgExitLib library when a #VC is encountered. A non-zero return code will propagate to the targeted exception handler. Under SEV-ES, a DR7 read or write intercept generates a #VC exception. To avoid exception recursion, a #VC exception will not try to read and push the actual debug registers into the EFI_SYSTEM_CONTEXT_X64 struct and instead push zeroes. The #VC exception handler does not make use of the debug registers from the saved context and the exception processing exit code does not attempt to restore the debug register values. Cc: Eric Dong <eric.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Eric Dong <eric.dong@intel.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
parent
3a4a6ead32
commit
5277540e37
|
@ -14,7 +14,7 @@
|
|||
//
|
||||
// 1 means an error code will be pushed, otherwise 0
|
||||
//
|
||||
CONST UINT32 mErrorCodeFlag = 0x00227d00;
|
||||
CONST UINT32 mErrorCodeFlag = 0x20227d00;
|
||||
|
||||
//
|
||||
// Define the maximum message length
|
||||
|
@ -45,6 +45,14 @@ CONST CHAR8 *mExceptionNameStr[] = {
|
|||
"#XM - SIMD floating-point",
|
||||
"#VE - Virtualization",
|
||||
"#CP - Control Protection"
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"#VC - VMM Communication",
|
||||
};
|
||||
|
||||
#define EXCEPTION_KNOWN_NAME_NUM (sizeof (mExceptionNameStr) / sizeof (CHAR8 *))
|
||||
|
|
|
@ -57,3 +57,4 @@
|
|||
PeCoffGetEntryPointLib
|
||||
MemoryAllocationLib
|
||||
DebugLib
|
||||
VmgExitLib
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
HobLib
|
||||
MemoryAllocationLib
|
||||
SynchronizationLib
|
||||
VmgExitLib
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard # CONSUMES
|
||||
|
|
|
@ -6,8 +6,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
|
||||
**/
|
||||
|
||||
#include "CpuExceptionCommon.h"
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/VmgExitLib.h>
|
||||
#include "CpuExceptionCommon.h"
|
||||
|
||||
/**
|
||||
Internal worker function for common exception handler.
|
||||
|
@ -27,6 +28,23 @@ CommonExceptionHandlerWorker (
|
|||
RESERVED_VECTORS_DATA *ReservedVectors;
|
||||
EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler;
|
||||
|
||||
if (ExceptionType == VC_EXCEPTION) {
|
||||
EFI_STATUS Status;
|
||||
//
|
||||
// #VC needs to be handled immediately upon enabling exception handling
|
||||
// and therefore can't use the RegisterCpuInterruptHandler() interface.
|
||||
//
|
||||
// Handle the #VC:
|
||||
// On EFI_SUCCESS - Exception has been handled, return
|
||||
// On other - ExceptionType contains (possibly new) exception
|
||||
// value
|
||||
//
|
||||
Status = VmgExitHandleVc (&ExceptionType, SystemContext);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ExceptionHandlerContext = (EXCEPTION_HANDLER_CONTEXT *) (UINTN) (SystemContext.SystemContextIa32);
|
||||
ReservedVectors = ExceptionHandlerData->ReservedVectors;
|
||||
ExternalInterruptHandler = ExceptionHandlerData->ExternalInterruptHandler;
|
||||
|
|
|
@ -7,6 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <Library/VmgExitLib.h>
|
||||
#include "CpuExceptionCommon.h"
|
||||
|
||||
CONST UINTN mDoFarReturnFlag = 0;
|
||||
|
@ -24,6 +25,24 @@ CommonExceptionHandler (
|
|||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
if (ExceptionType == VC_EXCEPTION) {
|
||||
EFI_STATUS Status;
|
||||
//
|
||||
// #VC needs to be handled immediately upon enabling exception handling
|
||||
// and therefore can't use the RegisterCpuInterruptHandler() interface
|
||||
// (which isn't supported under Sec and Pei anyway).
|
||||
//
|
||||
// Handle the #VC:
|
||||
// On EFI_SUCCESS - Exception has been handled, return
|
||||
// On other - ExceptionType contains (possibly new) exception
|
||||
// value
|
||||
//
|
||||
Status = VmgExitHandleVc (&ExceptionType, SystemContext);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the serial port before dumping.
|
||||
//
|
||||
|
|
|
@ -48,3 +48,4 @@
|
|||
PrintLib
|
||||
LocalApicLib
|
||||
PeCoffGetEntryPointLib
|
||||
VmgExitLib
|
||||
|
|
|
@ -51,4 +51,5 @@
|
|||
LocalApicLib
|
||||
PeCoffGetEntryPointLib
|
||||
DebugLib
|
||||
VmgExitLib
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
; CommonExceptionHandler()
|
||||
;
|
||||
|
||||
%define VC_EXCEPTION 29
|
||||
|
||||
extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions
|
||||
extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
|
||||
extern ASM_PFX(CommonExceptionHandler)
|
||||
|
@ -224,6 +226,9 @@ HasErrorCode:
|
|||
push rax
|
||||
|
||||
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
|
||||
cmp qword [rbp + 8], VC_EXCEPTION
|
||||
je VcDebugRegs ; For SEV-ES (#VC) Debug registers ignored
|
||||
|
||||
mov rax, dr7
|
||||
push rax
|
||||
mov rax, dr6
|
||||
|
@ -236,7 +241,19 @@ HasErrorCode:
|
|||
push rax
|
||||
mov rax, dr0
|
||||
push rax
|
||||
jmp DrFinish
|
||||
|
||||
VcDebugRegs:
|
||||
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 are skipped for #VC to avoid exception recursion
|
||||
xor rax, rax
|
||||
push rax
|
||||
push rax
|
||||
push rax
|
||||
push rax
|
||||
push rax
|
||||
push rax
|
||||
|
||||
DrFinish:
|
||||
;; FX_SAVE_STATE_X64 FxSaveState;
|
||||
sub rsp, 512
|
||||
mov rdi, rsp
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
; CommonExceptionHandler()
|
||||
;
|
||||
|
||||
%define VC_EXCEPTION 29
|
||||
|
||||
extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions
|
||||
extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
|
||||
extern ASM_PFX(CommonExceptionHandler)
|
||||
|
@ -225,6 +227,9 @@ HasErrorCode:
|
|||
push rax
|
||||
|
||||
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
|
||||
cmp qword [rbp + 8], VC_EXCEPTION
|
||||
je VcDebugRegs ; For SEV-ES (#VC) Debug registers ignored
|
||||
|
||||
mov rax, dr7
|
||||
push rax
|
||||
mov rax, dr6
|
||||
|
@ -237,7 +242,19 @@ HasErrorCode:
|
|||
push rax
|
||||
mov rax, dr0
|
||||
push rax
|
||||
jmp DrFinish
|
||||
|
||||
VcDebugRegs:
|
||||
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 are skipped for #VC to avoid exception recursion
|
||||
xor rax, rax
|
||||
push rax
|
||||
push rax
|
||||
push rax
|
||||
push rax
|
||||
push rax
|
||||
push rax
|
||||
|
||||
DrFinish:
|
||||
;; FX_SAVE_STATE_X64 FxSaveState;
|
||||
sub rsp, 512
|
||||
mov rdi, rsp
|
||||
|
|
|
@ -53,3 +53,4 @@
|
|||
PrintLib
|
||||
LocalApicLib
|
||||
PeCoffGetEntryPointLib
|
||||
VmgExitLib
|
||||
|
|
Loading…
Reference in New Issue