mirror of
https://github.com/acidanthera/audk.git
synced 2025-08-23 02:28:08 +02:00
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654 Currently, an SEV-SNP guest will terminate if it is not running at VMPL0. The requirement for running at VMPL0 is removed if an SVSM is present. Update the current VMPL0 check to additionally check for the presence of an SVSM is the guest is not running at VMPL0. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Erdem Aktas <erdemaktas@google.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Michael Roth <michael.roth@amd.com> Cc: Min Xu <min.m.xu@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
98 lines
2.3 KiB
C
98 lines
2.3 KiB
C
/** @file
|
|
|
|
SEV-SNP Page Validation functions.
|
|
|
|
Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <Uefi/UefiBaseType.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/MemEncryptSevLib.h>
|
|
#include <Library/AmdSvsmLib.h>
|
|
|
|
#include "SnpPageStateChange.h"
|
|
|
|
//
|
|
// The variable used for the VMPL check.
|
|
//
|
|
STATIC UINT8 gVmpl0Data[4096];
|
|
|
|
/**
|
|
The function checks whether SEV-SNP guest is booted under VMPL0.
|
|
|
|
@retval TRUE The guest is booted under VMPL0
|
|
@retval FALSE The guest is not booted under VMPL0
|
|
**/
|
|
STATIC
|
|
BOOLEAN
|
|
SevSnpIsVmpl0 (
|
|
VOID
|
|
)
|
|
{
|
|
UINT64 Rdx;
|
|
UINT32 Status;
|
|
|
|
//
|
|
// There is no straightforward way to query the current VMPL level.
|
|
// The simplest method is to use the RMPADJUST instruction to change
|
|
// a page permission to a VMPL level-1, and if the guest kernel is
|
|
// launched at a level <= 1, then RMPADJUST instruction will return
|
|
// an error.
|
|
//
|
|
Rdx = 1;
|
|
|
|
Status = AsmRmpAdjust ((UINT64)gVmpl0Data, 0, Rdx);
|
|
if (Status != 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
|
|
|
|
@param[in] BaseAddress Base address
|
|
@param[in] NumPages Number of pages starting from the base address
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
MemEncryptSevSnpPreValidateSystemRam (
|
|
IN PHYSICAL_ADDRESS BaseAddress,
|
|
IN UINTN NumPages
|
|
)
|
|
{
|
|
SEC_SEV_ES_WORK_AREA *SevEsWorkArea;
|
|
|
|
if (!MemEncryptSevSnpIsEnabled ()) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// The page state change uses the PVALIDATE instruction. The instruction
|
|
// can be run at VMPL-0 only. If its not a VMPL-0 guest, then an SVSM must
|
|
// be present to perform the operation on behalf of the guest. If the guest
|
|
// is not running at VMPL-0 and an SVSM is not present, then terminate the
|
|
// boot.
|
|
//
|
|
if (!SevSnpIsVmpl0 () && !AmdSvsmIsSvsmPresent ()) {
|
|
SnpPageStateFailureTerminate ();
|
|
}
|
|
|
|
SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);
|
|
|
|
InternalSetPageState (
|
|
BaseAddress,
|
|
NumPages,
|
|
SevSnpPagePrivate,
|
|
TRUE,
|
|
SevEsWorkArea->WorkBuffer,
|
|
sizeof (SevEsWorkArea->WorkBuffer)
|
|
);
|
|
}
|