TianoCore EDK2 master
Loading...
Searching...
No Matches
PeiSnpSystemRamValidate.c
Go to the documentation of this file.
1
11#include <Uefi/UefiBaseType.h>
12#include <Library/BaseLib.h>
13#include <Library/PcdLib.h>
14#include <Library/DebugLib.h>
16
17#include "SnpPageStateChange.h"
18#include "VirtualMemory.h"
19
20STATIC UINT8 mPscBufferPage[EFI_PAGE_SIZE];
21
22typedef struct {
23 UINT64 StartAddress;
24 UINT64 EndAddress;
26
27STATIC SNP_PRE_VALIDATED_RANGE mPreValidatedRange[] = {
28 // The below address range was part of the SEV OVMF metadata, and range
29 // should be pre-validated by the Hypervisor.
30 {
31 FixedPcdGet32 (PcdOvmfSecPageTablesBase),
32 FixedPcdGet32 (PcdOvmfPeiMemFvBase),
33 },
34 // The below range is pre-validated by the Sec/SecMain.c
35 {
36 FixedPcdGet32 (PcdOvmfSecValidatedStart),
37 FixedPcdGet32 (PcdOvmfSecValidatedEnd)
38 },
39};
40
42BOOLEAN
43DetectPreValidatedOverLap (
44 IN PHYSICAL_ADDRESS StartAddress,
45 IN PHYSICAL_ADDRESS EndAddress,
46 OUT SNP_PRE_VALIDATED_RANGE *OverlapRange
47 )
48{
49 UINTN i;
50
51 //
52 // Check if the specified address range exist in pre-validated array.
53 //
54 for (i = 0; i < ARRAY_SIZE (mPreValidatedRange); i++) {
55 if ((mPreValidatedRange[i].StartAddress < EndAddress) &&
56 (StartAddress < mPreValidatedRange[i].EndAddress))
57 {
58 OverlapRange->StartAddress = mPreValidatedRange[i].StartAddress;
59 OverlapRange->EndAddress = mPreValidatedRange[i].EndAddress;
60 return TRUE;
61 }
62 }
63
64 return FALSE;
65}
66
74VOID
75EFIAPI
77 IN PHYSICAL_ADDRESS BaseAddress,
78 IN UINTN NumPages
79 )
80{
81 PHYSICAL_ADDRESS EndAddress;
82 SNP_PRE_VALIDATED_RANGE OverlapRange;
83 EFI_STATUS Status;
84
86 return;
87 }
88
89 EndAddress = BaseAddress + EFI_PAGES_TO_SIZE (NumPages);
90
91 //
92 // The page table used in PEI can address up to 4GB memory. If we are asked to
93 // validate a range above the 4GB, then create an identity mapping so that the
94 // PVALIDATE instruction can execute correctly. If the page table entry is not
95 // present then PVALIDATE will #GP.
96 //
97 if (BaseAddress >= SIZE_4GB) {
99 0,
100 BaseAddress,
101 EFI_PAGES_TO_SIZE (NumPages)
102 );
103 if (EFI_ERROR (Status)) {
104 ASSERT (FALSE);
105 CpuDeadLoop ();
106 }
107 }
108
109 while (BaseAddress < EndAddress) {
110 //
111 // Check if the range overlaps with the pre-validated ranges.
112 //
113 if (DetectPreValidatedOverLap (BaseAddress, EndAddress, &OverlapRange)) {
114 // Validate the non-overlap regions.
115 if (BaseAddress < OverlapRange.StartAddress) {
116 NumPages = EFI_SIZE_TO_PAGES (OverlapRange.StartAddress - BaseAddress);
117
119 BaseAddress,
120 NumPages,
121 SevSnpPagePrivate,
122 TRUE,
123 mPscBufferPage,
124 sizeof (mPscBufferPage)
125 );
126 }
127
128 BaseAddress = OverlapRange.EndAddress;
129 continue;
130 }
131
132 // Validate the remaining pages.
133 NumPages = EFI_SIZE_TO_PAGES (EndAddress - BaseAddress);
135 BaseAddress,
136 NumPages,
137 SevSnpPagePrivate,
138 TRUE,
139 mPscBufferPage,
140 sizeof (mPscBufferPage)
141 );
142 BaseAddress = EndAddress;
143 }
144}
UINT64 UINTN
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
BOOLEAN EFIAPI MemEncryptSevSnpIsEnabled(VOID)
#define FixedPcdGet32(TokenName)
Definition: PcdLib.h:92
RETURN_STATUS EFIAPI InternalMemEncryptSevCreateIdentityMap1G(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS PhysicalAddress, IN UINTN Length)
VOID EFIAPI MemEncryptSevSnpPreValidateSystemRam(IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
VOID InternalSetPageState(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages, IN SEV_SNP_PAGE_STATE State, IN BOOLEAN UseLargeEntry, IN VOID *PscBuffer, IN UINTN PscBufferSize)
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200