TianoCore EDK2 master
Loading...
Searching...
No Matches
CcIoMmu.c
Go to the documentation of this file.
1
15#include <Library/PcdLib.h>
17#include "CcIoMmu.h"
18#include "IoMmuInternal.h"
19
20//
21// List of the MAP_INFO structures that have been set up by IoMmuMap() and not
22// yet torn down by IoMmuUnmap(). The list represents the full set of mappings
23// currently in effect.
24//
25STATIC LIST_ENTRY mMapInfos = INITIALIZE_LIST_HEAD_VARIABLE (mMapInfos);
26
27//
28// Indicate if the feature of reserved memory is supported in DMA operation.
29//
30BOOLEAN mReservedSharedMemSupported = FALSE;
31
32//
33// ASCII names for EDKII_IOMMU_OPERATION constants, for debug logging.
34//
35STATIC CONST CHAR8 *CONST
36mBusMasterOperationName[EdkiiIoMmuOperationMaximum] = {
37 "Read",
38 "Write",
39 "CommonBuffer",
40 "Read64",
41 "Write64",
42 "CommonBuffer64"
43};
44
76EFIAPI
79 IN EDKII_IOMMU_OPERATION Operation,
80 IN VOID *HostAddress,
81 IN OUT UINTN *NumberOfBytes,
82 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
83 OUT VOID **Mapping
84 )
85{
86 EFI_STATUS Status;
87 MAP_INFO *MapInfo;
88 EFI_ALLOCATE_TYPE AllocateType;
89 COMMON_BUFFER_HEADER *CommonBufferHeader;
90 VOID *DecryptionSource;
91
92 DEBUG ((
93 DEBUG_VERBOSE,
94 "%a: Operation=%a Host=0x%p Bytes=0x%Lx\n",
95 __func__,
96 ((Operation >= 0 &&
97 Operation < ARRAY_SIZE (mBusMasterOperationName)) ?
98 mBusMasterOperationName[Operation] :
99 "Invalid"),
100 HostAddress,
101 (UINT64)((NumberOfBytes == NULL) ? 0 : *NumberOfBytes)
102 ));
103
104 if ((HostAddress == NULL) || (NumberOfBytes == NULL) || (DeviceAddress == NULL) ||
105 (Mapping == NULL))
106 {
107 return EFI_INVALID_PARAMETER;
108 }
109
110 Status = EFI_SUCCESS;
111
112 //
113 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
114 // called later.
115 //
116 MapInfo = AllocatePool (sizeof (MAP_INFO));
117 if (MapInfo == NULL) {
118 Status = EFI_OUT_OF_RESOURCES;
119 goto Failed;
120 }
121
122 //
123 // Initialize the MAP_INFO structure, except the PlainTextAddress field
124 //
125 ZeroMem (&MapInfo->Link, sizeof MapInfo->Link);
126 MapInfo->Signature = MAP_INFO_SIG;
127 MapInfo->Operation = Operation;
128 MapInfo->NumberOfBytes = *NumberOfBytes;
129 MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes);
130 MapInfo->CryptedAddress = (UINTN)HostAddress;
131 MapInfo->ReservedMemBitmap = 0;
132
133 //
134 // In the switch statement below, we point "MapInfo->PlainTextAddress" to the
135 // plaintext buffer, according to Operation. We also set "DecryptionSource".
136 //
137 MapInfo->PlainTextAddress = MAX_ADDRESS;
138 AllocateType = AllocateAnyPages;
139 DecryptionSource = (VOID *)(UINTN)MapInfo->CryptedAddress;
140 switch (Operation) {
141 //
142 // For BusMasterRead[64] and BusMasterWrite[64] operations, a bounce buffer
143 // is necessary regardless of whether the original (crypted) buffer crosses
144 // the 4GB limit or not -- we have to allocate a separate plaintext buffer.
145 // The only variable is whether the plaintext buffer should be under 4GB.
146 //
149 MapInfo->PlainTextAddress = BASE_4GB - 1;
150 AllocateType = AllocateMaxAddress;
151 //
152 // fall through
153 //
156 //
157 // Allocate the implicit plaintext bounce buffer.
158 //
160 AllocateType,
162 MapInfo
163 );
164 if (EFI_ERROR (Status)) {
165 goto FreeMapInfo;
166 }
167
168 break;
169
170 //
171 // For BusMasterCommonBuffer[64] operations, a to-be-plaintext buffer and a
172 // stash buffer (for in-place decryption) have been allocated already, with
173 // AllocateBuffer(). We only check whether the address of the to-be-plaintext
174 // buffer is low enough for the requested operation.
175 //
177 if ((MapInfo->CryptedAddress > BASE_4GB) ||
178 (EFI_PAGES_TO_SIZE (MapInfo->NumberOfPages) >
179 BASE_4GB - MapInfo->CryptedAddress))
180 {
181 //
182 // CommonBuffer operations cannot be remapped. If the common buffer is
183 // above 4GB, then it is not possible to generate a mapping, so return an
184 // error.
185 //
186 Status = EFI_UNSUPPORTED;
187 goto FreeMapInfo;
188 }
189
190 //
191 // fall through
192 //
194 //
195 // The buffer at MapInfo->CryptedAddress comes from AllocateBuffer().
196 //
197 MapInfo->PlainTextAddress = MapInfo->CryptedAddress;
198 //
199 // Stash the crypted data.
200 //
201 CommonBufferHeader = (COMMON_BUFFER_HEADER *)(
202 (UINTN)MapInfo->CryptedAddress - EFI_PAGE_SIZE
203 );
204 ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG);
205 CopyMem (
206 CommonBufferHeader->StashBuffer,
207 (VOID *)(UINTN)MapInfo->CryptedAddress,
208 MapInfo->NumberOfBytes
209 );
210 //
211 // Point "DecryptionSource" to the stash buffer so that we decrypt
212 // it to the original location, after the switch statement.
213 //
214 DecryptionSource = CommonBufferHeader->StashBuffer;
215 MapInfo->ReservedMemBitmap = CommonBufferHeader->ReservedMemBitmap;
216 break;
217
218 default:
219 //
220 // Operation is invalid
221 //
222 Status = EFI_INVALID_PARAMETER;
223 goto FreeMapInfo;
224 }
225
226 if (MapInfo->ReservedMemBitmap == 0) {
227 //
228 // If MapInfo->ReservedMemBitmap is 0, it means the bounce buffer is not allocated
229 // from the pre-allocated shared memory, so it must be converted to shared memory here.
230 //
231 if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
232 //
233 // Clear the memory encryption mask on the plaintext buffer.
234 //
236 0,
237 MapInfo->PlainTextAddress,
238 MapInfo->NumberOfPages
239 );
240 } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
241 //
242 // Set the memory shared bit.
243 //
245 0,
246 MapInfo->PlainTextAddress,
247 MapInfo->NumberOfPages
248 );
249 } else {
250 ASSERT (FALSE);
251 }
252 }
253
254 ASSERT_EFI_ERROR (Status);
255 if (EFI_ERROR (Status)) {
256 CpuDeadLoop ();
257 }
258
259 //
260 // If this is a read operation from the Bus Master's point of view,
261 // then copy the contents of the real buffer into the mapped buffer
262 // so the Bus Master can read the contents of the real buffer.
263 //
264 // For BusMasterCommonBuffer[64] operations, the CopyMem() below will decrypt
265 // the original data (from the stash buffer) back to the original location.
266 //
267 if ((Operation == EdkiiIoMmuOperationBusMasterRead) ||
268 (Operation == EdkiiIoMmuOperationBusMasterRead64) ||
271 {
272 CopyMem (
273 (VOID *)(UINTN)MapInfo->PlainTextAddress,
274 DecryptionSource,
275 MapInfo->NumberOfBytes
276 );
277 }
278
279 //
280 // Track all MAP_INFO structures.
281 //
282 InsertHeadList (&mMapInfos, &MapInfo->Link);
283 //
284 // Populate output parameters.
285 //
286 *DeviceAddress = MapInfo->PlainTextAddress;
287 *Mapping = MapInfo;
288
289 DEBUG ((
290 DEBUG_VERBOSE,
291 "%a: Mapping=0x%p Device(PlainText)=0x%Lx Crypted=0x%Lx Pages=0x%Lx, ReservedMemBitmap=0x%Lx\n",
292 __func__,
293 MapInfo,
294 MapInfo->PlainTextAddress,
295 MapInfo->CryptedAddress,
296 (UINT64)MapInfo->NumberOfPages,
297 MapInfo->ReservedMemBitmap
298 ));
299
300 return EFI_SUCCESS;
301
302FreeMapInfo:
303 FreePool (MapInfo);
304
305Failed:
306 *NumberOfBytes = 0;
307 return Status;
308}
309
328STATIC
330EFIAPI
333 IN VOID *Mapping,
334 IN BOOLEAN MemoryMapLocked
335 )
336{
337 MAP_INFO *MapInfo;
338 EFI_STATUS Status;
339 COMMON_BUFFER_HEADER *CommonBufferHeader;
340 VOID *EncryptionTarget;
341
342 DEBUG ((
343 DEBUG_VERBOSE,
344 "%a: Mapping=0x%p MemoryMapLocked=%d\n",
345 __func__,
346 Mapping,
347 MemoryMapLocked
348 ));
349
350 if (Mapping == NULL) {
351 return EFI_INVALID_PARAMETER;
352 }
353
354 MapInfo = (MAP_INFO *)Mapping;
355 Status = EFI_SUCCESS;
356 //
357 // set CommonBufferHeader to suppress incorrect compiler/analyzer warnings
358 //
359 CommonBufferHeader = NULL;
360
361 //
362 // For BusMasterWrite[64] operations and BusMasterCommonBuffer[64] operations
363 // we have to encrypt the results, ultimately to the original place (i.e.,
364 // "MapInfo->CryptedAddress").
365 //
366 // For BusMasterCommonBuffer[64] operations however, this encryption has to
367 // land in-place, so divert the encryption to the stash buffer first.
368 //
369 EncryptionTarget = (VOID *)(UINTN)MapInfo->CryptedAddress;
370
371 switch (MapInfo->Operation) {
374 ASSERT (MapInfo->PlainTextAddress == MapInfo->CryptedAddress);
375
376 CommonBufferHeader = (COMMON_BUFFER_HEADER *)(
377 (UINTN)MapInfo->PlainTextAddress - EFI_PAGE_SIZE
378 );
379 ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG);
380 EncryptionTarget = CommonBufferHeader->StashBuffer;
381 //
382 // fall through
383 //
384
387 CopyMem (
388 EncryptionTarget,
389 (VOID *)(UINTN)MapInfo->PlainTextAddress,
390 MapInfo->NumberOfBytes
391 );
392 break;
393
394 default:
395 //
396 // nothing to encrypt after BusMasterRead[64] operations
397 //
398 break;
399 }
400
401 if (MapInfo->ReservedMemBitmap == 0) {
402 if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
403 //
404 // Restore the memory encryption mask on the area we used to hold the
405 // plaintext.
406 //
408 0,
409 MapInfo->PlainTextAddress,
410 MapInfo->NumberOfPages
411 );
412 } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {
413 //
414 // Restore the memory shared bit mask on the area we used to hold the
415 // plaintext.
416 //
418 0,
419 MapInfo->PlainTextAddress,
420 MapInfo->NumberOfPages
421 );
422 } else {
423 ASSERT (FALSE);
424 }
425 }
426
427 ASSERT_EFI_ERROR (Status);
428 if (EFI_ERROR (Status)) {
429 CpuDeadLoop ();
430 }
431
432 //
433 // For BusMasterCommonBuffer[64] operations, copy the stashed data to the
434 // original (now encrypted) location.
435 //
436 // For all other operations, fill the late bounce buffer (which existed as
437 // plaintext at some point) with zeros, and then release it (unless the UEFI
438 // memory map is locked).
439 //
440 if ((MapInfo->Operation == EdkiiIoMmuOperationBusMasterCommonBuffer) ||
441 (MapInfo->Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64))
442 {
443 CopyMem (
444 (VOID *)(UINTN)MapInfo->CryptedAddress,
445 CommonBufferHeader->StashBuffer,
446 MapInfo->NumberOfBytes
447 );
448 } else {
449 ZeroMem (
450 (VOID *)(UINTN)MapInfo->PlainTextAddress,
451 EFI_PAGES_TO_SIZE (MapInfo->NumberOfPages)
452 );
453
454 if (!MemoryMapLocked) {
455 IoMmuFreeBounceBuffer (MapInfo);
456 }
457 }
458
459 //
460 // Forget the MAP_INFO structure, then free it (unless the UEFI memory map is
461 // locked).
462 //
463 RemoveEntryList (&MapInfo->Link);
464 if (!MemoryMapLocked) {
465 FreePool (MapInfo);
466 }
467
468 return EFI_SUCCESS;
469}
470
484EFIAPI
487 IN VOID *Mapping
488 )
489{
490 return IoMmuUnmapWorker (
491 This,
492 Mapping,
493 FALSE // MemoryMapLocked
494 );
495}
496
520EFIAPI
524 IN EFI_MEMORY_TYPE MemoryType,
525 IN UINTN Pages,
526 IN OUT VOID **HostAddress,
527 IN UINT64 Attributes
528 )
529{
530 EFI_STATUS Status;
531 EFI_PHYSICAL_ADDRESS PhysicalAddress;
532 VOID *StashBuffer;
533 UINTN CommonBufferPages;
534 COMMON_BUFFER_HEADER *CommonBufferHeader;
535 UINT32 ReservedMemBitmap;
536
537 DEBUG ((
538 DEBUG_VERBOSE,
539 "%a: MemoryType=%u Pages=0x%Lx Attributes=0x%Lx\n",
540 __func__,
541 (UINT32)MemoryType,
542 (UINT64)Pages,
543 Attributes
544 ));
545
546 //
547 // Validate Attributes
548 //
549 if ((Attributes & EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
550 return EFI_UNSUPPORTED;
551 }
552
553 //
554 // Check for invalid inputs
555 //
556 if (HostAddress == NULL) {
557 return EFI_INVALID_PARAMETER;
558 }
559
560 //
561 // The only valid memory types are EfiBootServicesData and
562 // EfiRuntimeServicesData
563 //
564 if ((MemoryType != EfiBootServicesData) &&
565 (MemoryType != EfiRuntimeServicesData))
566 {
567 return EFI_INVALID_PARAMETER;
568 }
569
570 //
571 // We'll need a header page for the COMMON_BUFFER_HEADER structure.
572 //
573 if (Pages > MAX_UINTN - 1) {
574 return EFI_OUT_OF_RESOURCES;
575 }
576
577 CommonBufferPages = Pages + 1;
578
579 //
580 // Allocate the stash in EfiBootServicesData type memory.
581 //
582 // Map() will temporarily save encrypted data in the stash for
583 // BusMasterCommonBuffer[64] operations, so the data can be decrypted to the
584 // original location.
585 //
586 // Unmap() will temporarily save plaintext data in the stash for
587 // BusMasterCommonBuffer[64] operations, so the data can be encrypted to the
588 // original location.
589 //
590 // StashBuffer always resides in encrypted memory.
591 //
592 StashBuffer = AllocatePages (Pages);
593 if (StashBuffer == NULL) {
594 return EFI_OUT_OF_RESOURCES;
595 }
596
597 PhysicalAddress = (UINTN)-1;
598 if ((Attributes & EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
599 //
600 // Limit allocations to memory below 4GB
601 //
602 PhysicalAddress = SIZE_4GB - 1;
603 }
604
606 MemoryType,
607 CommonBufferPages,
608 &PhysicalAddress,
609 &ReservedMemBitmap
610 );
611
612 if (EFI_ERROR (Status)) {
613 goto FreeStashBuffer;
614 }
615
616 CommonBufferHeader = (VOID *)(UINTN)PhysicalAddress;
617 PhysicalAddress += EFI_PAGE_SIZE;
618
619 CommonBufferHeader->Signature = COMMON_BUFFER_SIG;
620 CommonBufferHeader->StashBuffer = StashBuffer;
621 CommonBufferHeader->ReservedMemBitmap = ReservedMemBitmap;
622
623 *HostAddress = (VOID *)(UINTN)PhysicalAddress;
624
625 DEBUG ((
626 DEBUG_VERBOSE,
627 "%a: Host=0x%Lx Stash=0x%p\n",
628 __func__,
629 PhysicalAddress,
630 StashBuffer
631 ));
632 return EFI_SUCCESS;
633
634FreeStashBuffer:
635 FreePages (StashBuffer, Pages);
636 return Status;
637}
638
653EFIAPI
656 IN UINTN Pages,
657 IN VOID *HostAddress
658 )
659{
660 UINTN CommonBufferPages;
661 COMMON_BUFFER_HEADER *CommonBufferHeader;
662
663 DEBUG ((
664 DEBUG_VERBOSE,
665 "%a: Host=0x%p Pages=0x%Lx\n",
666 __func__,
667 HostAddress,
668 (UINT64)Pages
669 ));
670
671 CommonBufferPages = Pages + 1;
672 CommonBufferHeader = (COMMON_BUFFER_HEADER *)(
673 (UINTN)HostAddress - EFI_PAGE_SIZE
674 );
675
676 //
677 // Check the signature.
678 //
679 ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG);
680 if (CommonBufferHeader->Signature != COMMON_BUFFER_SIG) {
681 return EFI_INVALID_PARAMETER;
682 }
683
684 //
685 // Free the stash buffer. This buffer was always encrypted, so no need to
686 // zero it.
687 //
688 FreePages (CommonBufferHeader->StashBuffer, Pages);
689
690 //
691 // Release the common buffer itself. Unmap() has re-encrypted it in-place, so
692 // no need to zero it.
693 //
694 return IoMmuFreeCommonBuffer (CommonBufferHeader, CommonBufferPages);
695}
696
746EFIAPI
749 IN EFI_HANDLE DeviceHandle,
750 IN VOID *Mapping,
751 IN UINT64 IoMmuAccess
752 )
753{
754 MAP_INFO *MapInfo;
755 EFI_STATUS Status;
756
757 DEBUG ((DEBUG_VERBOSE, "%a: Mapping=0x%p Access=%lu\n", __func__, Mapping, IoMmuAccess));
758
759 if (Mapping == NULL) {
760 return EFI_INVALID_PARAMETER;
761 }
762
763 Status = EFI_SUCCESS;
764
765 //
766 // An IoMmuAccess value of 0 is always accepted, validate any non-zero value.
767 //
768 if (IoMmuAccess != 0) {
769 MapInfo = (MAP_INFO *)Mapping;
770
771 //
772 // The mapping operation already implied the access mode. Validate that
773 // the supplied access mode matches operation access mode.
774 //
775 switch (MapInfo->Operation) {
778 if (IoMmuAccess != EDKII_IOMMU_ACCESS_READ) {
779 Status = EFI_INVALID_PARAMETER;
780 }
781
782 break;
783
786 if (IoMmuAccess != EDKII_IOMMU_ACCESS_WRITE) {
787 Status = EFI_INVALID_PARAMETER;
788 }
789
790 break;
791
794 if (IoMmuAccess != (EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE)) {
795 Status = EFI_INVALID_PARAMETER;
796 }
797
798 break;
799
800 default:
801 Status = EFI_UNSUPPORTED;
802 }
803 }
804
805 return Status;
806}
807
808EDKII_IOMMU_PROTOCOL mIoMmu = {
809 EDKII_IOMMU_PROTOCOL_REVISION,
811 IoMmuMap,
815};
816
837STATIC
838VOID
839EFIAPI
841 IN EFI_EVENT Event,
842 IN VOID *EventToSignal
843 )
844{
845 //
846 // (1) The NotifyFunctions of all the events in
847 // EFI_EVENT_GROUP_EXIT_BOOT_SERVICES will have been queued before
848 // IoMmuExitBoot() is entered.
849 //
850 // (2) IoMmuExitBoot() is executing minimally at TPL_CALLBACK.
851 //
852 // (3) IoMmuExitBoot() has been queued in unspecified order relative to the
853 // NotifyFunctions of all the other events in
854 // EFI_EVENT_GROUP_EXIT_BOOT_SERVICES whose NotifyTpl is the same as
855 // Event's.
856 //
857 // Consequences:
858 //
859 // - If Event's NotifyTpl is TPL_CALLBACK, then some other NotifyFunctions
860 // queued at TPL_CALLBACK may be invoked after IoMmuExitBoot() returns.
861 //
862 // - If Event's NotifyTpl is TPL_NOTIFY, then some other NotifyFunctions
863 // queued at TPL_NOTIFY may be invoked after IoMmuExitBoot() returns; plus
864 // *all* NotifyFunctions queued at TPL_CALLBACK will be invoked strictly
865 // after all NotifyFunctions queued at TPL_NOTIFY, including
866 // IoMmuExitBoot(), have been invoked.
867 //
868 // - By signaling EventToSignal here, whose NotifyTpl is TPL_CALLBACK, we
869 // queue EventToSignal's NotifyFunction after the NotifyFunctions of *all*
870 // events in EFI_EVENT_GROUP_EXIT_BOOT_SERVICES.
871 //
872 DEBUG ((DEBUG_VERBOSE, "%a\n", __func__));
873 gBS->SignalEvent (EventToSignal);
874}
875
889STATIC
890VOID
891EFIAPI
893 IN EFI_EVENT Event,
894 IN VOID *Context
895 )
896{
897 LIST_ENTRY *Node;
898 LIST_ENTRY *NextNode;
899 MAP_INFO *MapInfo;
900
901 DEBUG ((DEBUG_VERBOSE, "%a\n", __func__));
902
903 //
904 // All drivers that had set up IOMMU mappings have halted their respective
905 // controllers by now; tear down the mappings.
906 //
907 for (Node = GetFirstNode (&mMapInfos); Node != &mMapInfos; Node = NextNode) {
908 NextNode = GetNextNode (&mMapInfos, Node);
909 MapInfo = CR (Node, MAP_INFO, Link, MAP_INFO_SIG);
911 &mIoMmu, // This
912 MapInfo, // Mapping
913 TRUE // MemoryMapLocked
914 );
915 }
916
917 //
918 // Release the reserved shared memory as well.
919 //
921}
922
928EFIAPI
930 VOID
931 )
932{
933 EFI_STATUS Status;
934 EFI_EVENT UnmapAllMappingsEvent;
935 EFI_EVENT ExitBootEvent;
936 EFI_HANDLE Handle;
937
938 //
939 // Create the "late" event whose notification function will tear down all
940 // left-over IOMMU mappings.
941 //
942 Status = gBS->CreateEvent (
943 EVT_NOTIFY_SIGNAL, // Type
944 TPL_CALLBACK, // NotifyTpl
945 IoMmuUnmapAllMappings, // NotifyFunction
946 NULL, // NotifyContext
947 &UnmapAllMappingsEvent // Event
948 );
949 if (EFI_ERROR (Status)) {
950 return Status;
951 }
952
953 //
954 // Create the event whose notification function will be queued by
955 // gBS->ExitBootServices() and will signal the event created above.
956 //
957 Status = gBS->CreateEvent (
958 EVT_SIGNAL_EXIT_BOOT_SERVICES, // Type
959 TPL_CALLBACK, // NotifyTpl
960 IoMmuExitBoot, // NotifyFunction
961 UnmapAllMappingsEvent, // NotifyContext
962 &ExitBootEvent // Event
963 );
964 if (EFI_ERROR (Status)) {
965 goto CloseUnmapAllMappingsEvent;
966 }
967
968 Handle = NULL;
969 Status = gBS->InstallMultipleProtocolInterfaces (
970 &Handle,
972 &mIoMmu,
973 NULL
974 );
975 if (EFI_ERROR (Status)) {
976 goto CloseExitBootEvent;
977 }
978
979 //
980 // For CC guests, use reserved shared memory for DMA operation.
981 //
982 mReservedSharedMemSupported = TRUE;
983 Status = IoMmuInitReservedSharedMem ();
984 if (EFI_ERROR (Status)) {
985 mReservedSharedMemSupported = FALSE;
986 } else {
987 DEBUG ((DEBUG_INFO, "%a: Feature of reserved memory for DMA is supported.\n", __func__));
988 }
989
990 return EFI_SUCCESS;
991
992CloseExitBootEvent:
993 gBS->CloseEvent (ExitBootEvent);
994
995CloseUnmapAllMappingsEvent:
996 gBS->CloseEvent (UnmapAllMappingsEvent);
997
998 return Status;
999}
UINT64 UINTN
#define MAX_ADDRESS
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
Definition: BaseLib.h:2904
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
STATIC VOID EFIAPI IoMmuExitBoot(IN EFI_EVENT Event, IN VOID *EventToSignal)
Definition: CcIoMmu.c:840
EFI_STATUS EFIAPI IoMmuFreeBuffer(IN EDKII_IOMMU_PROTOCOL *This, IN UINTN Pages, IN VOID *HostAddress)
Definition: CcIoMmu.c:654
EFI_STATUS EFIAPI IoMmuAllocateBuffer(IN EDKII_IOMMU_PROTOCOL *This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN OUT VOID **HostAddress, IN UINT64 Attributes)
Definition: CcIoMmu.c:521
STATIC VOID EFIAPI IoMmuUnmapAllMappings(IN EFI_EVENT Event, IN VOID *Context)
Definition: CcIoMmu.c:892
STATIC EFI_STATUS EFIAPI IoMmuUnmapWorker(IN EDKII_IOMMU_PROTOCOL *This, IN VOID *Mapping, IN BOOLEAN MemoryMapLocked)
Definition: CcIoMmu.c:331
EFI_STATUS EFIAPI IoMmuUnmap(IN EDKII_IOMMU_PROTOCOL *This, IN VOID *Mapping)
Definition: CcIoMmu.c:485
EFI_STATUS EFIAPI InstallIoMmuProtocol(VOID)
Definition: CcIoMmu.c:929
EFI_STATUS EFIAPI IoMmuMap(IN EDKII_IOMMU_PROTOCOL *This, IN EDKII_IOMMU_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
Definition: CcIoMmu.c:77
EFI_STATUS EFIAPI IoMmuSetAttribute(IN EDKII_IOMMU_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN VOID *Mapping, IN UINT64 IoMmuAccess)
Definition: CcIoMmu.c:747
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS IoMmuAllocateCommonBuffer(IN EFI_MEMORY_TYPE MemoryType, IN UINTN CommonBufferPages, OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress, OUT UINT32 *ReservedMemBitmap)
Definition: IoMmuBuffer.c:457
EFI_STATUS IoMmuFreeBounceBuffer(IN OUT MAP_INFO *MapInfo)
Definition: IoMmuBuffer.c:421
EFI_STATUS IoMmuFreeCommonBuffer(IN COMMON_BUFFER_HEADER *CommonBufferHeader, IN UINTN CommonBufferPages)
Definition: IoMmuBuffer.c:492
EFI_STATUS IoMmuInitReservedSharedMem(VOID)
Definition: IoMmuBuffer.c:136
EFI_STATUS IoMmuReleaseReservedSharedMem(BOOLEAN MemoryMapLocked)
Definition: IoMmuBuffer.c:203
EFI_STATUS IoMmuAllocateBounceBuffer(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN OUT MAP_INFO *MapInfo)
Definition: IoMmuBuffer.c:372
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#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
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
RETURN_STATUS EFIAPI MemEncryptSevClearPageEncMask(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
RETURN_STATUS EFIAPI MemEncryptSevSetPageEncMask(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
RETURN_STATUS EFIAPI MemEncryptTdxSetPageSharedBit(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
RETURN_STATUS EFIAPI MemEncryptTdxClearPageSharedBit(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
EFI_GUID gEdkiiIoMmuProtocolGuid
EDKII_IOMMU_OPERATION
Definition: IoMmu.h:44
@ EdkiiIoMmuOperationBusMasterWrite
Definition: IoMmu.h:54
@ EdkiiIoMmuOperationBusMasterWrite64
Definition: IoMmu.h:69
@ EdkiiIoMmuOperationBusMasterCommonBuffer
Definition: IoMmu.h:59
@ EdkiiIoMmuOperationBusMasterRead64
Definition: IoMmu.h:64
@ EdkiiIoMmuOperationBusMasterRead
Definition: IoMmu.h:49
@ EdkiiIoMmuOperationBusMasterCommonBuffer64
Definition: IoMmu.h:74
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_MEMORY_TYPE
@ EfiBootServicesData
@ EfiRuntimeServicesData
EFI_ALLOCATE_TYPE
Definition: UefiSpec.h:29
@ AllocateMaxAddress
Definition: UefiSpec.h:38
@ AllocateAnyPages
Definition: UefiSpec.h:33