]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/VirtioGpuDxe: map virtio GPU command objects to device addresses
authorLaszlo Ersek <lersek@redhat.com>
Sat, 26 Aug 2017 15:34:51 +0000 (17:34 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Fri, 1 Sep 2017 12:28:15 +0000 (14:28 +0200)
Every virtio GPU command used by VirtioGpuDxe is synchronous and formatted
as a two-descriptor chain: request, response. The internal workhorse
function that all the command-specific functions call for such messaging
is VirtioGpuSendCommand().

In VirtioGpuSendCommand(), map the request from system memory to bus
master device address for BusMasterRead operation, and map the response
from system memory to bus master device address for BusMasterWrite
operation.

Pass the bus master device addresses to VirtioAppendDesc(). (See also
commit 4b725858de68, "OvmfPkg/VirtioLib: change the parameter of
VirtioAppendDesc() to UINT64", 2017-08-23.)

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>
OvmfPkg/VirtioGpuDxe/Commands.c

index 4e19bac606eea0d1fda3e757344c49b3dbb784f5..bdedea1df6a70887c0664f6a79ec38ef623853bb 100644 (file)
@@ -278,7 +278,8 @@ VirtioGpuExitBoot (
                                  code has been logged on the EFI_D_ERROR level.\r
 \r
   @return                        Codes for unexpected errors in VirtIo\r
-                                 messaging.\r
+                                 messaging, or request/response\r
+                                 mapping/unmapping.\r
 **/\r
 STATIC\r
 EFI_STATUS\r
@@ -294,6 +295,10 @@ VirtioGpuSendCommand (
   volatile VIRTIO_GPU_CONTROL_HEADER Response;\r
   EFI_STATUS                         Status;\r
   UINT32                             ResponseSize;\r
+  EFI_PHYSICAL_ADDRESS               RequestDeviceAddress;\r
+  VOID                               *RequestMap;\r
+  EFI_PHYSICAL_ADDRESS               ResponseDeviceAddress;\r
+  VOID                               *ResponseMap;\r
 \r
   //\r
   // Initialize Header.\r
@@ -312,14 +317,50 @@ VirtioGpuSendCommand (
   ASSERT (RequestSize >= sizeof *Header);\r
   ASSERT (RequestSize <= MAX_UINT32);\r
 \r
+  //\r
+  // Map request and response to bus master device addresses.\r
+  //\r
+  Status = VirtioMapAllBytesInSharedBuffer (\r
+             VgpuDev->VirtIo,\r
+             VirtioOperationBusMasterRead,\r
+             (VOID *)Header,\r
+             RequestSize,\r
+             &RequestDeviceAddress,\r
+             &RequestMap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  Status = VirtioMapAllBytesInSharedBuffer (\r
+             VgpuDev->VirtIo,\r
+             VirtioOperationBusMasterWrite,\r
+             (VOID *)&Response,\r
+             sizeof Response,\r
+             &ResponseDeviceAddress,\r
+             &ResponseMap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto UnmapRequest;\r
+  }\r
+\r
   //\r
   // Compose the descriptor chain.\r
   //\r
   VirtioPrepare (&VgpuDev->Ring, &Indices);\r
-  VirtioAppendDesc (&VgpuDev->Ring, (UINTN)Header, (UINT32)RequestSize,\r
-    VRING_DESC_F_NEXT, &Indices);\r
-  VirtioAppendDesc (&VgpuDev->Ring, (UINTN)&Response, sizeof Response,\r
-    VRING_DESC_F_WRITE, &Indices);\r
+  VirtioAppendDesc (\r
+    &VgpuDev->Ring,\r
+    RequestDeviceAddress,\r
+    (UINT32)RequestSize,\r
+    VRING_DESC_F_NEXT,\r
+    &Indices\r
+    );\r
+  VirtioAppendDesc (\r
+    &VgpuDev->Ring,\r
+    ResponseDeviceAddress,\r
+    (UINT32)sizeof Response,\r
+    VRING_DESC_F_WRITE,\r
+    &Indices\r
+    );\r
 \r
   //\r
   // Send the command.\r
@@ -327,18 +368,36 @@ VirtioGpuSendCommand (
   Status = VirtioFlush (VgpuDev->VirtIo, VIRTIO_GPU_CONTROL_QUEUE,\r
              &VgpuDev->Ring, &Indices, &ResponseSize);\r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    goto UnmapResponse;\r
   }\r
 \r
   //\r
-  // Parse the response.\r
+  // Verify response size.\r
   //\r
   if (ResponseSize != sizeof Response) {\r
     DEBUG ((EFI_D_ERROR, "%a: malformed response to Request=0x%x\n",\r
       __FUNCTION__, (UINT32)RequestType));\r
-    return EFI_PROTOCOL_ERROR;\r
+    Status = EFI_PROTOCOL_ERROR;\r
+    goto UnmapResponse;\r
   }\r
 \r
+  //\r
+  // Unmap response and request, in reverse order of mapping. On error, the\r
+  // respective mapping is invalidated anyway, only the data may not have been\r
+  // committed to system memory (in case of VirtioOperationBusMasterWrite).\r
+  //\r
+  Status = VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, ResponseMap);\r
+  if (EFI_ERROR (Status)) {\r
+    goto UnmapRequest;\r
+  }\r
+  Status = VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, RequestMap);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Parse the response.\r
+  //\r
   if (Response.Type == VirtioGpuRespOkNodata) {\r
     return EFI_SUCCESS;\r
   }\r
@@ -346,6 +405,14 @@ VirtioGpuSendCommand (
   DEBUG ((EFI_D_ERROR, "%a: Request=0x%x Response=0x%x\n", __FUNCTION__,\r
     (UINT32)RequestType, Response.Type));\r
   return EFI_DEVICE_ERROR;\r
+\r
+UnmapResponse:\r
+  VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, ResponseMap);\r
+\r
+UnmapRequest:\r
+  VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, RequestMap);\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r