From nobody Sat Jul 12 10:02:33 2025 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1503926688382889.1541349266197; Mon, 28 Aug 2017 06:24:48 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 215D32095DCA7; Mon, 28 Aug 2017 06:22:07 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D5A5021DF809B for ; Mon, 28 Aug 2017 06:22:05 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D42FE4ACBA; Mon, 28 Aug 2017 13:24:44 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-116-67.phx2.redhat.com [10.3.116.67]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7CA0860605; Mon, 28 Aug 2017 13:24:43 +0000 (UTC) X-Original-To: edk2-devel@lists.01.org DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com D42FE4ACBA Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=lersek@redhat.com From: Laszlo Ersek To: edk2-devel-01 Date: Mon, 28 Aug 2017 15:24:32 +0200 Message-Id: <20170828132436.15933-3-lersek@redhat.com> In-Reply-To: <20170828132436.15933-1-lersek@redhat.com> References: <20170828132436.15933-1-lersek@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 28 Aug 2017 13:24:45 +0000 (UTC) Subject: [edk2] [PATCH 2/6] OvmfPkg/VirtioGpuDxe: map virtio GPU command objects to device addresses X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jordan Justen , Tom Lendacky , Ard Biesheuvel MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" 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 Cc: Brijesh Singh Cc: Jordan Justen Cc: Tom Lendacky Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek --- OvmfPkg/VirtioGpuDxe/Commands.c | 83 ++++++++++++++++++-- 1 file changed, 75 insertions(+), 8 deletions(-) diff --git a/OvmfPkg/VirtioGpuDxe/Commands.c b/OvmfPkg/VirtioGpuDxe/Command= s.c index 4e19bac606ee..bdedea1df6a7 100644 --- a/OvmfPkg/VirtioGpuDxe/Commands.c +++ b/OvmfPkg/VirtioGpuDxe/Commands.c @@ -229,148 +229,215 @@ EFIAPI VirtioGpuExitBoot ( IN EFI_EVENT Event, IN VOID *Context ) { VGPU_DEV *VgpuDev; =20 VgpuDev =3D Context; VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, 0); VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, VgpuDev->RingMap); } =20 /** Internal utility function that sends a request to the VirtIo GPU device model, awaits the answer from the host, and returns a status. =20 @param[in,out] VgpuDev The VGPU_DEV object that represents the VirtIo G= PU device. The caller is responsible to have successfully invoked VirtioGpuInit() on VgpuDev previously, while VirtioGpuUninit() must not have been called on VgpuDev. =20 @param[in] RequestType The type of the request. The caller is responsib= le for providing a VirtioGpuCmd* RequestType which,= on success, elicits a VirtioGpuRespOkNodata response from the host. =20 @param[in] Fence Whether to enable fencing for this request. Fenc= ing forces the host to complete the command before producing a response. If Fence is TRUE, then VgpuDev->FenceId is consumed, and incremented. =20 @param[in,out] Header Pointer to the caller-allocated request object. = The request must start with VIRTIO_GPU_CONTROL_HEADE= R. This function overwrites all fields of Header be= fore submitting the request to the host: =20 - it sets Type from RequestType, =20 - it sets Flags and FenceId based on Fence, =20 - it zeroes CtxId and Padding. =20 @param[in] RequestSize Size of the entire caller-allocated request obje= ct, including the leading VIRTIO_GPU_CONTROL_HEADER. =20 @retval EFI_SUCCESS Operation successful. =20 @retval EFI_DEVICE_ERROR The host rejected the request. The host e= rror code has been logged on the EFI_D_ERROR l= evel. =20 @return Codes for unexpected errors in VirtIo - messaging. + messaging, or request/response + mapping/unmapping. **/ STATIC EFI_STATUS VirtioGpuSendCommand ( IN OUT VGPU_DEV *VgpuDev, IN VIRTIO_GPU_CONTROL_TYPE RequestType, IN BOOLEAN Fence, IN OUT volatile VIRTIO_GPU_CONTROL_HEADER *Header, IN UINTN RequestSize ) { DESC_INDICES Indices; volatile VIRTIO_GPU_CONTROL_HEADER Response; EFI_STATUS Status; UINT32 ResponseSize; + EFI_PHYSICAL_ADDRESS RequestDeviceAddress; + VOID *RequestMap; + EFI_PHYSICAL_ADDRESS ResponseDeviceAddress; + VOID *ResponseMap; =20 // // Initialize Header. // Header->Type =3D RequestType; if (Fence) { Header->Flags =3D VIRTIO_GPU_FLAG_FENCE; Header->FenceId =3D VgpuDev->FenceId++; } else { Header->Flags =3D 0; Header->FenceId =3D 0; } Header->CtxId =3D 0; Header->Padding =3D 0; =20 ASSERT (RequestSize >=3D sizeof *Header); ASSERT (RequestSize <=3D MAX_UINT32); =20 + // + // Map request and response to bus master device addresses. + // + Status =3D VirtioMapAllBytesInSharedBuffer ( + VgpuDev->VirtIo, + VirtioOperationBusMasterRead, + (VOID *)Header, + RequestSize, + &RequestDeviceAddress, + &RequestMap + ); + if (EFI_ERROR (Status)) { + return Status; + } + Status =3D VirtioMapAllBytesInSharedBuffer ( + VgpuDev->VirtIo, + VirtioOperationBusMasterWrite, + (VOID *)&Response, + sizeof Response, + &ResponseDeviceAddress, + &ResponseMap + ); + if (EFI_ERROR (Status)) { + goto UnmapRequest; + } + // // Compose the descriptor chain. // VirtioPrepare (&VgpuDev->Ring, &Indices); - VirtioAppendDesc (&VgpuDev->Ring, (UINTN)Header, (UINT32)RequestSize, - VRING_DESC_F_NEXT, &Indices); - VirtioAppendDesc (&VgpuDev->Ring, (UINTN)&Response, sizeof Response, - VRING_DESC_F_WRITE, &Indices); + VirtioAppendDesc ( + &VgpuDev->Ring, + RequestDeviceAddress, + (UINT32)RequestSize, + VRING_DESC_F_NEXT, + &Indices + ); + VirtioAppendDesc ( + &VgpuDev->Ring, + ResponseDeviceAddress, + (UINT32)sizeof Response, + VRING_DESC_F_WRITE, + &Indices + ); =20 // // Send the command. // Status =3D VirtioFlush (VgpuDev->VirtIo, VIRTIO_GPU_CONTROL_QUEUE, &VgpuDev->Ring, &Indices, &ResponseSize); if (EFI_ERROR (Status)) { - return Status; + goto UnmapResponse; } =20 // - // Parse the response. + // Verify response size. // if (ResponseSize !=3D sizeof Response) { DEBUG ((EFI_D_ERROR, "%a: malformed response to Request=3D0x%x\n", __FUNCTION__, (UINT32)RequestType)); - return EFI_PROTOCOL_ERROR; + Status =3D EFI_PROTOCOL_ERROR; + goto UnmapResponse; } =20 + // + // Unmap response and request, in reverse order of mapping. On error, the + // respective mapping is invalidated anyway, only the data may not have = been + // committed to system memory (in case of VirtioOperationBusMasterWrite). + // + Status =3D VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, Response= Map); + if (EFI_ERROR (Status)) { + goto UnmapRequest; + } + Status =3D VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, RequestM= ap); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Parse the response. + // if (Response.Type =3D=3D VirtioGpuRespOkNodata) { return EFI_SUCCESS; } =20 DEBUG ((EFI_D_ERROR, "%a: Request=3D0x%x Response=3D0x%x\n", __FUNCTION_= _, (UINT32)RequestType, Response.Type)); return EFI_DEVICE_ERROR; + +UnmapResponse: + VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, ResponseMap); + +UnmapRequest: + VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, RequestMap); + + return Status; } =20 /** The following functions send requests to the VirtIo GPU device model, aw= ait the answer from the host, and return a status. They share the following interface details: =20 @param[in,out] VgpuDev The VGPU_DEV object that represents the VirtIo G= PU device. The caller is responsible to have successfully invoked VirtioGpuInit() on VgpuDev previously, while VirtioGpuUninit() must not have been called on VgpuDev. =20 @retval EFI_INVALID_PARAMETER Invalid command-specific parameters were detected by this driver. =20 @retval EFI_SUCCESS Operation successful. =20 @retval EFI_DEVICE_ERROR The host rejected the request. The host e= rror code has been logged on the EFI_D_ERROR l= evel. =20 @return Codes for unexpected errors in VirtIo messaging. =20 For the command-specific parameters, please consult the GPU Device secti= on of the VirtIo 1.0 specification (see references in "OvmfPkg/Include/IndustryStandard/VirtioGpu.h"). **/ --=20 2.14.1.3.gb7cf6e02401b _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel