1 /** @file
2 
3   The protocol provides support to allocate, free, map and umap a DMA buffer
4   for bus master (e.g PciHostBridge). When SEV is enabled, the DMA operations
5   must be performed on unencrypted buffer hence we use a bounce buffer to map
6   the guest buffer into an unencrypted DMA buffer.
7 
8   Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
9   Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
10 
11   SPDX-License-Identifier: BSD-2-Clause-Patent
12 
13 **/
14 
15 #include "AmdSevIoMmu.h"
16 
17 #define MAP_INFO_SIG SIGNATURE_64 ('M', 'A', 'P', '_', 'I', 'N', 'F', 'O')
18 
19 typedef struct {
20   UINT64                                    Signature;
21   LIST_ENTRY                                Link;
22   EDKII_IOMMU_OPERATION                     Operation;
23   UINTN                                     NumberOfBytes;
24   UINTN                                     NumberOfPages;
25   EFI_PHYSICAL_ADDRESS                      CryptedAddress;
26   EFI_PHYSICAL_ADDRESS                      PlainTextAddress;
27 } MAP_INFO;
28 
29 //
30 // List of the MAP_INFO structures that have been set up by IoMmuMap() and not
31 // yet torn down by IoMmuUnmap(). The list represents the full set of mappings
32 // currently in effect.
33 //
34 STATIC LIST_ENTRY mMapInfos = INITIALIZE_LIST_HEAD_VARIABLE (mMapInfos);
35 
36 #define COMMON_BUFFER_SIG SIGNATURE_64 ('C', 'M', 'N', 'B', 'U', 'F', 'F', 'R')
37 
38 //
39 // ASCII names for EDKII_IOMMU_OPERATION constants, for debug logging.
40 //
41 STATIC CONST CHAR8 * CONST
42 mBusMasterOperationName[EdkiiIoMmuOperationMaximum] = {
43   "Read",
44   "Write",
45   "CommonBuffer",
46   "Read64",
47   "Write64",
48   "CommonBuffer64"
49 };
50 
51 //
52 // The following structure enables Map() and Unmap() to perform in-place
53 // decryption and encryption, respectively, for BusMasterCommonBuffer[64]
54 // operations, without dynamic memory allocation or release.
55 //
56 // Both COMMON_BUFFER_HEADER and COMMON_BUFFER_HEADER.StashBuffer are allocated
57 // by AllocateBuffer() and released by FreeBuffer().
58 //
59 #pragma pack (1)
60 typedef struct {
61   UINT64 Signature;
62 
63   //
64   // Always allocated from EfiBootServicesData type memory, and always
65   // encrypted.
66   //
67   VOID *StashBuffer;
68 
69   //
70   // Followed by the actual common buffer, starting at the next page.
71   //
72 } COMMON_BUFFER_HEADER;
73 #pragma pack ()
74 
75 /**
76   Provides the controller-specific addresses required to access system memory
77   from a DMA bus master. On SEV guest, the DMA operations must be performed on
78   shared buffer hence we allocate a bounce buffer to map the HostAddress to a
79   DeviceAddress. The Encryption attribute is removed from the DeviceAddress
80   buffer.
81 
82   @param  This                  The protocol instance pointer.
83   @param  Operation             Indicates if the bus master is going to read or
84                                 write to system memory.
85   @param  HostAddress           The system memory address to map to the PCI
86                                 controller.
87   @param  NumberOfBytes         On input the number of bytes to map. On output
88                                 the number of bytes that were mapped.
89   @param  DeviceAddress         The resulting map address for the bus master
90                                 PCI controller to use to access the hosts
91                                 HostAddress.
92   @param  Mapping               A resulting value to pass to Unmap().
93 
94   @retval EFI_SUCCESS           The range was mapped for the returned
95                                 NumberOfBytes.
96   @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common
97                                 buffer.
98   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
99   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a
100                                 lack of resources.
101   @retval EFI_DEVICE_ERROR      The system hardware could not map the requested
102                                 address.
103 
104 **/
105 EFI_STATUS
106 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)107 IoMmuMap (
108   IN     EDKII_IOMMU_PROTOCOL                       *This,
109   IN     EDKII_IOMMU_OPERATION                      Operation,
110   IN     VOID                                       *HostAddress,
111   IN OUT UINTN                                      *NumberOfBytes,
112   OUT    EFI_PHYSICAL_ADDRESS                       *DeviceAddress,
113   OUT    VOID                                       **Mapping
114   )
115 {
116   EFI_STATUS                                        Status;
117   MAP_INFO                                          *MapInfo;
118   EFI_ALLOCATE_TYPE                                 AllocateType;
119   COMMON_BUFFER_HEADER                              *CommonBufferHeader;
120   VOID                                              *DecryptionSource;
121 
122   DEBUG ((
123     DEBUG_VERBOSE,
124     "%a: Operation=%a Host=0x%p Bytes=0x%Lx\n",
125     __FUNCTION__,
126     ((Operation >= 0 &&
127       Operation < ARRAY_SIZE (mBusMasterOperationName)) ?
128      mBusMasterOperationName[Operation] :
129      "Invalid"),
130     HostAddress,
131     (UINT64)((NumberOfBytes == NULL) ? 0 : *NumberOfBytes)
132     ));
133 
134   if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL ||
135       Mapping == NULL) {
136     return EFI_INVALID_PARAMETER;
137   }
138 
139   //
140   // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
141   // called later.
142   //
143   MapInfo = AllocatePool (sizeof (MAP_INFO));
144   if (MapInfo == NULL) {
145     Status = EFI_OUT_OF_RESOURCES;
146     goto Failed;
147   }
148 
149   //
150   // Initialize the MAP_INFO structure, except the PlainTextAddress field
151   //
152   ZeroMem (&MapInfo->Link, sizeof MapInfo->Link);
153   MapInfo->Signature         = MAP_INFO_SIG;
154   MapInfo->Operation         = Operation;
155   MapInfo->NumberOfBytes     = *NumberOfBytes;
156   MapInfo->NumberOfPages     = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes);
157   MapInfo->CryptedAddress    = (UINTN)HostAddress;
158 
159   //
160   // In the switch statement below, we point "MapInfo->PlainTextAddress" to the
161   // plaintext buffer, according to Operation. We also set "DecryptionSource".
162   //
163   MapInfo->PlainTextAddress = MAX_ADDRESS;
164   AllocateType = AllocateAnyPages;
165   DecryptionSource = (VOID *)(UINTN)MapInfo->CryptedAddress;
166   switch (Operation) {
167   //
168   // For BusMasterRead[64] and BusMasterWrite[64] operations, a bounce buffer
169   // is necessary regardless of whether the original (crypted) buffer crosses
170   // the 4GB limit or not -- we have to allocate a separate plaintext buffer.
171   // The only variable is whether the plaintext buffer should be under 4GB.
172   //
173   case EdkiiIoMmuOperationBusMasterRead:
174   case EdkiiIoMmuOperationBusMasterWrite:
175     MapInfo->PlainTextAddress = BASE_4GB - 1;
176     AllocateType = AllocateMaxAddress;
177     //
178     // fall through
179     //
180   case EdkiiIoMmuOperationBusMasterRead64:
181   case EdkiiIoMmuOperationBusMasterWrite64:
182     //
183     // Allocate the implicit plaintext bounce buffer.
184     //
185     Status = gBS->AllocatePages (
186                     AllocateType,
187                     EfiBootServicesData,
188                     MapInfo->NumberOfPages,
189                     &MapInfo->PlainTextAddress
190                     );
191     if (EFI_ERROR (Status)) {
192       goto FreeMapInfo;
193     }
194     break;
195 
196   //
197   // For BusMasterCommonBuffer[64] operations, a to-be-plaintext buffer and a
198   // stash buffer (for in-place decryption) have been allocated already, with
199   // AllocateBuffer(). We only check whether the address of the to-be-plaintext
200   // buffer is low enough for the requested operation.
201   //
202   case EdkiiIoMmuOperationBusMasterCommonBuffer:
203     if ((MapInfo->CryptedAddress > BASE_4GB) ||
204         (EFI_PAGES_TO_SIZE (MapInfo->NumberOfPages) >
205          BASE_4GB - MapInfo->CryptedAddress)) {
206       //
207       // CommonBuffer operations cannot be remapped. If the common buffer is
208       // above 4GB, then it is not possible to generate a mapping, so return an
209       // error.
210       //
211       Status = EFI_UNSUPPORTED;
212       goto FreeMapInfo;
213     }
214     //
215     // fall through
216     //
217   case EdkiiIoMmuOperationBusMasterCommonBuffer64:
218     //
219     // The buffer at MapInfo->CryptedAddress comes from AllocateBuffer().
220     //
221     MapInfo->PlainTextAddress = MapInfo->CryptedAddress;
222     //
223     // Stash the crypted data.
224     //
225     CommonBufferHeader = (COMMON_BUFFER_HEADER *)(
226                            (UINTN)MapInfo->CryptedAddress - EFI_PAGE_SIZE
227                            );
228     ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG);
229     CopyMem (
230       CommonBufferHeader->StashBuffer,
231       (VOID *)(UINTN)MapInfo->CryptedAddress,
232       MapInfo->NumberOfBytes
233       );
234     //
235     // Point "DecryptionSource" to the stash buffer so that we decrypt
236     // it to the original location, after the switch statement.
237     //
238     DecryptionSource = CommonBufferHeader->StashBuffer;
239     break;
240 
241   default:
242     //
243     // Operation is invalid
244     //
245     Status = EFI_INVALID_PARAMETER;
246     goto FreeMapInfo;
247   }
248 
249   //
250   // Clear the memory encryption mask on the plaintext buffer.
251   //
252   Status = MemEncryptSevClearPageEncMask (
253              0,
254              MapInfo->PlainTextAddress,
255              MapInfo->NumberOfPages,
256              TRUE
257              );
258   ASSERT_EFI_ERROR (Status);
259   if (EFI_ERROR (Status)) {
260     CpuDeadLoop ();
261   }
262 
263   //
264   // If this is a read operation from the Bus Master's point of view,
265   // then copy the contents of the real buffer into the mapped buffer
266   // so the Bus Master can read the contents of the real buffer.
267   //
268   // For BusMasterCommonBuffer[64] operations, the CopyMem() below will decrypt
269   // the original data (from the stash buffer) back to the original location.
270   //
271   if (Operation == EdkiiIoMmuOperationBusMasterRead ||
272       Operation == EdkiiIoMmuOperationBusMasterRead64 ||
273       Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||
274       Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {
275     CopyMem (
276       (VOID *) (UINTN) MapInfo->PlainTextAddress,
277       DecryptionSource,
278       MapInfo->NumberOfBytes
279       );
280   }
281 
282   //
283   // Track all MAP_INFO structures.
284   //
285   InsertHeadList (&mMapInfos, &MapInfo->Link);
286   //
287   // Populate output parameters.
288   //
289   *DeviceAddress = MapInfo->PlainTextAddress;
290   *Mapping       = MapInfo;
291 
292   DEBUG ((
293     DEBUG_VERBOSE,
294     "%a: Mapping=0x%p Device(PlainText)=0x%Lx Crypted=0x%Lx Pages=0x%Lx\n",
295     __FUNCTION__,
296     MapInfo,
297     MapInfo->PlainTextAddress,
298     MapInfo->CryptedAddress,
299     (UINT64)MapInfo->NumberOfPages
300     ));
301 
302   return EFI_SUCCESS;
303 
304 FreeMapInfo:
305   FreePool (MapInfo);
306 
307 Failed:
308   *NumberOfBytes = 0;
309   return Status;
310 }
311 
312 /**
313   Completes the Map() operation and releases any corresponding resources.
314 
315   This is an internal worker function that only extends the Map() API with
316   the MemoryMapLocked parameter.
317 
318   @param  This                  The protocol instance pointer.
319   @param  Mapping               The mapping value returned from Map().
320   @param  MemoryMapLocked       The function is executing on the stack of
321                                 gBS->ExitBootServices(); changes to the UEFI
322                                 memory map are forbidden.
323 
324   @retval EFI_SUCCESS           The range was unmapped.
325   @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by
326                                 Map().
327   @retval EFI_DEVICE_ERROR      The data was not committed to the target system
328                                 memory.
329 **/
330 STATIC
331 EFI_STATUS
332 EFIAPI
IoMmuUnmapWorker(IN EDKII_IOMMU_PROTOCOL * This,IN VOID * Mapping,IN BOOLEAN MemoryMapLocked)333 IoMmuUnmapWorker (
334   IN  EDKII_IOMMU_PROTOCOL                     *This,
335   IN  VOID                                     *Mapping,
336   IN  BOOLEAN                                  MemoryMapLocked
337   )
338 {
339   MAP_INFO                 *MapInfo;
340   EFI_STATUS               Status;
341   COMMON_BUFFER_HEADER     *CommonBufferHeader;
342   VOID                     *EncryptionTarget;
343 
344   DEBUG ((
345     DEBUG_VERBOSE,
346     "%a: Mapping=0x%p MemoryMapLocked=%d\n",
347     __FUNCTION__,
348     Mapping,
349     MemoryMapLocked
350     ));
351 
352   if (Mapping == NULL) {
353     return EFI_INVALID_PARAMETER;
354   }
355 
356   MapInfo = (MAP_INFO *)Mapping;
357 
358   //
359   // set CommonBufferHeader to suppress incorrect compiler/analyzer warnings
360   //
361   CommonBufferHeader = NULL;
362 
363   //
364   // For BusMasterWrite[64] operations and BusMasterCommonBuffer[64] operations
365   // we have to encrypt the results, ultimately to the original place (i.e.,
366   // "MapInfo->CryptedAddress").
367   //
368   // For BusMasterCommonBuffer[64] operations however, this encryption has to
369   // land in-place, so divert the encryption to the stash buffer first.
370   //
371   EncryptionTarget = (VOID *)(UINTN)MapInfo->CryptedAddress;
372 
373   switch (MapInfo->Operation) {
374   case EdkiiIoMmuOperationBusMasterCommonBuffer:
375   case EdkiiIoMmuOperationBusMasterCommonBuffer64:
376     ASSERT (MapInfo->PlainTextAddress == MapInfo->CryptedAddress);
377 
378     CommonBufferHeader = (COMMON_BUFFER_HEADER *)(
379                            (UINTN)MapInfo->PlainTextAddress - EFI_PAGE_SIZE
380                            );
381     ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG);
382     EncryptionTarget = CommonBufferHeader->StashBuffer;
383     //
384     // fall through
385     //
386 
387   case EdkiiIoMmuOperationBusMasterWrite:
388   case EdkiiIoMmuOperationBusMasterWrite64:
389     CopyMem (
390       EncryptionTarget,
391       (VOID *) (UINTN) MapInfo->PlainTextAddress,
392       MapInfo->NumberOfBytes
393       );
394     break;
395 
396   default:
397     //
398     // nothing to encrypt after BusMasterRead[64] operations
399     //
400     break;
401   }
402 
403   //
404   // Restore the memory encryption mask on the area we used to hold the
405   // plaintext.
406   //
407   Status = MemEncryptSevSetPageEncMask (
408              0,
409              MapInfo->PlainTextAddress,
410              MapInfo->NumberOfPages,
411              TRUE
412              );
413   ASSERT_EFI_ERROR (Status);
414   if (EFI_ERROR (Status)) {
415     CpuDeadLoop ();
416   }
417 
418   //
419   // For BusMasterCommonBuffer[64] operations, copy the stashed data to the
420   // original (now encrypted) location.
421   //
422   // For all other operations, fill the late bounce buffer (which existed as
423   // plaintext at some point) with zeros, and then release it (unless the UEFI
424   // memory map is locked).
425   //
426   if (MapInfo->Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||
427       MapInfo->Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {
428     CopyMem (
429       (VOID *)(UINTN)MapInfo->CryptedAddress,
430       CommonBufferHeader->StashBuffer,
431       MapInfo->NumberOfBytes
432       );
433   } else {
434     ZeroMem (
435       (VOID *)(UINTN)MapInfo->PlainTextAddress,
436       EFI_PAGES_TO_SIZE (MapInfo->NumberOfPages)
437       );
438     if (!MemoryMapLocked) {
439       gBS->FreePages (MapInfo->PlainTextAddress, MapInfo->NumberOfPages);
440     }
441   }
442 
443   //
444   // Forget the MAP_INFO structure, then free it (unless the UEFI memory map is
445   // locked).
446   //
447   RemoveEntryList (&MapInfo->Link);
448   if (!MemoryMapLocked) {
449     FreePool (MapInfo);
450   }
451 
452   return EFI_SUCCESS;
453 }
454 
455 /**
456   Completes the Map() operation and releases any corresponding resources.
457 
458   @param  This                  The protocol instance pointer.
459   @param  Mapping               The mapping value returned from Map().
460 
461   @retval EFI_SUCCESS           The range was unmapped.
462   @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by
463                                 Map().
464   @retval EFI_DEVICE_ERROR      The data was not committed to the target system
465                                 memory.
466 **/
467 EFI_STATUS
468 EFIAPI
IoMmuUnmap(IN EDKII_IOMMU_PROTOCOL * This,IN VOID * Mapping)469 IoMmuUnmap (
470   IN  EDKII_IOMMU_PROTOCOL                     *This,
471   IN  VOID                                     *Mapping
472   )
473 {
474   return IoMmuUnmapWorker (
475            This,
476            Mapping,
477            FALSE    // MemoryMapLocked
478            );
479 }
480 
481 /**
482   Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
483   OperationBusMasterCommonBuffer64 mapping.
484 
485   @param  This                  The protocol instance pointer.
486   @param  Type                  This parameter is not used and must be ignored.
487   @param  MemoryType            The type of memory to allocate,
488                                 EfiBootServicesData or EfiRuntimeServicesData.
489   @param  Pages                 The number of pages to allocate.
490   @param  HostAddress           A pointer to store the base system memory
491                                 address of the allocated range.
492   @param  Attributes            The requested bit mask of attributes for the
493                                 allocated range.
494 
495   @retval EFI_SUCCESS           The requested memory pages were allocated.
496   @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal
497                                 attribute bits are MEMORY_WRITE_COMBINE and
498                                 MEMORY_CACHED.
499   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
500   @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.
501 
502 **/
503 EFI_STATUS
504 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)505 IoMmuAllocateBuffer (
506   IN     EDKII_IOMMU_PROTOCOL                     *This,
507   IN     EFI_ALLOCATE_TYPE                        Type,
508   IN     EFI_MEMORY_TYPE                          MemoryType,
509   IN     UINTN                                    Pages,
510   IN OUT VOID                                     **HostAddress,
511   IN     UINT64                                   Attributes
512   )
513 {
514   EFI_STATUS                Status;
515   EFI_PHYSICAL_ADDRESS      PhysicalAddress;
516   VOID                      *StashBuffer;
517   UINTN                     CommonBufferPages;
518   COMMON_BUFFER_HEADER      *CommonBufferHeader;
519 
520   DEBUG ((
521     DEBUG_VERBOSE,
522     "%a: MemoryType=%u Pages=0x%Lx Attributes=0x%Lx\n",
523     __FUNCTION__,
524     (UINT32)MemoryType,
525     (UINT64)Pages,
526     Attributes
527     ));
528 
529   //
530   // Validate Attributes
531   //
532   if ((Attributes & EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
533     return EFI_UNSUPPORTED;
534   }
535 
536   //
537   // Check for invalid inputs
538   //
539   if (HostAddress == NULL) {
540     return EFI_INVALID_PARAMETER;
541   }
542 
543   //
544   // The only valid memory types are EfiBootServicesData and
545   // EfiRuntimeServicesData
546   //
547   if (MemoryType != EfiBootServicesData &&
548       MemoryType != EfiRuntimeServicesData) {
549     return EFI_INVALID_PARAMETER;
550   }
551 
552   //
553   // We'll need a header page for the COMMON_BUFFER_HEADER structure.
554   //
555   if (Pages > MAX_UINTN - 1) {
556     return EFI_OUT_OF_RESOURCES;
557   }
558   CommonBufferPages = Pages + 1;
559 
560   //
561   // Allocate the stash in EfiBootServicesData type memory.
562   //
563   // Map() will temporarily save encrypted data in the stash for
564   // BusMasterCommonBuffer[64] operations, so the data can be decrypted to the
565   // original location.
566   //
567   // Unmap() will temporarily save plaintext data in the stash for
568   // BusMasterCommonBuffer[64] operations, so the data can be encrypted to the
569   // original location.
570   //
571   // StashBuffer always resides in encrypted memory.
572   //
573   StashBuffer = AllocatePages (Pages);
574   if (StashBuffer == NULL) {
575     return EFI_OUT_OF_RESOURCES;
576   }
577 
578   PhysicalAddress = (UINTN)-1;
579   if ((Attributes & EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
580     //
581     // Limit allocations to memory below 4GB
582     //
583     PhysicalAddress = SIZE_4GB - 1;
584   }
585   Status = gBS->AllocatePages (
586                   AllocateMaxAddress,
587                   MemoryType,
588                   CommonBufferPages,
589                   &PhysicalAddress
590                   );
591   if (EFI_ERROR (Status)) {
592     goto FreeStashBuffer;
593   }
594 
595   CommonBufferHeader = (VOID *)(UINTN)PhysicalAddress;
596   PhysicalAddress += EFI_PAGE_SIZE;
597 
598   CommonBufferHeader->Signature = COMMON_BUFFER_SIG;
599   CommonBufferHeader->StashBuffer = StashBuffer;
600 
601   *HostAddress = (VOID *)(UINTN)PhysicalAddress;
602 
603   DEBUG ((
604     DEBUG_VERBOSE,
605     "%a: Host=0x%Lx Stash=0x%p\n",
606     __FUNCTION__,
607     PhysicalAddress,
608     StashBuffer
609     ));
610   return EFI_SUCCESS;
611 
612 FreeStashBuffer:
613   FreePages (StashBuffer, Pages);
614   return Status;
615 }
616 
617 /**
618   Frees memory that was allocated with AllocateBuffer().
619 
620   @param  This                  The protocol instance pointer.
621   @param  Pages                 The number of pages to free.
622   @param  HostAddress           The base system memory address of the allocated
623                                 range.
624 
625   @retval EFI_SUCCESS           The requested memory pages were freed.
626   @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and
627                                 Pages was not allocated with AllocateBuffer().
628 
629 **/
630 EFI_STATUS
631 EFIAPI
IoMmuFreeBuffer(IN EDKII_IOMMU_PROTOCOL * This,IN UINTN Pages,IN VOID * HostAddress)632 IoMmuFreeBuffer (
633   IN  EDKII_IOMMU_PROTOCOL                     *This,
634   IN  UINTN                                    Pages,
635   IN  VOID                                     *HostAddress
636   )
637 {
638   UINTN                CommonBufferPages;
639   COMMON_BUFFER_HEADER *CommonBufferHeader;
640 
641   DEBUG ((
642     DEBUG_VERBOSE,
643     "%a: Host=0x%p Pages=0x%Lx\n",
644     __FUNCTION__,
645     HostAddress,
646     (UINT64)Pages
647     ));
648 
649   CommonBufferPages = Pages + 1;
650   CommonBufferHeader = (COMMON_BUFFER_HEADER *)(
651                          (UINTN)HostAddress - EFI_PAGE_SIZE
652                          );
653 
654   //
655   // Check the signature.
656   //
657   ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG);
658   if (CommonBufferHeader->Signature != COMMON_BUFFER_SIG) {
659     return EFI_INVALID_PARAMETER;
660   }
661 
662   //
663   // Free the stash buffer. This buffer was always encrypted, so no need to
664   // zero it.
665   //
666   FreePages (CommonBufferHeader->StashBuffer, Pages);
667 
668   //
669   // Release the common buffer itself. Unmap() has re-encrypted it in-place, so
670   // no need to zero it.
671   //
672   return gBS->FreePages ((UINTN)CommonBufferHeader, CommonBufferPages);
673 }
674 
675 
676 /**
677   Set IOMMU attribute for a system memory.
678 
679   If the IOMMU protocol exists, the system memory cannot be used
680   for DMA by default.
681 
682   When a device requests a DMA access for a system memory,
683   the device driver need use SetAttribute() to update the IOMMU
684   attribute to request DMA access (read and/or write).
685 
686   The DeviceHandle is used to identify which device submits the request.
687   The IOMMU implementation need translate the device path to an IOMMU device
688   ID, and set IOMMU hardware register accordingly.
689   1) DeviceHandle can be a standard PCI device.
690      The memory for BusMasterRead need set EDKII_IOMMU_ACCESS_READ.
691      The memory for BusMasterWrite need set EDKII_IOMMU_ACCESS_WRITE.
692      The memory for BusMasterCommonBuffer need set
693      EDKII_IOMMU_ACCESS_READ|EDKII_IOMMU_ACCESS_WRITE.
694      After the memory is used, the memory need set 0 to keep it being
695      protected.
696   2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
697      The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or
698      EDKII_IOMMU_ACCESS_WRITE.
699 
700   @param[in]  This              The protocol instance pointer.
701   @param[in]  DeviceHandle      The device who initiates the DMA access
702                                 request.
703   @param[in]  Mapping           The mapping value returned from Map().
704   @param[in]  IoMmuAccess       The IOMMU access.
705 
706   @retval EFI_SUCCESS            The IoMmuAccess is set for the memory range
707                                  specified by DeviceAddress and Length.
708   @retval EFI_INVALID_PARAMETER  DeviceHandle is an invalid handle.
709   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by
710                                  Map().
711   @retval EFI_INVALID_PARAMETER  IoMmuAccess specified an illegal combination
712                                  of access.
713   @retval EFI_UNSUPPORTED        DeviceHandle is unknown by the IOMMU.
714   @retval EFI_UNSUPPORTED        The bit mask of IoMmuAccess is not supported
715                                  by the IOMMU.
716   @retval EFI_UNSUPPORTED        The IOMMU does not support the memory range
717                                  specified by Mapping.
718   @retval EFI_OUT_OF_RESOURCES   There are not enough resources available to
719                                  modify the IOMMU access.
720   @retval EFI_DEVICE_ERROR       The IOMMU device reported an error while
721                                  attempting the operation.
722 
723 **/
724 EFI_STATUS
725 EFIAPI
IoMmuSetAttribute(IN EDKII_IOMMU_PROTOCOL * This,IN EFI_HANDLE DeviceHandle,IN VOID * Mapping,IN UINT64 IoMmuAccess)726 IoMmuSetAttribute (
727   IN EDKII_IOMMU_PROTOCOL  *This,
728   IN EFI_HANDLE            DeviceHandle,
729   IN VOID                  *Mapping,
730   IN UINT64                IoMmuAccess
731   )
732 {
733   return EFI_UNSUPPORTED;
734 }
735 
736 EDKII_IOMMU_PROTOCOL  mAmdSev = {
737   EDKII_IOMMU_PROTOCOL_REVISION,
738   IoMmuSetAttribute,
739   IoMmuMap,
740   IoMmuUnmap,
741   IoMmuAllocateBuffer,
742   IoMmuFreeBuffer,
743 };
744 
745 /**
746   Notification function that is queued when gBS->ExitBootServices() signals the
747   EFI_EVENT_GROUP_EXIT_BOOT_SERVICES event group. This function signals another
748   event, received as Context, and returns.
749 
750   Signaling an event in this context is safe. The UEFI spec allows
751   gBS->SignalEvent() to return EFI_SUCCESS only; EFI_OUT_OF_RESOURCES is not
752   listed, hence memory is not allocated. The edk2 implementation also does not
753   release memory (and we only have to care about the edk2 implementation
754   because EDKII_IOMMU_PROTOCOL is edk2-specific anyway).
755 
756   @param[in] Event          Event whose notification function is being invoked.
757                             Event is permitted to request the queueing of this
758                             function at TPL_CALLBACK or TPL_NOTIFY task
759                             priority level.
760 
761   @param[in] EventToSignal  Identifies the EFI_EVENT to signal. EventToSignal
762                             is permitted to request the queueing of its
763                             notification function only at TPL_CALLBACK level.
764 **/
765 STATIC
766 VOID
767 EFIAPI
AmdSevExitBoot(IN EFI_EVENT Event,IN VOID * EventToSignal)768 AmdSevExitBoot (
769   IN EFI_EVENT Event,
770   IN VOID      *EventToSignal
771   )
772 {
773   //
774   // (1) The NotifyFunctions of all the events in
775   //     EFI_EVENT_GROUP_EXIT_BOOT_SERVICES will have been queued before
776   //     AmdSevExitBoot() is entered.
777   //
778   // (2) AmdSevExitBoot() is executing minimally at TPL_CALLBACK.
779   //
780   // (3) AmdSevExitBoot() has been queued in unspecified order relative to the
781   //     NotifyFunctions of all the other events in
782   //     EFI_EVENT_GROUP_EXIT_BOOT_SERVICES whose NotifyTpl is the same as
783   //     Event's.
784   //
785   // Consequences:
786   //
787   // - If Event's NotifyTpl is TPL_CALLBACK, then some other NotifyFunctions
788   //   queued at TPL_CALLBACK may be invoked after AmdSevExitBoot() returns.
789   //
790   // - If Event's NotifyTpl is TPL_NOTIFY, then some other NotifyFunctions
791   //   queued at TPL_NOTIFY may be invoked after AmdSevExitBoot() returns; plus
792   //   *all* NotifyFunctions queued at TPL_CALLBACK will be invoked strictly
793   //   after all NotifyFunctions queued at TPL_NOTIFY, including
794   //   AmdSevExitBoot(), have been invoked.
795   //
796   // - By signaling EventToSignal here, whose NotifyTpl is TPL_CALLBACK, we
797   //   queue EventToSignal's NotifyFunction after the NotifyFunctions of *all*
798   //   events in EFI_EVENT_GROUP_EXIT_BOOT_SERVICES.
799   //
800   DEBUG ((DEBUG_VERBOSE, "%a\n", __FUNCTION__));
801   gBS->SignalEvent (EventToSignal);
802 }
803 
804 /**
805   Notification function that is queued after the notification functions of all
806   events in the EFI_EVENT_GROUP_EXIT_BOOT_SERVICES event group. The same memory
807   map restrictions apply.
808 
809   This function unmaps all currently existing IOMMU mappings.
810 
811   @param[in] Event    Event whose notification function is being invoked. Event
812                       is permitted to request the queueing of this function
813                       only at TPL_CALLBACK task priority level.
814 
815   @param[in] Context  Ignored.
816 **/
817 STATIC
818 VOID
819 EFIAPI
AmdSevUnmapAllMappings(IN EFI_EVENT Event,IN VOID * Context)820 AmdSevUnmapAllMappings (
821   IN EFI_EVENT Event,
822   IN VOID      *Context
823   )
824 {
825   LIST_ENTRY *Node;
826   LIST_ENTRY *NextNode;
827   MAP_INFO   *MapInfo;
828 
829   DEBUG ((DEBUG_VERBOSE, "%a\n", __FUNCTION__));
830 
831   //
832   // All drivers that had set up IOMMU mappings have halted their respective
833   // controllers by now; tear down the mappings.
834   //
835   for (Node = GetFirstNode (&mMapInfos); Node != &mMapInfos; Node = NextNode) {
836     NextNode = GetNextNode (&mMapInfos, Node);
837     MapInfo = CR (Node, MAP_INFO, Link, MAP_INFO_SIG);
838     IoMmuUnmapWorker (
839       &mAmdSev, // This
840       MapInfo,  // Mapping
841       TRUE      // MemoryMapLocked
842       );
843   }
844 }
845 
846 /**
847   Initialize Iommu Protocol.
848 
849 **/
850 EFI_STATUS
851 EFIAPI
AmdSevInstallIoMmuProtocol(VOID)852 AmdSevInstallIoMmuProtocol (
853   VOID
854   )
855 {
856   EFI_STATUS  Status;
857   EFI_EVENT   UnmapAllMappingsEvent;
858   EFI_EVENT   ExitBootEvent;
859   EFI_HANDLE  Handle;
860 
861   //
862   // Create the "late" event whose notification function will tear down all
863   // left-over IOMMU mappings.
864   //
865   Status = gBS->CreateEvent (
866                   EVT_NOTIFY_SIGNAL,      // Type
867                   TPL_CALLBACK,           // NotifyTpl
868                   AmdSevUnmapAllMappings, // NotifyFunction
869                   NULL,                   // NotifyContext
870                   &UnmapAllMappingsEvent  // Event
871                   );
872   if (EFI_ERROR (Status)) {
873     return Status;
874   }
875 
876   //
877   // Create the event whose notification function will be queued by
878   // gBS->ExitBootServices() and will signal the event created above.
879   //
880   Status = gBS->CreateEvent (
881                   EVT_SIGNAL_EXIT_BOOT_SERVICES, // Type
882                   TPL_CALLBACK,                  // NotifyTpl
883                   AmdSevExitBoot,                // NotifyFunction
884                   UnmapAllMappingsEvent,         // NotifyContext
885                   &ExitBootEvent                 // Event
886                   );
887   if (EFI_ERROR (Status)) {
888     goto CloseUnmapAllMappingsEvent;
889   }
890 
891   Handle = NULL;
892   Status = gBS->InstallMultipleProtocolInterfaces (
893                   &Handle,
894                   &gEdkiiIoMmuProtocolGuid, &mAmdSev,
895                   NULL
896                   );
897   if (EFI_ERROR (Status)) {
898     goto CloseExitBootEvent;
899   }
900 
901   return EFI_SUCCESS;
902 
903 CloseExitBootEvent:
904   gBS->CloseEvent (ExitBootEvent);
905 
906 CloseUnmapAllMappingsEvent:
907   gBS->CloseEvent (UnmapAllMappingsEvent);
908 
909   return Status;
910 }
911