Add functions to map and unmap the ring buffer with BusMasterCommonBuffer.
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
OvmfPkg/Include/Library/VirtioLib.h | 41 +++++++++++++++
OvmfPkg/Library/VirtioLib/VirtioLib.c | 52 ++++++++++++++++++++
2 files changed, 93 insertions(+)
diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
index 610654225de7..877961af0514 100644
--- a/OvmfPkg/Include/Library/VirtioLib.h
+++ b/OvmfPkg/Include/Library/VirtioLib.h
@@ -62,6 +62,47 @@ VirtioRingInit (
/**
+ Map the ring buffer so that it can be accessed equally by both guest
+ and hypervisor.
+
+ @param[in] VirtIo The virtio device instance.
+
+ @param[in] Ring The virtio ring to map.
+
+ @param[out] Mapping A resulting value to pass to Unmap().
+
+ @retval Value returned from VirtIo->MapSharedBuffer()
+**/
+EFI_STATUS
+EFIAPI
+VirtioRingMap (
+ IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
+ IN VRING *Ring,
+ OUT VOID **Mapping
+ );
+
+/**
+
+ Unmap the ring buffer mapped using VirtioRingMap()
+
+ @param[in] VirtIo The virtio device instance.
+
+ @param[in] Ring The virtio ring to unmap.
+
+ @param[in] Mapping A value obtained through Map().
+
+ @retval Value returned from VirtIo->UnmapSharedBuffer()
+**/
+EFI_STATUS
+EFIAPI
+VirtioRingUnmap (
+ IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
+ IN VRING *Ring,
+ IN VOID *Mapping
+ );
+
+/**
+
Tear down the internal resources of a configured virtio ring.
The caller is responsible to stop the host from using this ring before
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
index 50e5ec28ea1b..09a3f9b7f2e5 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
@@ -640,3 +640,55 @@ VirtioUnmapSharedBuffer (
{
return VirtIo->UnmapSharedBuffer (VirtIo, Mapping);
}
+
+/**
+
+ Map the ring buffer so that it can be accessed equally by both guest
+ and hypervisor.
+
+ @param[in] VirtIo The virtio device instance.
+
+ @param[in] Ring The virtio ring to map.
+
+ @param[out] Mapping A resulting value to pass to Unmap().
+
+ @retval Value returned from VirtIo->MapSharedBuffer()
+**/
+EFI_STATUS
+EFIAPI
+VirtioRingMap (
+ IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
+ IN VRING *Ring,
+ OUT VOID **Mapping
+ )
+{
+ UINTN NumberOfBytes;
+
+ NumberOfBytes = Ring->NumPages * EFI_PAGE_SIZE;
+
+ return VirtioMapSharedBufferCommon (VirtIo, Ring->Base,
+ NumberOfBytes, Mapping);
+}
+
+/**
+
+ Unmap the ring buffer mapped using VirtioRingMap()
+
+ @param[in] VirtIo The virtio device instance.
+
+ @param[in] Ring The virtio ring to unmap.
+
+ @param[in] Mapping A value obtained through Map().
+
+ @retval Value returned from VirtIo->UnmapSharedBuffer()
+**/
+EFI_STATUS
+EFIAPI
+VirtioRingUnmap (
+ IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
+ IN VRING *Ring,
+ IN VOID *Mapping
+ )
+{
+ return VirtioUnmapSharedBuffer (VirtIo, Mapping);
+}
--
2.7.4
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
First some superficial comments, then some more serious ones.
On 08/07/17 13:58, Brijesh Singh wrote:
> Add functions to map and unmap the ring buffer with BusMasterCommonBuffer.
>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
> OvmfPkg/Include/Library/VirtioLib.h | 41 +++++++++++++++
> OvmfPkg/Library/VirtioLib/VirtioLib.c | 52 ++++++++++++++++++++
> 2 files changed, 93 insertions(+)
>
> diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
> index 610654225de7..877961af0514 100644
> --- a/OvmfPkg/Include/Library/VirtioLib.h
> +++ b/OvmfPkg/Include/Library/VirtioLib.h
> @@ -62,6 +62,47 @@ VirtioRingInit (
>
> /**
>
> + Map the ring buffer so that it can be accessed equally by both guest
> + and hypervisor.
> +
> + @param[in] VirtIo The virtio device instance.
> +
> + @param[in] Ring The virtio ring to map.
> +
> + @param[out] Mapping A resulting value to pass to Unmap().
(1) Please say "token" here (to be consistent with my earlier request).
(2) Please replace Unmap() with VirtIo->UnmapSharedBuffer().
> +
> + @retval Value returned from VirtIo->MapSharedBuffer()
(3) This should be @return, not @retval. @retval is for concrete
constants. Also I would suggest "Status code" rather than "Value".
(4) Please sync the comment block in the C file.
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtioRingMap (
> + IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
> + IN VRING *Ring,
> + OUT VOID **Mapping
> + );
> +
> +/**
> +
> + Unmap the ring buffer mapped using VirtioRingMap()
> +
> + @param[in] VirtIo The virtio device instance.
> +
> + @param[in] Ring The virtio ring to unmap.
> +
> + @param[in] Mapping A value obtained through Map().
> +
> + @retval Value returned from VirtIo->UnmapSharedBuffer()
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtioRingUnmap (
> + IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
> + IN VRING *Ring,
> + IN VOID *Mapping
> + );
(5) Please drop this function. It doesn't save us anything. (The Ring
parameter isn't even used in the implementation.)
> +
> +/**
> +
> Tear down the internal resources of a configured virtio ring.
>
> The caller is responsible to stop the host from using this ring before
> diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
> index 50e5ec28ea1b..09a3f9b7f2e5 100644
> --- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
> +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
> @@ -640,3 +640,55 @@ VirtioUnmapSharedBuffer (
> {
> return VirtIo->UnmapSharedBuffer (VirtIo, Mapping);
> }
> +
> +/**
> +
> + Map the ring buffer so that it can be accessed equally by both guest
> + and hypervisor.
> +
> + @param[in] VirtIo The virtio device instance.
> +
> + @param[in] Ring The virtio ring to map.
> +
> + @param[out] Mapping A resulting value to pass to Unmap().
> +
> + @retval Value returned from VirtIo->MapSharedBuffer()
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtioRingMap (
> + IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
> + IN VRING *Ring,
> + OUT VOID **Mapping
> + )
> +{
> + UINTN NumberOfBytes;
> +
> + NumberOfBytes = Ring->NumPages * EFI_PAGE_SIZE;
(6) "EFI_PAGES_TO_SIZE (Ring->NumPages)" is more idiomatic.
> +
> + return VirtioMapSharedBufferCommon (VirtIo, Ring->Base,
> + NumberOfBytes, Mapping);
(7) So, based on my earlier request, this should become a call to
VirtioMapAllBytesInSharedBuffer(). Please break every argument to a
separate line.
Now, my important comments for this patch. :)
VirtioMapAllBytesInSharedBuffer() will give you a DeviceAddress. Here's
what we should do with it:
(8) Please introduce a new patch that modifies the
VIRTIO_SET_QUEUE_ADDRESS typedef, in
"OvmfPkg/Include/Protocol/VirtioDevice.h". Namely, please add a third
parameter:
IN UINT64 RingBaseShift
In this initial patch, simply update all call sites to pass in 0.
In parallel (in the same initial patch), update all three implementations:
- VirtioMmioSetQueueAddress()
[OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c]
- VirtioPciSetQueueAddress()
[OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c]
- Virtio10SetQueueAddress() [OvmfPkg/Virtio10Dxe/Virtio10.c]
as follows:
- accept the new parameter (obviously),
- simply assert that it is zero, at the top of the function.
(9) Modify Virtio10SetQueueAddress() as follows, in another separate patch:
- every time after the local variable "Address" is assigned, please insert:
Address += RingBaseShift;
This is automatically going to happen in UINT64 arithmetic, which has
well-defined wrap-around semantics. Three such insertions will be necessary.
- remove the ASSERT added in (8)
(10) Then please include the present patch, with the following update
(beyond the changes requested above):
- Add the following output parameter to VirtioRingMap():
OUT UINT64 *RingBaseShift
- In the implementation, assign it like this, if
VirtioMapAllBytesInSharedBuffer() succeeds:
*RingBaseShift = DeviceAddress - (UINT64)(UINTN)Ring->Base;
(DeviceAddress has type EFI_PHYSICAL_ADDRESS, which is equivalent to
UINT64, on the spec level.)
(11) Please make sure that no output parameter is modified before we can
guarantee returning EFI_SUCCESS.
(12) In the individual virtio device drivers, whenever you insert the
VirtioRingMap() function call, carry "RingBaseShift" from
VirtioRingMap() to VirtIo->SetQueueAddress() in a new local UINT64 variable.
End result:
- the MMIO and legacy PCI transport implementations will always set
DeviceAddress to HostAddress in their no-op MapSharedBuffer() member
functions,
- therefore VirtioRingMap() will set RingBaseShift to zero,
- the ASSERT()s in the SetQueueAddress() members of those same transport
implementations will be satisfied,
- with the modern-only (1.0) transport, RingBaseShift will also be zero
(because of the SEV IOMMU that we have), and "Address += 0" will have no
effect,
- if we ever add an IOMMU driver that translates addresses, the
translation will happen automatically in the modern-only transport.
Thanks,
Laszlo
> +}
> +
> +/**
> +
> + Unmap the ring buffer mapped using VirtioRingMap()
> +
> + @param[in] VirtIo The virtio device instance.
> +
> + @param[in] Ring The virtio ring to unmap.
> +
> + @param[in] Mapping A value obtained through Map().
> +
> + @retval Value returned from VirtIo->UnmapSharedBuffer()
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtioRingUnmap (
> + IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
> + IN VRING *Ring,
> + IN VOID *Mapping
> + )
> +{
> + return VirtioUnmapSharedBuffer (VirtIo, Mapping);
> +}
>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2025 Red Hat, Inc.