]> git.proxmox.com Git - mirror_edk2.git/blob - StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / StandaloneMmPkg / Library / StandaloneMmMemLib / StandaloneMmMemLib.c
1 /** @file
2 Instance of MM memory check library.
3
4 MM memory check library implementation. This library consumes MM_ACCESS_PROTOCOL
5 to get MMRAM information. In order to use this library instance, the platform should produce
6 all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core
7 and MM driver) and/or specific dedicated hardware.
8
9 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
10 Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
11
12 SPDX-License-Identifier: BSD-2-Clause-Patent
13
14 **/
15
16 #include <PiMm.h>
17
18 #include <Library/BaseLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/DebugLib.h>
21
22 EFI_MMRAM_DESCRIPTOR *mMmMemLibInternalMmramRanges;
23 UINTN mMmMemLibInternalMmramCount;
24
25 //
26 // Maximum support address used to check input buffer
27 //
28 EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress = 0;
29
30 /**
31 Calculate and save the maximum support address.
32
33 **/
34 VOID
35 MmMemLibInternalCalculateMaximumSupportAddress (
36 VOID
37 );
38
39 /**
40 Initialize cached Mmram Ranges from HOB.
41
42 @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.
43 @retval EFI_SUCCESS MmRanges are populated successfully.
44
45 **/
46 EFI_STATUS
47 MmMemLibInternalPopulateMmramRanges (
48 VOID
49 );
50
51 /**
52 Deinitialize cached Mmram Ranges.
53
54 **/
55 VOID
56 MmMemLibInternalFreeMmramRanges (
57 VOID
58 );
59
60 /**
61 This function check if the buffer is valid per processor architecture and not overlap with MMRAM.
62
63 @param Buffer The buffer start address to be checked.
64 @param Length The buffer length to be checked.
65
66 @retval TRUE This buffer is valid per processor architecture and not overlap with MMRAM.
67 @retval FALSE This buffer is not valid per processor architecture or overlap with MMRAM.
68 **/
69 BOOLEAN
70 EFIAPI
71 MmIsBufferOutsideMmValid (
72 IN EFI_PHYSICAL_ADDRESS Buffer,
73 IN UINT64 Length
74 )
75 {
76 UINTN Index;
77
78 //
79 // Check override.
80 // NOTE: (B:0->L:4G) is invalid for IA32, but (B:1->L:4G-1)/(B:4G-1->L:1) is valid.
81 //
82 if ((Length > mMmMemLibInternalMaximumSupportAddress) ||
83 (Buffer > mMmMemLibInternalMaximumSupportAddress) ||
84 ((Length != 0) && (Buffer > (mMmMemLibInternalMaximumSupportAddress - (Length - 1)))))
85 {
86 //
87 // Overflow happen
88 //
89 DEBUG ((
90 DEBUG_ERROR,
91 "MmIsBufferOutsideMmValid: Overflow: Buffer (0x%lx) - Length (0x%lx), MaximumSupportAddress (0x%lx)\n",
92 Buffer,
93 Length,
94 mMmMemLibInternalMaximumSupportAddress
95 ));
96 return FALSE;
97 }
98
99 for (Index = 0; Index < mMmMemLibInternalMmramCount; Index++) {
100 if (((Buffer >= mMmMemLibInternalMmramRanges[Index].CpuStart) &&
101 (Buffer < mMmMemLibInternalMmramRanges[Index].CpuStart + mMmMemLibInternalMmramRanges[Index].PhysicalSize)) ||
102 ((mMmMemLibInternalMmramRanges[Index].CpuStart >= Buffer) &&
103 (mMmMemLibInternalMmramRanges[Index].CpuStart < Buffer + Length)))
104 {
105 DEBUG ((
106 DEBUG_ERROR,
107 "MmIsBufferOutsideMmValid: Overlap: Buffer (0x%lx) - Length (0x%lx), ",
108 Buffer,
109 Length
110 ));
111 DEBUG ((
112 DEBUG_ERROR,
113 "CpuStart (0x%lx) - PhysicalSize (0x%lx)\n",
114 mMmMemLibInternalMmramRanges[Index].CpuStart,
115 mMmMemLibInternalMmramRanges[Index].PhysicalSize
116 ));
117 return FALSE;
118 }
119 }
120
121 return TRUE;
122 }
123
124 /**
125 Copies a source buffer (non-MMRAM) to a destination buffer (MMRAM).
126
127 This function copies a source buffer (non-MMRAM) to a destination buffer (MMRAM).
128 It checks if source buffer is valid per processor architecture and not overlap with MMRAM.
129 If the check passes, it copies memory and returns EFI_SUCCESS.
130 If the check fails, it return EFI_SECURITY_VIOLATION.
131 The implementation must be reentrant.
132
133 @param DestinationBuffer The pointer to the destination buffer of the memory copy.
134 @param SourceBuffer The pointer to the source buffer of the memory copy.
135 @param Length The number of bytes to copy from SourceBuffer to DestinationBuffer.
136
137 @retval EFI_SECURITY_VIOLATION The SourceBuffer is invalid per processor architecture or overlap with MMRAM.
138 @retval EFI_SUCCESS Memory is copied.
139
140 **/
141 EFI_STATUS
142 EFIAPI
143 MmCopyMemToMmram (
144 OUT VOID *DestinationBuffer,
145 IN CONST VOID *SourceBuffer,
146 IN UINTN Length
147 )
148 {
149 if (!MmIsBufferOutsideMmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)SourceBuffer, Length)) {
150 DEBUG ((DEBUG_ERROR, "MmCopyMemToMmram: Security Violation: Source (0x%x), Length (0x%x)\n", SourceBuffer, Length));
151 return EFI_SECURITY_VIOLATION;
152 }
153
154 CopyMem (DestinationBuffer, SourceBuffer, Length);
155 return EFI_SUCCESS;
156 }
157
158 /**
159 Copies a source buffer (MMRAM) to a destination buffer (NON-MMRAM).
160
161 This function copies a source buffer (non-MMRAM) to a destination buffer (MMRAM).
162 It checks if destination buffer is valid per processor architecture and not overlap with MMRAM.
163 If the check passes, it copies memory and returns EFI_SUCCESS.
164 If the check fails, it returns EFI_SECURITY_VIOLATION.
165 The implementation must be reentrant.
166
167 @param DestinationBuffer The pointer to the destination buffer of the memory copy.
168 @param SourceBuffer The pointer to the source buffer of the memory copy.
169 @param Length The number of bytes to copy from SourceBuffer to DestinationBuffer.
170
171 @retval EFI_SECURITY_VIOLATION The DestinationBuffer is invalid per processor architecture or overlap with MMRAM.
172 @retval EFI_SUCCESS Memory is copied.
173
174 **/
175 EFI_STATUS
176 EFIAPI
177 MmCopyMemFromMmram (
178 OUT VOID *DestinationBuffer,
179 IN CONST VOID *SourceBuffer,
180 IN UINTN Length
181 )
182 {
183 if (!MmIsBufferOutsideMmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)DestinationBuffer, Length)) {
184 DEBUG ((
185 DEBUG_ERROR,
186 "MmCopyMemFromMmram: Security Violation: Destination (0x%x), Length (0x%x)\n",
187 DestinationBuffer,
188 Length
189 ));
190 return EFI_SECURITY_VIOLATION;
191 }
192
193 CopyMem (DestinationBuffer, SourceBuffer, Length);
194 return EFI_SUCCESS;
195 }
196
197 /**
198 Copies a source buffer (NON-MMRAM) to a destination buffer (NON-MMRAM).
199
200 This function copies a source buffer (non-MMRAM) to a destination buffer (MMRAM).
201 It checks if source buffer and destination buffer are valid per processor architecture and not overlap with MMRAM.
202 If the check passes, it copies memory and returns EFI_SUCCESS.
203 If the check fails, it returns EFI_SECURITY_VIOLATION.
204 The implementation must be reentrant, and it must handle the case where source buffer overlaps destination buffer.
205
206 @param DestinationBuffer The pointer to the destination buffer of the memory copy.
207 @param SourceBuffer The pointer to the source buffer of the memory copy.
208 @param Length The number of bytes to copy from SourceBuffer to DestinationBuffer.
209
210 @retval EFI_SECURITY_VIOLATION The DestinationBuffer is invalid per processor architecture or overlap with MMRAM.
211 @retval EFI_SECURITY_VIOLATION The SourceBuffer is invalid per processor architecture or overlap with MMRAM.
212 @retval EFI_SUCCESS Memory is copied.
213
214 **/
215 EFI_STATUS
216 EFIAPI
217 MmCopyMem (
218 OUT VOID *DestinationBuffer,
219 IN CONST VOID *SourceBuffer,
220 IN UINTN Length
221 )
222 {
223 if (!MmIsBufferOutsideMmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)DestinationBuffer, Length)) {
224 DEBUG ((
225 DEBUG_ERROR,
226 "MmCopyMem: Security Violation: Destination (0x%x), Length (0x%x)\n",
227 DestinationBuffer,
228 Length
229 ));
230 return EFI_SECURITY_VIOLATION;
231 }
232
233 if (!MmIsBufferOutsideMmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)SourceBuffer, Length)) {
234 DEBUG ((DEBUG_ERROR, "MmCopyMem: Security Violation: Source (0x%x), Length (0x%x)\n", SourceBuffer, Length));
235 return EFI_SECURITY_VIOLATION;
236 }
237
238 CopyMem (DestinationBuffer, SourceBuffer, Length);
239 return EFI_SUCCESS;
240 }
241
242 /**
243 Fills a target buffer (NON-MMRAM) with a byte value.
244
245 This function fills a target buffer (non-MMRAM) with a byte value.
246 It checks if target buffer is valid per processor architecture and not overlap with MMRAM.
247 If the check passes, it fills memory and returns EFI_SUCCESS.
248 If the check fails, it returns EFI_SECURITY_VIOLATION.
249
250 @param Buffer The memory to set.
251 @param Length The number of bytes to set.
252 @param Value The value with which to fill Length bytes of Buffer.
253
254 @retval EFI_SECURITY_VIOLATION The Buffer is invalid per processor architecture or overlap with MMRAM.
255 @retval EFI_SUCCESS Memory is set.
256
257 **/
258 EFI_STATUS
259 EFIAPI
260 MmSetMem (
261 OUT VOID *Buffer,
262 IN UINTN Length,
263 IN UINT8 Value
264 )
265 {
266 if (!MmIsBufferOutsideMmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Length)) {
267 DEBUG ((DEBUG_ERROR, "MmSetMem: Security Violation: Source (0x%x), Length (0x%x)\n", Buffer, Length));
268 return EFI_SECURITY_VIOLATION;
269 }
270
271 SetMem (Buffer, Length, Value);
272 return EFI_SUCCESS;
273 }
274
275 /**
276 The constructor function initializes the Mm Mem library
277
278 @param [in] ImageHandle The firmware allocated handle for the EFI image.
279 @param [in] MmSystemTable A pointer to the EFI System Table.
280
281 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
282
283 **/
284 EFI_STATUS
285 EFIAPI
286 MemLibConstructor (
287 IN EFI_HANDLE ImageHandle,
288 IN EFI_MM_SYSTEM_TABLE *MmSystemTable
289 )
290 {
291 EFI_STATUS Status;
292
293 //
294 // Calculate and save maximum support address
295 //
296 MmMemLibInternalCalculateMaximumSupportAddress ();
297
298 //
299 // Initialize cached Mmram Ranges from HOB.
300 //
301 Status = MmMemLibInternalPopulateMmramRanges ();
302
303 return Status;
304 }
305
306 /**
307 Destructor for Mm Mem library.
308
309 @param ImageHandle The image handle of the process.
310 @param MmSystemTable The EFI System Table pointer.
311
312 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
313
314 **/
315 EFI_STATUS
316 EFIAPI
317 MemLibDestructor (
318 IN EFI_HANDLE ImageHandle,
319 IN EFI_MM_SYSTEM_TABLE *MmSystemTable
320 )
321 {
322 //
323 // Deinitialize cached Mmram Ranges.
324 //
325 MmMemLibInternalFreeMmramRanges ();
326
327 return EFI_SUCCESS;
328 }