]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Library / BaseMemEncryptSevLib / X64 / VirtualMemory.c
CommitLineData
c330af02
TL
1/** @file\r
2\r
3 Virtual Memory Management Services to test an address range encryption state\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/CpuLib.h>\r
12#include <Library/MemEncryptSevLib.h>\r
13\r
14#include "VirtualMemory.h"\r
15\r
16/**\r
17 Returns the (updated) address range state based upon the page table\r
18 entry.\r
19\r
20 @param[in] CurrentState The current address range state\r
21 @param[in] PageDirectoryEntry The page table entry to check\r
22 @param[in] AddressEncMask The encryption mask\r
23\r
24 @retval MemEncryptSevAddressRangeUnencrypted Address range is mapped\r
25 unencrypted\r
26 @retval MemEncryptSevAddressRangeEncrypted Address range is mapped\r
27 encrypted\r
28 @retval MemEncryptSevAddressRangeMixed Address range is mapped mixed\r
29**/\r
30STATIC\r
31MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE\r
32UpdateAddressState (\r
33 IN MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE CurrentState,\r
34 IN UINT64 PageDirectoryEntry,\r
35 IN UINT64 AddressEncMask\r
36 )\r
37{\r
38 if (CurrentState == MemEncryptSevAddressRangeEncrypted) {\r
39 if ((PageDirectoryEntry & AddressEncMask) == 0) {\r
40 CurrentState = MemEncryptSevAddressRangeMixed;\r
41 }\r
42 } else if (CurrentState == MemEncryptSevAddressRangeUnencrypted) {\r
43 if ((PageDirectoryEntry & AddressEncMask) != 0) {\r
44 CurrentState = MemEncryptSevAddressRangeMixed;\r
45 }\r
46 } else if (CurrentState == MemEncryptSevAddressRangeError) {\r
47 //\r
48 // First address check, set initial state\r
49 //\r
50 if ((PageDirectoryEntry & AddressEncMask) == 0) {\r
51 CurrentState = MemEncryptSevAddressRangeUnencrypted;\r
52 } else {\r
53 CurrentState = MemEncryptSevAddressRangeEncrypted;\r
54 }\r
55 }\r
56\r
57 return CurrentState;\r
58}\r
59\r
60/**\r
61 Returns the encryption state of the specified virtual address range.\r
62\r
63 @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use\r
64 current CR3)\r
65 @param[in] BaseAddress Base address to check\r
66 @param[in] Length Length of virtual address range\r
67\r
68 @retval MemEncryptSevAddressRangeUnencrypted Address range is mapped\r
69 unencrypted\r
70 @retval MemEncryptSevAddressRangeEncrypted Address range is mapped\r
71 encrypted\r
72 @retval MemEncryptSevAddressRangeMixed Address range is mapped mixed\r
73 @retval MemEncryptSevAddressRangeError Address range is not mapped\r
74**/\r
75MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE\r
76EFIAPI\r
77InternalMemEncryptSevGetAddressRangeState (\r
78 IN PHYSICAL_ADDRESS Cr3BaseAddress,\r
79 IN PHYSICAL_ADDRESS BaseAddress,\r
80 IN UINTN Length\r
81 )\r
82{\r
83 PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;\r
84 PAGE_MAP_AND_DIRECTORY_POINTER *PageUpperDirectoryPointerEntry;\r
85 PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;\r
86 PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;\r
87 PAGE_TABLE_ENTRY *PageDirectory2MEntry;\r
88 PAGE_TABLE_4K_ENTRY *PageTableEntry;\r
89 UINT64 AddressEncMask;\r
90 UINT64 PgTableMask;\r
91 PHYSICAL_ADDRESS Address;\r
92 PHYSICAL_ADDRESS AddressEnd;\r
93 MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE State;\r
94\r
95 //\r
96 // If Cr3BaseAddress is not specified then read the current CR3\r
97 //\r
98 if (Cr3BaseAddress == 0) {\r
ac0a286f 99 Cr3BaseAddress = AsmReadCr3 ();\r
c330af02
TL
100 }\r
101\r
ac0a286f 102 AddressEncMask = MemEncryptSevGetEncryptionMask ();\r
c330af02
TL
103 AddressEncMask &= PAGING_1G_ADDRESS_MASK_64;\r
104\r
105 PgTableMask = AddressEncMask | EFI_PAGE_MASK;\r
106\r
107 State = MemEncryptSevAddressRangeError;\r
108\r
109 //\r
110 // Encryption is on a page basis, so start at the beginning of the\r
111 // virtual address page boundary and walk page-by-page.\r
112 //\r
ac0a286f 113 Address = (PHYSICAL_ADDRESS)(UINTN)BaseAddress & ~EFI_PAGE_MASK;\r
c330af02 114 AddressEnd = (PHYSICAL_ADDRESS)\r
ac0a286f 115 (UINTN)(BaseAddress + Length);\r
c330af02
TL
116\r
117 while (Address < AddressEnd) {\r
ac0a286f 118 PageMapLevel4Entry = (VOID *)(Cr3BaseAddress & ~PgTableMask);\r
c330af02
TL
119 PageMapLevel4Entry += PML4_OFFSET (Address);\r
120 if (!PageMapLevel4Entry->Bits.Present) {\r
121 return MemEncryptSevAddressRangeError;\r
122 }\r
123\r
ac0a286f
MK
124 PageDirectory1GEntry = (VOID *)(\r
125 (PageMapLevel4Entry->Bits.PageTableBaseAddress <<\r
126 12) & ~PgTableMask\r
127 );\r
c330af02
TL
128 PageDirectory1GEntry += PDP_OFFSET (Address);\r
129 if (!PageDirectory1GEntry->Bits.Present) {\r
130 return MemEncryptSevAddressRangeError;\r
131 }\r
132\r
133 //\r
134 // If the MustBe1 bit is not 1, it's not actually a 1GB entry\r
135 //\r
136 if (PageDirectory1GEntry->Bits.MustBe1) {\r
137 //\r
138 // Valid 1GB page\r
139 //\r
140 State = UpdateAddressState (\r
141 State,\r
142 PageDirectory1GEntry->Uint64,\r
143 AddressEncMask\r
144 );\r
145\r
146 Address += BIT30;\r
147 continue;\r
148 }\r
149\r
150 //\r
151 // Actually a PDP\r
152 //\r
153 PageUpperDirectoryPointerEntry =\r
ac0a286f 154 (PAGE_MAP_AND_DIRECTORY_POINTER *)PageDirectory1GEntry;\r
c330af02 155 PageDirectory2MEntry =\r
ac0a286f
MK
156 (VOID *)(\r
157 (PageUpperDirectoryPointerEntry->Bits.PageTableBaseAddress <<\r
158 12) & ~PgTableMask\r
159 );\r
c330af02
TL
160 PageDirectory2MEntry += PDE_OFFSET (Address);\r
161 if (!PageDirectory2MEntry->Bits.Present) {\r
162 return MemEncryptSevAddressRangeError;\r
163 }\r
164\r
165 //\r
166 // If the MustBe1 bit is not a 1, it's not a 2MB entry\r
167 //\r
168 if (PageDirectory2MEntry->Bits.MustBe1) {\r
169 //\r
170 // Valid 2MB page\r
171 //\r
172 State = UpdateAddressState (\r
173 State,\r
174 PageDirectory2MEntry->Uint64,\r
175 AddressEncMask\r
176 );\r
177\r
178 Address += BIT21;\r
179 continue;\r
180 }\r
181\r
182 //\r
183 // Actually a PMD\r
184 //\r
185 PageDirectoryPointerEntry =\r
186 (PAGE_MAP_AND_DIRECTORY_POINTER *)PageDirectory2MEntry;\r
187 PageTableEntry =\r
188 (VOID *)(\r
ac0a286f
MK
189 (PageDirectoryPointerEntry->Bits.PageTableBaseAddress <<\r
190 12) & ~PgTableMask\r
191 );\r
c330af02
TL
192 PageTableEntry += PTE_OFFSET (Address);\r
193 if (!PageTableEntry->Bits.Present) {\r
194 return MemEncryptSevAddressRangeError;\r
195 }\r
196\r
197 State = UpdateAddressState (\r
198 State,\r
199 PageTableEntry->Uint64,\r
200 AddressEncMask\r
201 );\r
202\r
203 Address += EFI_PAGE_SIZE;\r
204 }\r
205\r
206 return State;\r
207}\r