3 SEV-SNP Page Validation functions.
5 Copyright (c) 2021 AMD Incorporated. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Uefi/UefiBaseType.h>
12 #include <Library/BaseLib.h>
13 #include <Library/PcdLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/MemEncryptSevLib.h>
17 #include "SnpPageStateChange.h"
18 #include "VirtualMemory.h"
23 } SNP_PRE_VALIDATED_RANGE
;
25 STATIC SNP_PRE_VALIDATED_RANGE mPreValidatedRange
[] = {
26 // The below address range was part of the SEV OVMF metadata, and range
27 // should be pre-validated by the Hypervisor.
29 FixedPcdGet32 (PcdOvmfSecPageTablesBase
),
30 FixedPcdGet32 (PcdOvmfPeiMemFvBase
),
32 // The below range is pre-validated by the Sec/SecMain.c
34 FixedPcdGet32 (PcdOvmfSecValidatedStart
),
35 FixedPcdGet32 (PcdOvmfSecValidatedEnd
)
41 DetectPreValidatedOverLap (
42 IN PHYSICAL_ADDRESS StartAddress
,
43 IN PHYSICAL_ADDRESS EndAddress
,
44 OUT SNP_PRE_VALIDATED_RANGE
*OverlapRange
50 // Check if the specified address range exist in pre-validated array.
52 for (i
= 0; i
< ARRAY_SIZE (mPreValidatedRange
); i
++) {
53 if ((mPreValidatedRange
[i
].StartAddress
< EndAddress
) &&
54 (StartAddress
< mPreValidatedRange
[i
].EndAddress
))
56 OverlapRange
->StartAddress
= mPreValidatedRange
[i
].StartAddress
;
57 OverlapRange
->EndAddress
= mPreValidatedRange
[i
].EndAddress
;
66 Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
68 @param[in] BaseAddress Base address
69 @param[in] NumPages Number of pages starting from the base address
74 MemEncryptSevSnpPreValidateSystemRam (
75 IN PHYSICAL_ADDRESS BaseAddress
,
79 PHYSICAL_ADDRESS EndAddress
;
80 SNP_PRE_VALIDATED_RANGE OverlapRange
;
83 if (!MemEncryptSevSnpIsEnabled ()) {
87 EndAddress
= BaseAddress
+ EFI_PAGES_TO_SIZE (NumPages
);
90 // The page table used in PEI can address up to 4GB memory. If we are asked to
91 // validate a range above the 4GB, then create an identity mapping so that the
92 // PVALIDATE instruction can execute correctly. If the page table entry is not
93 // present then PVALIDATE will #GP.
95 if (BaseAddress
>= SIZE_4GB
) {
96 Status
= InternalMemEncryptSevCreateIdentityMap1G (
99 EFI_PAGES_TO_SIZE (NumPages
)
101 if (EFI_ERROR (Status
)) {
107 while (BaseAddress
< EndAddress
) {
109 // Check if the range overlaps with the pre-validated ranges.
111 if (DetectPreValidatedOverLap (BaseAddress
, EndAddress
, &OverlapRange
)) {
112 // Validate the non-overlap regions.
113 if (BaseAddress
< OverlapRange
.StartAddress
) {
114 NumPages
= EFI_SIZE_TO_PAGES (OverlapRange
.StartAddress
- BaseAddress
);
116 InternalSetPageState (BaseAddress
, NumPages
, SevSnpPagePrivate
, TRUE
);
119 BaseAddress
= OverlapRange
.EndAddress
;
123 // Validate the remaining pages.
124 NumPages
= EFI_SIZE_TO_PAGES (EndAddress
- BaseAddress
);
125 InternalSetPageState (BaseAddress
, NumPages
, SevSnpPagePrivate
, TRUE
);
126 BaseAddress
= EndAddress
;