From: Brijesh Singh <brijesh.singh@amd.com>
To: edk2-devel@lists.01.org
Cc: Tom Lendacky <thomas.lendacky@amd.com>,
Brijesh Singh <brijesh.singh@amd.com>,
Jordan Justen <jordan.l.justen@intel.com>,
Laszlo Ersek <lersek@redhat.com>,
Jason Wang <jasowang@redhat.com>,
"Michael S . Tsirkin" <mst@redhat.com>
Subject: [RFC v1 3/3] OvmfPkg/VirtioBlkDxe: Add VIRITO_F_IOMMU_PLATFORM support
Date: Wed, 19 Jul 2017 18:09:11 -0400 [thread overview]
Message-ID: <1500502151-13508-4-git-send-email-brijesh.singh@amd.com> (raw)
In-Reply-To: <1500502151-13508-1-git-send-email-brijesh.singh@amd.com>
When VIRTIO_F_IOMMU_PLATFORM feature bit in set then try locating
IOMMU protocol. If IOMMU protocol is available, then use the IOMMU
protocols functions to allocate, free, map and unmap the host buffer
to device 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/VirtioBlkDxe/VirtioBlk.inf | 4 +
OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 125 ++++++++++++++++++--
2 files changed, 118 insertions(+), 11 deletions(-)
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf b/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
index 53d5a164a0b8..12577c5f700f 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
@@ -41,3 +41,7 @@ [LibraryClasses]
[Protocols]
gEfiBlockIoProtocolGuid ## BY_START
gVirtioDeviceProtocolGuid ## TO_START
+ gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
+
+[Depex]
+ gEdkiiIoMmuProtocolGuid OR gIoMmuAbsentProtocolGuid
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index 3ce72281c204..f78052c4ecc0 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -23,6 +23,8 @@
**/
+#include <Protocol/IoMmu.h>
+
#include <IndustryStandard/VirtioBlk.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
@@ -33,6 +35,8 @@
#include "VirtioBlk.h"
+STATIC EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;
+
/**
Convenience macros to read and write region 0 IO space elements of the
@@ -247,13 +251,49 @@ SynchronousRequest (
)
{
UINT32 BlockSize;
- volatile VIRTIO_BLK_REQ Request;
- volatile UINT8 HostStatus;
+ volatile VIRTIO_BLK_REQ LocalRequest;
+ volatile UINT8 LocalHostStatus;
+ volatile VIRTIO_BLK_REQ *Request;
+ volatile UINT8 *HostStatus;
DESC_INDICES Indices;
+ VOID *IommuBuffer;
+ UINT32 NumPages;
+ VOID *Mapping;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS DeviceBuffer;
BlockSize = Dev->BlockIoMedia.BlockSize;
//
+ // set NumPages to suppress incorrect compiler/analyzer warnings
+ //
+ NumPages = 0;
+
+ //
+ // If IOMMU platform is enabled for this device then allocate Request and
+ // HostStatus variable dynamically using IOMMU allocator
+ //
+ if (mIoMmuProtocol) {
+ EFI_STATUS Status;
+
+ NumPages = (UINT32)EFI_SIZE_TO_PAGES (sizeof (*Request) + sizeof (*HostStatus));
+ Status = mIoMmuProtocol->AllocateBuffer (mIoMmuProtocol, 0,
+ EfiBootServicesData, NumPages, &IommuBuffer,
+ EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Request = IommuBuffer;
+ HostStatus = IommuBuffer + sizeof(*Request);
+ } else {
+ Request = &LocalRequest;
+ HostStatus = &LocalHostStatus;
+ IommuBuffer = NULL;
+ Mapping = NULL;
+ }
+
+ //
// ensured by VirtioBlkInit()
//
ASSERT (BlockSize > 0);
@@ -268,18 +308,18 @@ SynchronousRequest (
// Prepare virtio-blk request header, setting zero size for flush.
// IO Priority is homogeneously 0.
//
- Request.Type = RequestIsWrite ?
+ Request->Type = RequestIsWrite ?
(BufferSize == 0 ? VIRTIO_BLK_T_FLUSH : VIRTIO_BLK_T_OUT) :
VIRTIO_BLK_T_IN;
- Request.IoPrio = 0;
- Request.Sector = MultU64x32(Lba, BlockSize / 512);
+ Request->IoPrio = 0;
+ Request->Sector = MultU64x32(Lba, BlockSize / 512);
VirtioPrepare (&Dev->Ring, &Indices);
//
// preset a host status for ourselves that we do not accept as success
//
- HostStatus = VIRTIO_BLK_S_IOERR;
+ *HostStatus = VIRTIO_BLK_S_IOERR;
//
// ensured by VirtioBlkInit() -- this predicate, in combination with the
@@ -290,7 +330,7 @@ SynchronousRequest (
//
// virtio-blk header in first desc
//
- VirtioAppendDesc (&Dev->Ring, (UINTN) &Request, sizeof Request,
+ VirtioAppendDesc (&Dev->Ring, (UINTN) Request, sizeof *Request,
VRING_DESC_F_NEXT, &Indices);
//
@@ -308,6 +348,42 @@ SynchronousRequest (
ASSERT (BufferSize <= SIZE_1GB);
//
+ // When IOMMU platform is enabled, map the host buffer to device
+ //
+ if (mIoMmuProtocol) {
+ EDKII_IOMMU_OPERATION Operation;
+ UINTN NumBytes;
+
+ NumBytes = BufferSize;
+
+ if (RequestIsWrite) {
+ Operation = EdkiiIoMmuOperationBusMasterRead;
+ } else {
+ Operation = EdkiiIoMmuOperationBusMasterWrite;
+ }
+
+ Status = mIoMmuProtocol->Map (mIoMmuProtocol, Operation, (VOID *)Buffer,
+ &NumBytes, &DeviceBuffer, &Mapping);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto HandleExit;
+ }
+
+ //
+ // Verify that we are able to map the required size
+ //
+ if (NumBytes < BufferSize) {
+ DEBUG ((DEBUG_ERROR, "%a: request %d got %d\n", __FUNCTION__,
+ BufferSize, NumBytes));
+
+ Status = EFI_DEVICE_ERROR;
+ mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping);
+ goto HandleExit;
+ }
+ Buffer = (VOID *)DeviceBuffer;
+ }
+
+ //
// VRING_DESC_F_WRITE is interpreted from the host's point of view.
//
VirtioAppendDesc (&Dev->Ring, (UINTN) Buffer, (UINT32) BufferSize,
@@ -318,7 +394,7 @@ SynchronousRequest (
//
// host status in last (second or third) desc
//
- VirtioAppendDesc (&Dev->Ring, (UINTN) &HostStatus, sizeof HostStatus,
+ VirtioAppendDesc (&Dev->Ring, (UINTN) HostStatus, sizeof *HostStatus,
VRING_DESC_F_WRITE, &Indices);
//
@@ -326,11 +402,23 @@ SynchronousRequest (
//
if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices,
NULL) == EFI_SUCCESS &&
- HostStatus == VIRTIO_BLK_S_OK) {
- return EFI_SUCCESS;
+ *HostStatus == VIRTIO_BLK_S_OK) {
+ Status = EFI_SUCCESS;
+ goto HandleExit;
}
- return EFI_DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR;
+
+HandleExit:
+ if (Mapping) {
+ mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping);
+ }
+
+ if (IommuBuffer) {
+ mIoMmuProtocol->FreeBuffer (mIoMmuProtocol, NumPages, IommuBuffer);
+ }
+
+ return Status;
}
@@ -692,6 +780,21 @@ VirtioBlkInit (
}
}
+ //
+ // If IOMMU_PLATFORM feature is requested then try to locate IOMMU
+ // protocol before acking that we support IOMMU_PLATFORM feature
+ //
+ if (Features & VIRTIO_F_IOMMU_PLATFORM) {
+ Status = gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmuProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to locate IOMMU protocol\n", __FUNCTION__));
+ goto Failed;
+ }
+
+ Features &= VIRTIO_F_IOMMU_PLATFORM;
+ VirtioRingUseIommu (&Dev->Ring, mIoMmuProtocol);
+ }
+
Features &= VIRTIO_BLK_F_BLK_SIZE | VIRTIO_BLK_F_TOPOLOGY | VIRTIO_BLK_F_RO |
VIRTIO_BLK_F_FLUSH | VIRTIO_F_VERSION_1;
--
2.7.4
next prev parent reply other threads:[~2017-07-19 22:07 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-19 22:09 [RFC v1 0/3] Add VIRTIO_F_IOMMU_PLATFORM support Brijesh Singh
2017-07-19 22:09 ` [RFC v1 1/3] OvmfPkg/Include/Virtio10: Define VIRTIO_F_IOMMU_PLATFORM feature bit Brijesh Singh
2017-07-19 22:09 ` [RFC v1 2/3] OvmfPkg/VirtioLib: Add IOMMU_PLATFORM support Brijesh Singh
2017-07-19 22:09 ` Brijesh Singh [this message]
[not found] ` <62320c1a-0cec-947c-8c63-5eb0416e4e33@redhat.com>
2017-07-21 11:17 ` [RFC v1 0/3] Add VIRTIO_F_IOMMU_PLATFORM support Brijesh Singh
[not found] ` <20170722024318-mutt-send-email-mst@kernel.org>
2017-07-24 8:25 ` Gerd Hoffmann
2017-07-25 18:17 ` Laszlo Ersek
2017-07-25 23:42 ` Brijesh Singh
[not found] ` <904dae9f-e515-01ba-e16f-6561616c78af@redhat.com>
2017-07-26 15:30 ` Laszlo Ersek
2017-07-27 14:21 ` Brijesh Singh
2017-07-27 17:16 ` Laszlo Ersek
2017-07-27 17:56 ` Ard Biesheuvel
2017-07-27 19:00 ` Brijesh Singh
2017-07-27 20:55 ` Brijesh Singh
2017-07-27 21:31 ` Ard Biesheuvel
2017-07-27 21:38 ` Andrew Fish
2017-07-27 22:13 ` Brijesh Singh
2017-07-27 22:10 ` Brijesh Singh
2017-07-28 8:39 ` Ard Biesheuvel
2017-07-28 15:27 ` Laszlo Ersek
2017-07-28 13:38 ` Laszlo Ersek
2017-07-28 16:00 ` Brijesh Singh
2017-07-28 16:16 ` Laszlo Ersek
2017-07-28 19:21 ` Laszlo Ersek
2017-07-28 19:59 ` Laszlo Ersek
2017-07-29 0:52 ` Brijesh Singh
2017-07-29 1:37 ` Brijesh Singh
2017-07-31 18:20 ` Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1500502151-13508-4-git-send-email-brijesh.singh@amd.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox