123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- /** @file
- X64 #VC Exception Handler functon.
- Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Base.h>
- #include <Uefi.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/MemEncryptSevLib.h>
- #include <Library/CcExitLib.h>
- #include <Register/Amd/Msr.h>
- #include "CcExitVcHandler.h"
- /**
- Handle a #VC exception.
- Performs the necessary processing to handle a #VC exception.
- @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be set
- as value to use on error.
- @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
- @retval EFI_SUCCESS Exception handled
- @retval EFI_UNSUPPORTED #VC not supported, (new) exception value to
- propagate provided
- @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception value to
- propagate provided
- **/
- EFI_STATUS
- EFIAPI
- VmgExitHandleVc (
- IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- )
- {
- MSR_SEV_ES_GHCB_REGISTER Msr;
- GHCB *Ghcb;
- GHCB *GhcbBackup;
- EFI_STATUS VcRet;
- BOOLEAN InterruptState;
- SEV_ES_PER_CPU_DATA *SevEsData;
- InterruptState = GetInterruptState ();
- if (InterruptState) {
- DisableInterrupts ();
- }
- Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
- ASSERT (Msr.GhcbInfo.Function == 0);
- ASSERT (Msr.Ghcb != 0);
- Ghcb = Msr.Ghcb;
- GhcbBackup = NULL;
- SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);
- SevEsData->VcCount++;
- //
- // Check for maximum SEC #VC nesting.
- //
- if (SevEsData->VcCount > VMGEXIT_MAXIMUM_VC_COUNT) {
- VmgExitIssueAssert (SevEsData);
- } else if (SevEsData->VcCount > 1) {
- UINTN GhcbBackupSize;
- //
- // Be sure that the proper amount of pages are allocated
- //
- GhcbBackupSize = (VMGEXIT_MAXIMUM_VC_COUNT - 1) * sizeof (*Ghcb);
- if (GhcbBackupSize > FixedPcdGet32 (PcdOvmfSecGhcbBackupSize)) {
- //
- // Not enough SEC backup pages allocated.
- //
- VmgExitIssueAssert (SevEsData);
- }
- //
- // Save the active GHCB to a backup page.
- // To access the correct backup page, increment the backup page pointer
- // based on the current VcCount.
- //
- GhcbBackup = (GHCB *)FixedPcdGet32 (PcdOvmfSecGhcbBackupBase);
- GhcbBackup += (SevEsData->VcCount - 2);
- CopyMem (GhcbBackup, Ghcb, sizeof (*Ghcb));
- }
- VcRet = InternalVmgExitHandleVc (Ghcb, ExceptionType, SystemContext);
- if (GhcbBackup != NULL) {
- //
- // Restore the active GHCB from the backup page.
- //
- CopyMem (Ghcb, GhcbBackup, sizeof (*Ghcb));
- }
- SevEsData->VcCount--;
- if (InterruptState) {
- EnableInterrupts ();
- }
- return VcRet;
- }
|