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