audk/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c

156 lines
5.2 KiB
C
Raw Normal View History

/** @file
Secure Encrypted Virtualization (SEV) library helper function
Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MemEncryptSevLib.h>
#include <Register/Amd/Cpuid.h>
#include <Register/Amd/Msr.h>
#include <Register/Cpuid.h>
/**
This function clears memory encryption bit for the memory region specified by
BaseAddress and NumPages from the current page table context.
@param[in] Cr3BaseAddress Cr3 Base Address (if zero then use
current CR3)
@param[in] BaseAddress The physical address that is the start
address of a memory region.
@param[in] NumPages The number of pages from start memory
region.
@retval RETURN_SUCCESS The attributes were cleared for the
memory region.
@retval RETURN_INVALID_PARAMETER Number of pages is zero.
@retval RETURN_UNSUPPORTED Clearing the memory encryption attribute
is not supported
**/
RETURN_STATUS
EFIAPI
MemEncryptSevClearPageEncMask (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS BaseAddress,
IN UINTN NumPages
)
{
//
// Memory encryption bit is not accessible in 32-bit mode
//
return RETURN_UNSUPPORTED;
}
/**
This function sets memory encryption bit for the memory region specified by
BaseAddress and NumPages from the current page table context.
@param[in] Cr3BaseAddress Cr3 Base Address (if zero then use
current CR3)
@param[in] BaseAddress The physical address that is the start
address of a memory region.
@param[in] NumPages The number of pages from start memory
region.
@retval RETURN_SUCCESS The attributes were set for the memory
region.
@retval RETURN_INVALID_PARAMETER Number of pages is zero.
@retval RETURN_UNSUPPORTED Setting the memory encryption attribute
is not supported
**/
RETURN_STATUS
EFIAPI
MemEncryptSevSetPageEncMask (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS BaseAddress,
IN UINTN NumPages
)
{
//
// Memory encryption bit is not accessible in 32-bit mode
//
return RETURN_UNSUPPORTED;
}
/**
Returns the encryption state of the specified virtual address range.
@param[in] Cr3BaseAddress Cr3 Base Address (if zero then use
current CR3)
@param[in] BaseAddress Base address to check
@param[in] Length Length of virtual address range
@retval MemEncryptSevAddressRangeUnencrypted Address range is mapped
unencrypted
@retval MemEncryptSevAddressRangeEncrypted Address range is mapped
encrypted
@retval MemEncryptSevAddressRangeMixed Address range is mapped mixed
@retval MemEncryptSevAddressRangeError Address range is not mapped
**/
MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE
EFIAPI
MemEncryptSevGetAddressRangeState (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS BaseAddress,
IN UINTN Length
)
{
//
// Memory is always encrypted in 32-bit mode
//
return MemEncryptSevAddressRangeEncrypted;
}
/**
This function clears memory encryption bit for the MMIO region specified by
BaseAddress and NumPages.
@param[in] Cr3BaseAddress Cr3 Base Address (if zero then use
current CR3)
@param[in] BaseAddress The physical address that is the start
address of a MMIO region.
@param[in] NumPages The number of pages from start memory
region.
@retval RETURN_SUCCESS The attributes were cleared for the
memory region.
@retval RETURN_INVALID_PARAMETER Number of pages is zero.
@retval RETURN_UNSUPPORTED Clearing the memory encryption attribute
is not supported
**/
RETURN_STATUS
EFIAPI
MemEncryptSevClearMmioPageEncMask (
IN PHYSICAL_ADDRESS Cr3BaseAddress,
IN PHYSICAL_ADDRESS BaseAddress,
IN UINTN NumPages
)
{
//
// Memory encryption bit is not accessible in 32-bit mode
//
return RETURN_UNSUPPORTED;
}
OvmfPkg/MemEncryptSevLib: add support to validate system RAM BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275 Many of the integrity guarantees of SEV-SNP are enforced through the Reverse Map Table (RMP). Each RMP entry contains the GPA at which a particular page of DRAM should be mapped. The guest can request the hypervisor to add pages in the RMP table via the Page State Change VMGEXIT defined in the GHCB specification section 2.5.1 and 4.1.6. Inside each RMP entry is a Validated flag; this flag is automatically cleared to 0 by the CPU hardware when a new RMP entry is created for a guest. Each VM page can be either validated or invalidated, as indicated by the Validated flag in the RMP entry. Memory access to a private page that is not validated generates a #VC. A VM can use the PVALIDATE instruction to validate the private page before using it. During the guest creation, the boot ROM memory is pre-validated by the AMD-SEV firmware. The MemEncryptSevSnpValidateSystemRam() can be called during the SEC and PEI phase to validate the detected system RAM. One of the fields in the Page State Change NAE is the RMP page size. The page size input parameter indicates that either a 4KB or 2MB page should be used while adding the RMP entry. During the validation, when possible, the MemEncryptSevSnpValidateSystemRam() will use the 2MB entry. A hypervisor backing the memory may choose to use the different page size in the RMP entry. In those cases, the PVALIDATE instruction should return SIZEMISMATCH. If a SIZEMISMATCH is detected, then validate all 512-pages constituting a 2MB region. Upon completion, the PVALIDATE instruction sets the rFLAGS.CF to 0 if instruction changed the RMP entry and to 1 if the instruction did not change the RMP entry. The rFlags.CF will be 1 only when a memory region is already validated. We should not double validate a memory as it could lead to a security compromise. If double validation is detected, terminate the boot. Cc: Michael Roth <michael.roth@amd.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Min Xu <min.m.xu@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Erdem Aktas <erdemaktas@google.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Jiewen Yao <Jiewen.yao@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
2021-12-09 04:27:42 +01:00
/**
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
)
{
ASSERT (FALSE);
}