]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
OvmfPkg/BaseMemEncryptSevLib: skip the pre-validated system RAM
[mirror_edk2.git] / OvmfPkg / Library / BaseMemEncryptSevLib / PeiMemEncryptSevLibInternal.c
CommitLineData
b97dc4b9
TL
1/** @file\r
2\r
3 Secure Encrypted Virtualization (SEV) library helper function\r
4\r
5 Copyright (c) 2020, AMD Incorporated. All rights reserved.<BR>\r
6\r
7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
8\r
9**/\r
10\r
11#include <Library/BaseLib.h>\r
12#include <Library/DebugLib.h>\r
13#include <Library/MemEncryptSevLib.h>\r
14#include <Library/PcdLib.h>\r
15#include <Register/Amd/Cpuid.h>\r
16#include <Register/Amd/Msr.h>\r
17#include <Register/Cpuid.h>\r
18#include <Uefi/UefiBaseType.h>\r
19\r
ac0a286f
MK
20STATIC BOOLEAN mSevStatus = FALSE;\r
21STATIC BOOLEAN mSevEsStatus = FALSE;\r
d9822304 22STATIC BOOLEAN mSevSnpStatus = FALSE;\r
ac0a286f 23STATIC BOOLEAN mSevStatusChecked = FALSE;\r
b97dc4b9 24\r
ac0a286f
MK
25STATIC UINT64 mSevEncryptionMask = 0;\r
26STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE;\r
b97dc4b9
TL
27\r
28/**\r
29 Reads and sets the status of SEV features.\r
30\r
31 **/\r
32STATIC\r
33VOID\r
34EFIAPI\r
35InternalMemEncryptSevStatus (\r
36 VOID\r
37 )\r
38{\r
39 UINT32 RegEax;\r
40 MSR_SEV_STATUS_REGISTER Msr;\r
41 CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax;\r
42 BOOLEAN ReadSevMsr;\r
43 SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
44\r
45 ReadSevMsr = FALSE;\r
46\r
ac0a286f
MK
47 SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);\r
48 if ((SevEsWorkArea != NULL) && (SevEsWorkArea->EncryptionMask != 0)) {\r
b97dc4b9
TL
49 //\r
50 // The MSR has been read before, so it is safe to read it again and avoid\r
51 // having to validate the CPUID information.\r
52 //\r
53 ReadSevMsr = TRUE;\r
54 } else {\r
55 //\r
56 // Check if memory encryption leaf exist\r
57 //\r
58 AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
59 if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {\r
60 //\r
61 // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)\r
62 //\r
63 AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);\r
64\r
65 if (Eax.Bits.SevBit) {\r
66 ReadSevMsr = TRUE;\r
67 }\r
68 }\r
69 }\r
70\r
71 if (ReadSevMsr) {\r
72 //\r
73 // Check MSR_0xC0010131 Bit 0 (Sev Enabled)\r
74 //\r
75 Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);\r
76 if (Msr.Bits.SevBit) {\r
77 mSevStatus = TRUE;\r
78 }\r
79\r
80 //\r
81 // Check MSR_0xC0010131 Bit 1 (Sev-Es Enabled)\r
82 //\r
83 if (Msr.Bits.SevEsBit) {\r
84 mSevEsStatus = TRUE;\r
85 }\r
d9822304
BS
86\r
87 //\r
88 // Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled)\r
89 //\r
90 if (Msr.Bits.SevSnpBit) {\r
91 mSevSnpStatus = TRUE;\r
92 }\r
b97dc4b9
TL
93 }\r
94\r
95 mSevStatusChecked = TRUE;\r
96}\r
97\r
d9822304
BS
98/**\r
99 Returns a boolean to indicate whether SEV-SNP is enabled.\r
100\r
101 @retval TRUE SEV-SNP is enabled\r
102 @retval FALSE SEV-SNP is not enabled\r
103**/\r
104BOOLEAN\r
105EFIAPI\r
106MemEncryptSevSnpIsEnabled (\r
107 VOID\r
108 )\r
109{\r
110 if (!mSevStatusChecked) {\r
111 InternalMemEncryptSevStatus ();\r
112 }\r
113\r
114 return mSevSnpStatus;\r
115}\r
116\r
b97dc4b9
TL
117/**\r
118 Returns a boolean to indicate whether SEV-ES is enabled.\r
119\r
120 @retval TRUE SEV-ES is enabled\r
121 @retval FALSE SEV-ES is not enabled\r
122**/\r
123BOOLEAN\r
124EFIAPI\r
125MemEncryptSevEsIsEnabled (\r
126 VOID\r
127 )\r
128{\r
129 if (!mSevStatusChecked) {\r
130 InternalMemEncryptSevStatus ();\r
131 }\r
132\r
133 return mSevEsStatus;\r
134}\r
135\r
136/**\r
137 Returns a boolean to indicate whether SEV is enabled.\r
138\r
139 @retval TRUE SEV is enabled\r
140 @retval FALSE SEV is not enabled\r
141**/\r
142BOOLEAN\r
143EFIAPI\r
144MemEncryptSevIsEnabled (\r
145 VOID\r
146 )\r
147{\r
148 if (!mSevStatusChecked) {\r
149 InternalMemEncryptSevStatus ();\r
150 }\r
151\r
152 return mSevStatus;\r
153}\r
154\r
155/**\r
156 Returns the SEV encryption mask.\r
157\r
158 @return The SEV pagtable encryption mask\r
159**/\r
160UINT64\r
161EFIAPI\r
162MemEncryptSevGetEncryptionMask (\r
163 VOID\r
164 )\r
165{\r
166 if (!mSevEncryptionMaskSaved) {\r
167 SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
168\r
ac0a286f 169 SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);\r
b97dc4b9
TL
170 if (SevEsWorkArea != NULL) {\r
171 mSevEncryptionMask = SevEsWorkArea->EncryptionMask;\r
172 } else {\r
173 CPUID_MEMORY_ENCRYPTION_INFO_EBX Ebx;\r
174\r
175 //\r
176 // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)\r
177 //\r
178 AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);\r
179 mSevEncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits);\r
180 }\r
181\r
182 mSevEncryptionMaskSaved = TRUE;\r
183 }\r
184\r
185 return mSevEncryptionMask;\r
186}\r