TianoCore EDK2 master
Loading...
Searching...
No Matches
AmdSev.c
Go to the documentation of this file.
1
10#include <Library/BaseLib.h>
11#include <Library/CpuLib.h>
13#include <Library/DebugLib.h>
17#include <Register/Amd/Ghcb.h>
18#include <Register/Amd/Msr.h>
19
20#include "AmdSev.h"
21
32VOID
34 IN UINT8 ReasonCode
35 )
36{
38
39 //
40 // Use the GHCB MSR Protocol to request termination by the hypervisor
41 //
42 Msr.GhcbPhysicalAddress = 0;
43 Msr.GhcbTerminate.Function = GHCB_INFO_TERMINATE_REQUEST;
44 Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;
45 Msr.GhcbTerminate.ReasonCode = ReasonCode;
46 AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
47
48 AsmVmgExit ();
49
50 ASSERT (FALSE);
51 CpuDeadLoop ();
52}
53
61BOOLEAN
63 VOID
64 )
65{
67
68 //
69 // Read the SEV_STATUS MSR to determine whether SEV-SNP is active.
70 //
71 Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
72
73 //
74 // Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled)
75 //
76 if (Msr.Bits.SevSnpBit) {
77 return TRUE;
78 }
79
80 return FALSE;
81}
82
88VOID
91 )
92{
94
95 //
96 // Use the GHCB MSR Protocol to request to register the GPA.
97 //
98 Msr.GhcbPhysicalAddress = Address & ~EFI_PAGE_MASK;
99 Msr.GhcbGpaRegister.Function = GHCB_INFO_GHCB_GPA_REGISTER_REQUEST;
100 AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
101
102 AsmVmgExit ();
103
104 Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
105
106 //
107 // If hypervisor responded with a different GPA than requested then fail.
108 //
109 if ((Msr.GhcbGpaRegister.Function != GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE) ||
110 ((Msr.GhcbPhysicalAddress & ~EFI_PAGE_MASK) != Address))
111 {
112 SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);
113 }
114}
115
120STATIC
121BOOLEAN
123 VOID
124 )
125{
127 UINT64 Features;
128
129 //
130 // Use the GHCB MSR Protocol to query the hypervisor capabilities
131 //
132 Msr.GhcbPhysicalAddress = 0;
133 Msr.GhcbHypervisorFeatures.Function = GHCB_HYPERVISOR_FEATURES_REQUEST;
134 AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
135
136 AsmVmgExit ();
137
138 Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
139
140 Features = RShiftU64 (Msr.GhcbPhysicalAddress, 12);
141
142 if ((Msr.GhcbHypervisorFeatures.Function != GHCB_HYPERVISOR_FEATURES_RESPONSE) ||
143 (!(Features & GHCB_HV_FEATURES_SNP)))
144 {
145 return FALSE;
146 }
147
148 return TRUE;
149}
150
158VOID
160 VOID
161 )
162{
164 GHCB *Ghcb;
165
166 //
167 // Use the GHCB MSR Protocol to obtain the GHCB SEV-ES Information for
168 // protocol checking
169 //
170 Msr.GhcbPhysicalAddress = 0;
171 Msr.GhcbInfo.Function = GHCB_INFO_SEV_INFO_GET;
172 AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
173
174 AsmVmgExit ();
175
176 Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
177
178 if (Msr.GhcbInfo.Function != GHCB_INFO_SEV_INFO) {
179 SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);
180 }
181
182 if (Msr.GhcbProtocol.SevEsProtocolMin > Msr.GhcbProtocol.SevEsProtocolMax) {
183 SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
184 }
185
186 if ((Msr.GhcbProtocol.SevEsProtocolMin > GHCB_VERSION_MAX) ||
187 (Msr.GhcbProtocol.SevEsProtocolMax < GHCB_VERSION_MIN))
188 {
189 SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
190 }
191
192 //
193 // We cannot use the MemEncryptSevSnpIsEnabled () because the
194 // ProcessLibraryConstructorList () is not called yet.
195 //
196 if (SevSnpIsEnabled ()) {
197 //
198 // Check if hypervisor supports the SNP feature
199 //
201 SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
202 }
203
204 //
205 // Unlike the SEV-ES guest, the SNP requires that GHCB GPA must be
206 // registered with the Hypervisor before the use. This can be done
207 // using the new VMGEXIT defined in the GHCB v2. Register the GPA
208 // before it is used.
209 //
211 }
212
213 //
214 // SEV-ES protocol checking succeeded, set the initial GHCB address
215 //
216 Msr.GhcbPhysicalAddress = FixedPcdGet32 (PcdOvmfSecGhcbBase);
217 AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
218
219 Ghcb = Msr.Ghcb;
220 SetMem (Ghcb, FixedPcdGet32 (PcdOvmfSecGhcbSize), 0);
221
222 //
223 // Set the version to the maximum that can be supported
224 //
225 Ghcb->ProtocolVersion = MIN (Msr.GhcbProtocol.SevEsProtocolMax, GHCB_VERSION_MAX);
226 Ghcb->GhcbUsage = GHCB_STANDARD_USAGE;
227}
228
239BOOLEAN
241 VOID
242 )
243{
244 OVMF_WORK_AREA *WorkArea;
245
246 //
247 // Ensure that the size of the Confidential Computing work area header
248 // is same as what is provided through a fixed PCD.
249 //
250 ASSERT (
251 (UINTN)FixedPcdGet32 (PcdOvmfConfidentialComputingWorkAreaHeader) ==
253 );
254
255 WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
256
257 return ((WorkArea != NULL) && (WorkArea->Header.GuestType == CcGuestTypeAmdSev));
258}
259
271BOOLEAN
273 VOID
274 )
275{
276 SEC_SEV_ES_WORK_AREA *SevEsWorkArea;
277
278 if (!IsSevGuest ()) {
279 return FALSE;
280 }
281
282 SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);
283
284 return ((SevEsWorkArea->SevStatusMsrValue & BIT1) != 0);
285}
286
293VOID
295 VOID
296 )
297{
298 PHYSICAL_ADDRESS Start, End;
299
300 if (IsSevGuest () && SevSnpIsEnabled ()) {
301 Start = (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecValidatedStart);
302 End = (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecValidatedEnd);
303
305 }
306}
307
317VOID
319 VOID
320 )
321{
322 PHYSICAL_ADDRESS Cr3;
323 UINT64 ApicAddress;
324 VOID *Buffer;
325 UINTN BufferSize;
326 IA32_MAP_ATTRIBUTE MapAttribute;
327 IA32_MAP_ATTRIBUTE MapMask;
328 RETURN_STATUS Status;
329
330 if (!SevEsIsEnabled ()) {
331 return;
332 }
333
334 ApicAddress = (UINT64)GetLocalApicBaseAddress ();
335 Buffer = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecApicPageTableBase);
336 Cr3 = AsmReadCr3 ();
337
338 MapAttribute.Uint64 = ApicAddress;
339 MapAttribute.Bits.Present = 1;
340 MapAttribute.Bits.ReadWrite = 1;
341 MapMask.Uint64 = MAX_UINT64;
342 BufferSize = SIZE_4KB;
343
344 Status = PageTableMap (
345 (UINTN *)&Cr3,
346 Paging4Level,
347 Buffer,
348 &BufferSize,
349 ApicAddress,
350 SIZE_4KB,
351 &MapAttribute,
352 &MapMask,
353 NULL
354 );
355 if (RETURN_ERROR (Status)) {
356 DEBUG ((DEBUG_ERROR, "Failed to map APIC MMIO region as unencrypted: %d\n", Status));
357 ASSERT (FALSE);
358 }
359
360 CpuFlushTlb ();
361}
UINT64 UINTN
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
VOID EFIAPI CpuFlushTlb(VOID)
RETURN_STATUS EFIAPI PageTableMap(IN OUT UINTN *PageTable OPTIONAL, IN PAGING_MODE PagingMode, IN VOID *Buffer, IN OUT UINTN *BufferSize, IN UINT64 LinearAddress, IN UINT64 Length, IN IA32_MAP_ATTRIBUTE *Attribute, IN IA32_MAP_ATTRIBUTE *Mask, OUT BOOLEAN *IsModified OPTIONAL)
UINTN EFIAPI AsmReadCr3(VOID)
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
Definition: GccInlinePriv.c:60
UINT64 EFIAPI AsmWriteMsr64(IN UINT32 Index, IN UINT64 Value)
UINTN EFIAPI GetLocalApicBaseAddress(VOID)
Definition: BaseXApicLib.c:66
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID EFIAPI MemEncryptSevSnpPreValidateSystemRam(IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
STATIC VOID SevEsProtocolFailure(IN UINT8 ReasonCode)
Definition: AmdSev.c:185
STATIC BOOLEAN HypervisorSnpFeatureCheck(VOID)
Definition: AmdSev.c:122
VOID SecValidateSystemRam(VOID)
Definition: AmdSev.c:294
VOID SecMapApicBaseUnencrypted(VOID)
Definition: AmdSev.c:318
VOID SevEsProtocolCheck(VOID)
Definition: AmdSev.c:159
BOOLEAN SevSnpIsEnabled(VOID)
Definition: AmdSev.c:62
STATIC VOID SevSnpGhcbRegister(EFI_PHYSICAL_ADDRESS Address)
Definition: AmdSev.c:89
BOOLEAN IsSevGuest(VOID)
Definition: AmdSev.c:240
BOOLEAN SevEsIsEnabled(VOID)
Definition: AmdSev.c:272
#define FixedPcdGet32(TokenName)
Definition: PcdLib.h:92
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define MSR_SEV_STATUS
Definition: SevSnpMsr.h:116
#define MSR_SEV_ES_GHCB
Definition: SevSnpMsr.h:24
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
UINT32 EFIAPI AsmReadMsr32(IN UINT32 Index)
Definition: X86Msr.c:27