]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c
OvmfPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / OvmfPkg / Library / BaseMemEncryptSevLib / MemEncryptSevLibInternal.c
1 /** @file
2
3 Secure Encrypted Virtualization (SEV) library helper function
4
5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include <Library/BaseLib.h>
12 #include <Library/DebugLib.h>
13 #include <Library/MemEncryptSevLib.h>
14 #include <Library/PcdLib.h>
15 #include <Register/Amd/Cpuid.h>
16 #include <Register/Amd/Msr.h>
17 #include <Register/Cpuid.h>
18 #include <Register/QemuSmramSaveStateMap.h>
19 #include <Register/SmramSaveStateMap.h>
20 #include <Uefi/UefiBaseType.h>
21
22 STATIC BOOLEAN mSevStatus = FALSE;
23 STATIC BOOLEAN mSevStatusChecked = FALSE;
24
25 /**
26
27 Returns a boolean to indicate whether SEV is enabled
28
29 @retval TRUE SEV is enabled
30 @retval FALSE SEV is not enabled
31 **/
32 STATIC
33 BOOLEAN
34 EFIAPI
35 InternalMemEncryptSevIsEnabled (
36 VOID
37 )
38 {
39 UINT32 RegEax;
40 MSR_SEV_STATUS_REGISTER Msr;
41 CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax;
42
43 //
44 // Check if memory encryption leaf exist
45 //
46 AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
47 if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
48 //
49 // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
50 //
51 AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
52
53 if (Eax.Bits.SevBit) {
54 //
55 // Check MSR_0xC0010131 Bit 0 (Sev Enabled)
56 //
57 Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
58 if (Msr.Bits.SevBit) {
59 return TRUE;
60 }
61 }
62 }
63
64 return FALSE;
65 }
66
67 /**
68 Returns a boolean to indicate whether SEV is enabled
69
70 @retval TRUE SEV is enabled
71 @retval FALSE SEV is not enabled
72 **/
73 BOOLEAN
74 EFIAPI
75 MemEncryptSevIsEnabled (
76 VOID
77 )
78 {
79 if (mSevStatusChecked) {
80 return mSevStatus;
81 }
82
83 mSevStatus = InternalMemEncryptSevIsEnabled();
84 mSevStatusChecked = TRUE;
85
86 return mSevStatus;
87 }
88
89
90 /**
91 Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM
92 Save State Map.
93
94 @param[out] BaseAddress The base address of the lowest-address page that
95 covers the initial SMRAM Save State Map.
96
97 @param[out] NumberOfPages The number of pages in the page range that covers
98 the initial SMRAM Save State Map.
99
100 @retval RETURN_SUCCESS BaseAddress and NumberOfPages have been set on
101 output.
102
103 @retval RETURN_UNSUPPORTED SMM is unavailable.
104 **/
105 RETURN_STATUS
106 EFIAPI
107 MemEncryptSevLocateInitialSmramSaveStateMapPages (
108 OUT UINTN *BaseAddress,
109 OUT UINTN *NumberOfPages
110 )
111 {
112 UINTN MapStart;
113 UINTN MapEnd;
114 UINTN MapPagesStart; // MapStart rounded down to page boundary
115 UINTN MapPagesEnd; // MapEnd rounded up to page boundary
116 UINTN MapPagesSize; // difference between MapPagesStart and MapPagesEnd
117
118 if (!FeaturePcdGet (PcdSmmSmramRequire)) {
119 return RETURN_UNSUPPORTED;
120 }
121
122 MapStart = SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET;
123 MapEnd = MapStart + sizeof (QEMU_SMRAM_SAVE_STATE_MAP);
124 MapPagesStart = MapStart & ~(UINTN)EFI_PAGE_MASK;
125 MapPagesEnd = ALIGN_VALUE (MapEnd, EFI_PAGE_SIZE);
126 MapPagesSize = MapPagesEnd - MapPagesStart;
127
128 ASSERT ((MapPagesSize & EFI_PAGE_MASK) == 0);
129
130 *BaseAddress = MapPagesStart;
131 *NumberOfPages = MapPagesSize >> EFI_PAGE_SHIFT;
132
133 return RETURN_SUCCESS;
134 }