When iommu_platform is set, use IOMMU protocols buffer allocation
and free routines to allocate and free vring buffer (guest-host
communication buffer).
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
OvmfPkg/Library/VirtioLib/VirtioLib.inf | 1 +
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf | 1 +
OvmfPkg/VirtioGpuDxe/VirtioGpu.inf | 1 +
OvmfPkg/VirtioNetDxe/VirtioNet.inf | 1 +
OvmfPkg/VirtioRngDxe/VirtioRng.inf | 1 +
OvmfPkg/VirtioScsiDxe/VirtioScsi.inf | 1 +
OvmfPkg/Include/IndustryStandard/Virtio095.h | 1 +
OvmfPkg/Include/Library/VirtioLib.h | 20 ++++
OvmfPkg/Library/VirtioLib/VirtioLib.c | 96 +++++++++++++++++++-
9 files changed, 121 insertions(+), 2 deletions(-)
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.inf b/OvmfPkg/Library/VirtioLib/VirtioLib.inf
index fb5897a88ecf..6629d0d52b04 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.inf
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.inf
@@ -26,6 +26,7 @@ [Sources]
[Packages]
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf b/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
index d5975b74eb05..53d5a164a0b8 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
@@ -26,6 +26,7 @@ [Sources]
[Packages]
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
diff --git a/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf b/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
index 04bc2964c223..a6d4cbbd191a 100644
--- a/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
+++ b/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
@@ -31,6 +31,7 @@ [Sources]
[Packages]
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.inf b/OvmfPkg/VirtioNetDxe/VirtioNet.inf
index a855ad4ac154..2b8996ed366e 100644
--- a/OvmfPkg/VirtioNetDxe/VirtioNet.inf
+++ b/OvmfPkg/VirtioNetDxe/VirtioNet.inf
@@ -42,6 +42,7 @@ [Sources]
[Packages]
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.inf b/OvmfPkg/VirtioRngDxe/VirtioRng.inf
index 471beb37bc7f..898bfb7158c2 100644
--- a/OvmfPkg/VirtioRngDxe/VirtioRng.inf
+++ b/OvmfPkg/VirtioRngDxe/VirtioRng.inf
@@ -26,6 +26,7 @@ [Sources]
[Packages]
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf b/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
index 75581123930b..082f9a12bb09 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
@@ -27,6 +27,7 @@ [Sources]
[Packages]
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
diff --git a/OvmfPkg/Include/IndustryStandard/Virtio095.h b/OvmfPkg/Include/IndustryStandard/Virtio095.h
index 6bf77cb32075..c81b29c6d9d0 100644
--- a/OvmfPkg/Include/IndustryStandard/Virtio095.h
+++ b/OvmfPkg/Include/IndustryStandard/Virtio095.h
@@ -154,6 +154,7 @@ typedef struct {
VRING_AVAIL Avail;
VRING_USED Used;
UINT16 QueueSize;
+ VOID *Iommu;
} VRING;
//
diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
index 5badfb32917f..92a3d5e10f7b 100644
--- a/OvmfPkg/Include/Library/VirtioLib.h
+++ b/OvmfPkg/Include/Library/VirtioLib.h
@@ -17,10 +17,30 @@
#ifndef _VIRTIO_LIB_H_
#define _VIRTIO_LIB_H_
+#include <Protocol/IoMmu.h>
#include <Protocol/VirtioDevice.h>
#include <IndustryStandard/Virtio.h>
+/**
+
+ Configure a virtio ring to use IOMMU protocol
+
+ This function tells vring to use the given IOMMU protocol interface
+ for allocating and freeing the vring buffer (this guest-host communication
+ area)
+
+ @param[in] The virtio ring to set up.
+
+ @param[in] IOMMU protocol to use.
+
+**/
+VOID
+EFIAPI
+VirtioRingUseIommu (
+ IN VRING *Ring,
+ IN EDKII_IOMMU_PROTOCOL *Iommu
+ );
/**
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
index 845f206369a3..d8fdb6310d52 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
@@ -26,6 +26,69 @@
/**
+ Configure a virtio ring to use IOMMU protocol
+
+ This function tells vring to use the given IOMMU protocol interface
+ for allocating and freeing the vring buffer (this guest-host communication
+ area)
+
+ @param[in] The virtio ring to set up.
+
+ @param[in] IOMMU protocol to use.
+
+**/
+VOID
+EFIAPI
+VirtioRingUseIommu (
+ IN VRING *Ring,
+ IN EDKII_IOMMU_PROTOCOL *Iommu
+ )
+{
+ Ring->Iommu = Iommu;
+}
+
+/**
+
+ Allocate vring (the guest-host communication area)
+
+ This function checks if host has requested the Iommu support then it uses
+ the IOMMU protocol allocator for allocating vring otherwise uses AllocatePages
+
+**/
+STATIC
+VOID *
+VirtioRingAllocatePages (
+ IN VRING *Ring
+ )
+{
+ UINT32 NumPages;
+ EDKII_IOMMU_PROTOCOL *Iommu;
+
+ NumPages = Ring->NumPages;
+ Iommu = (EDKII_IOMMU_PROTOCOL *)Ring->Iommu;
+
+ //
+ // If IOMMU protocol is set then use IOMMU allocator otherwise
+ // fallback to standard allocator
+ //
+ if (Iommu) {
+ EFI_STATUS Status;
+ VOID *Buffer;
+
+ Status = Iommu->AllocateBuffer (Iommu, 0, EfiBootServicesData,
+ NumPages, &Buffer, EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ return Buffer;
+ }
+
+ return AllocatePages (NumPages);
+}
+
+/**
+
Configure a virtio ring.
This function sets up internal storage (the guest-host communication area)
@@ -76,7 +139,7 @@ VirtioRingInit (
EFI_PAGE_SIZE);
Ring->NumPages = EFI_SIZE_TO_PAGES (RingSize);
- Ring->Base = AllocatePages (Ring->NumPages);
+ Ring->Base = VirtioRingAllocatePages (Ring);
if (Ring->Base == NULL) {
return EFI_OUT_OF_RESOURCES;
}
@@ -118,6 +181,35 @@ VirtioRingInit (
return EFI_SUCCESS;
}
+/**
+
+ Free vring (the guest-host communication area)
+
+ This function checks if host has requested the Iommu support then it uses
+ the IOMMU protocol free callback otherwise uses FreePages
+
+**/
+STATIC
+VOID
+VirtioRingFreePages (
+ IN VRING *Ring
+ )
+{
+ EDKII_IOMMU_PROTOCOL *Iommu;
+
+ Iommu = (EDKII_IOMMU_PROTOCOL *)Ring->Iommu;
+
+ //
+ // If IOMMU protocol is set then use IOMMU FreeBuffer otherwise
+ // fallback to FreePages
+ //
+ if (Iommu) {
+ Iommu->FreeBuffer (Iommu, Ring->NumPages, Ring->Base);
+ } else {
+ FreePages (Ring->Base, Ring->NumPages);
+ }
+}
+
/**
@@ -136,7 +228,7 @@ VirtioRingUninit (
IN OUT VRING *Ring
)
{
- FreePages (Ring->Base, Ring->NumPages);
+ VirtioRingFreePages (Ring);
SetMem (Ring, sizeof *Ring, 0x00);
}
--
2.7.4
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2024 Red Hat, Inc.