]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
b6a955ed8088b4ce6aa85de918ec44e3815db36f
[mirror_edk2.git] / OvmfPkg / Library / VmgExitLib / VmgExitVcHandler.c
1 /** @file
2 X64 #VC Exception Handler functon.
3
4 Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <Base.h>
10 #include <Uefi.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/VmgExitLib.h>
13 #include <Register/Amd/Msr.h>
14
15 /**
16 Handle a #VC exception.
17
18 Performs the necessary processing to handle a #VC exception.
19
20 @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be set
21 as value to use on error.
22 @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
23
24 @retval EFI_SUCCESS Exception handled
25 @retval EFI_UNSUPPORTED #VC not supported, (new) exception value to
26 propagate provided
27 @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception value to
28 propagate provided
29
30 **/
31 EFI_STATUS
32 EFIAPI
33 VmgExitHandleVc (
34 IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
35 IN OUT EFI_SYSTEM_CONTEXT SystemContext
36 )
37 {
38 MSR_SEV_ES_GHCB_REGISTER Msr;
39 EFI_SYSTEM_CONTEXT_X64 *Regs;
40 GHCB *Ghcb;
41 UINT64 ExitCode, Status;
42 EFI_STATUS VcRet;
43
44 VcRet = EFI_SUCCESS;
45
46 Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
47 ASSERT (Msr.GhcbInfo.Function == 0);
48 ASSERT (Msr.Ghcb != 0);
49
50 Regs = SystemContext.SystemContextX64;
51 Ghcb = Msr.Ghcb;
52
53 VmgInit (Ghcb);
54
55 ExitCode = Regs->ExceptionData;
56 switch (ExitCode) {
57 default:
58 Status = VmgExit (Ghcb, SVM_EXIT_UNSUPPORTED, ExitCode, 0);
59 if (Status == 0) {
60 Regs->ExceptionData = 0;
61 *ExceptionType = GP_EXCEPTION;
62 } else {
63 GHCB_EVENT_INJECTION Event;
64
65 Event.Uint64 = Status;
66 if (Event.Elements.ErrorCodeValid != 0) {
67 Regs->ExceptionData = Event.Elements.ErrorCode;
68 } else {
69 Regs->ExceptionData = 0;
70 }
71
72 *ExceptionType = Event.Elements.Vector;
73 }
74
75 VcRet = EFI_PROTOCOL_ERROR;
76 }
77
78 VmgDone (Ghcb);
79
80 return VcRet;
81 }