/** @file Secure Encrypted Virtualization (SEV) library helper function Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include #include STATIC BOOLEAN mSevStatus = FALSE; STATIC BOOLEAN mSevStatusChecked = FALSE; /** Returns a boolean to indicate whether SEV is enabled @retval TRUE SEV is enabled @retval FALSE SEV is not enabled **/ STATIC BOOLEAN EFIAPI InternalMemEncryptSevIsEnabled ( VOID ) { UINT32 RegEax; MSR_SEV_STATUS_REGISTER Msr; CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax; // // Check if memory encryption leaf exist // AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) { // // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported) // AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL); if (Eax.Bits.SevBit) { // // Check MSR_0xC0010131 Bit 0 (Sev Enabled) // Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS); if (Msr.Bits.SevBit) { return TRUE; } } } return FALSE; } /** Returns a boolean to indicate whether SEV is enabled @retval TRUE SEV is enabled @retval FALSE SEV is not enabled **/ BOOLEAN EFIAPI MemEncryptSevIsEnabled ( VOID ) { if (mSevStatusChecked) { return mSevStatus; } mSevStatus = InternalMemEncryptSevIsEnabled(); mSevStatusChecked = TRUE; return mSevStatus; } /** Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM Save State Map. @param[out] BaseAddress The base address of the lowest-address page that covers the initial SMRAM Save State Map. @param[out] NumberOfPages The number of pages in the page range that covers the initial SMRAM Save State Map. @retval RETURN_SUCCESS BaseAddress and NumberOfPages have been set on output. @retval RETURN_UNSUPPORTED SMM is unavailable. **/ RETURN_STATUS EFIAPI MemEncryptSevLocateInitialSmramSaveStateMapPages ( OUT UINTN *BaseAddress, OUT UINTN *NumberOfPages ) { UINTN MapStart; UINTN MapEnd; UINTN MapPagesStart; // MapStart rounded down to page boundary UINTN MapPagesEnd; // MapEnd rounded up to page boundary UINTN MapPagesSize; // difference between MapPagesStart and MapPagesEnd if (!FeaturePcdGet (PcdSmmSmramRequire)) { return RETURN_UNSUPPORTED; } MapStart = SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET; MapEnd = MapStart + sizeof (QEMU_SMRAM_SAVE_STATE_MAP); MapPagesStart = MapStart & ~(UINTN)EFI_PAGE_MASK; MapPagesEnd = ALIGN_VALUE (MapEnd, EFI_PAGE_SIZE); MapPagesSize = MapPagesEnd - MapPagesStart; ASSERT ((MapPagesSize & EFI_PAGE_MASK) == 0); *BaseAddress = MapPagesStart; *NumberOfPages = MapPagesSize >> EFI_PAGE_SHIFT; return RETURN_SUCCESS; }