diff options
author | Laszlo Ersek <lersek@redhat.com> | 2017-08-26 16:00:30 +0200 |
---|---|---|
committer | Laszlo Ersek <lersek@redhat.com> | 2017-09-01 14:27:28 +0200 |
commit | 9bc5026c19a5b698d49c5228c70a32ea4675591a (patch) | |
tree | ff26b5f3ea2f406f810d9a0a9e3ba5c408501528 | |
parent | 1afbb85f8736b63bc32f5827c3cb7b2e583114eb (diff) | |
download | edk2-9bc5026c19a5b698d49c5228c70a32ea4675591a.tar.gz edk2-9bc5026c19a5b698d49c5228c70a32ea4675591a.tar.bz2 edk2-9bc5026c19a5b698d49c5228c70a32ea4675591a.zip |
OvmfPkg/VirtioGpuDxe: map VRING for bus master common buffer operation
VirtioGpuDxe uses one virtio ring, for VIRTIO_GPU_CONTROL_QUEUE.
Map it for bus master common buffer operation with VirtioRingMap(), so
that it can be accessed equally by both guest and hypervisor even if an
IOMMU is used. (VirtioRingInit() already allocates the ring suitably for
this, see commit b0338c53297c, "OvmfPkg/VirtioLib: alloc VRING buffer with
AllocateSharedPages()", 2017-08-23).
Pass the resultant translation offset ("RingBaseShift"), from system
memory address to bus master device address, to VIRTIO_SET_QUEUE_ADDRESS.
Unmap the ring in all contexts where the ring becomes unused (these
contexts are mutually exclusive):
- in VirtioGpuInit(): the ring has been mapped, but we cannot complete the
virtio initialization for another reason,
- in VirtioGpuUninit(): the virtio initialization has succeeded, but
VirtioGpuDriverBindingStart() fails for another reason, or
VirtioGpuDriverBindingStop() unbinds the device after use,
- in VirtioGpuExitBoot(): ExitBootServices() is called after
VirtioGpuDriverBindingStart() has successfully bound the device.
(Unmapping the ring does not change the UEFI memory map.)
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
-rw-r--r-- | OvmfPkg/VirtioGpuDxe/Commands.c | 27 | ||||
-rw-r--r-- | OvmfPkg/VirtioGpuDxe/VirtioGpu.h | 6 |
2 files changed, 30 insertions, 3 deletions
diff --git a/OvmfPkg/VirtioGpuDxe/Commands.c b/OvmfPkg/VirtioGpuDxe/Commands.c index 5cb0031612..4e19bac606 100644 --- a/OvmfPkg/VirtioGpuDxe/Commands.c +++ b/OvmfPkg/VirtioGpuDxe/Commands.c @@ -44,6 +44,7 @@ VirtioGpuInit ( EFI_STATUS Status;
UINT64 Features;
UINT16 QueueSize;
+ UINT64 RingBaseShift;
//
// Execute virtio-v1.0-cs04, 3.1.1 Driver Requirements: Device
@@ -132,13 +133,28 @@ VirtioGpuInit ( if (EFI_ERROR (Status)) {
goto Failed;
}
+ //
+ // If anything fails from here on, we have to release the ring.
+ //
+ Status = VirtioRingMap (
+ VgpuDev->VirtIo,
+ &VgpuDev->Ring,
+ &RingBaseShift,
+ &VgpuDev->RingMap
+ );
+ if (EFI_ERROR (Status)) {
+ goto ReleaseQueue;
+ }
+ //
+ // If anything fails from here on, we have to unmap the ring.
+ //
Status = VgpuDev->VirtIo->SetQueueAddress (
VgpuDev->VirtIo,
&VgpuDev->Ring,
- 0
+ RingBaseShift
);
if (EFI_ERROR (Status)) {
- goto ReleaseQueue;
+ goto UnmapQueue;
}
//
@@ -147,11 +163,14 @@ VirtioGpuInit ( NextDevStat |= VSTAT_DRIVER_OK;
Status = VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, NextDevStat);
if (EFI_ERROR (Status)) {
- goto ReleaseQueue;
+ goto UnmapQueue;
}
return EFI_SUCCESS;
+UnmapQueue:
+ VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, VgpuDev->RingMap);
+
ReleaseQueue:
VirtioRingUninit (VgpuDev->VirtIo, &VgpuDev->Ring);
@@ -188,6 +207,7 @@ VirtioGpuUninit ( // configuration.
//
VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, 0);
+ VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, VgpuDev->RingMap);
VirtioRingUninit (VgpuDev->VirtIo, &VgpuDev->Ring);
}
@@ -215,6 +235,7 @@ VirtioGpuExitBoot ( VgpuDev = Context;
VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, 0);
+ VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, VgpuDev->RingMap);
}
/**
diff --git a/OvmfPkg/VirtioGpuDxe/VirtioGpu.h b/OvmfPkg/VirtioGpuDxe/VirtioGpu.h index 078b7d44d8..193e932e14 100644 --- a/OvmfPkg/VirtioGpuDxe/VirtioGpu.h +++ b/OvmfPkg/VirtioGpuDxe/VirtioGpu.h @@ -56,6 +56,12 @@ typedef struct { VRING Ring;
//
+ // Token associated with Ring's mapping for bus master common buffer
+ // operation, from VirtioRingMap().
+ //
+ VOID *RingMap;
+
+ //
// Event to be signaled at ExitBootServices().
//
EFI_EVENT ExitBoot;
|