From patchwork Wed Feb 24 08:34:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 62778 Delivered-To: patch@linaro.org Received: by 10.112.43.199 with SMTP id y7csp2271930lbl; Wed, 24 Feb 2016 00:34:51 -0800 (PST) X-Received: by 10.98.80.91 with SMTP id e88mr52532988pfb.62.1456302891394; Wed, 24 Feb 2016 00:34:51 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id w6si3449914pfi.99.2016.02.24.00.34.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Feb 2016 00:34:51 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dkim=neutral (body hash did not verify) header.i=@linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 4E6DA1A1F91; Wed, 24 Feb 2016 00:34:54 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x231.google.com (mail-wm0-x231.google.com [IPv6:2a00:1450:400c:c09::231]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 583371A1F25 for ; Wed, 24 Feb 2016 00:34:52 -0800 (PST) Received: by mail-wm0-x231.google.com with SMTP id a4so18642503wme.1 for ; Wed, 24 Feb 2016 00:34:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ziL5CCsRj3Xac+L+wAqpKWw0aHdifqZG3wFfFeAEPwM=; b=GKqs/L3j0L+zkHNbJ6I9eec+c0JQC9nTkISF5dPWAwfyTPMJLxRHkOBO6/tFIfkOiL dULkhBj3yu57nCAFdFPKNMh/UZbjN7tbkDLqI2KFfOFnYPQIOjh9F1r58CyXRYvOnmPe b/oN5R29BLYKGx4nod7w+N00Vug25eurY2r6o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ziL5CCsRj3Xac+L+wAqpKWw0aHdifqZG3wFfFeAEPwM=; b=eKBbw47TRmuDDzGQf7BvlIFoyk+MTY2+HSLhxh71OIwrRRX9BVMpJ9+T4chp3aBNMW +YvN1spcnJItlosoRIJIhTHUD4CGToFdVAaX+rgzEmQFDYYbP6g8lGpb3NzjbYek0Cep NLW8iGlNTCANnJgIagBN9xJgtNyh7E/wqBWcNuIPCPA4rbVMyS6ES6VKcudU/AOuMPsb lbLnjboY5HHaOHRpqrlEl7dtvoxxce7xhGqCvSPZ9FfJufWTqKQP4W3BB12tlkcd2I0T pZrg/xuXKheAqCQ/l4hi3k3NIJpWuzBj/UP/A0T2SqxH3x00j/MuFBQD4RQXIpV1LITZ YfRw== X-Gm-Message-State: AG10YOQn0uhSfCsB+ZBKLUidpN1fThxKoFq0bvlVDCRMW//Kc9goWeMVMhkvonWDEiJZGK/W X-Received: by 10.194.113.38 with SMTP id iv6mr37698305wjb.126.1456302887720; Wed, 24 Feb 2016 00:34:47 -0800 (PST) Received: from localhost.localdomain ([195.55.142.58]) by smtp.gmail.com with ESMTPSA id za6sm1822367wjc.18.2016.02.24.00.34.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 24 Feb 2016 00:34:47 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, lersek@redhat.com, jordan.l.justen@intel.com Date: Wed, 24 Feb 2016 09:34:33 +0100 Message-Id: <1456302876-24702-2-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1456302876-24702-1-git-send-email-ard.biesheuvel@linaro.org> References: <1456302876-24702-1-git-send-email-ard.biesheuvel@linaro.org> Cc: Ard Biesheuvel Subject: [edk2] [PATCH v4 1/4] OvmfPkg: VirtioFlush(): return the number of bytes written by the host X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" From: Laszlo Ersek VirtioLib provides an API for simple, synchronous (request/response-style) virtio communication. The guest driver builds one descriptor chain, link for link, with VirtioPrepare() and VirtioAppendDesc(), then submits the chain, and awaits the processing, with VirtioFlush(). The descriptor chain is always built at the beginning of the descriptor area, with the head descriptor having descriptor index 0. In order to submit the descriptor chain to the host, the guest always pushes a new "available element" to the Available Ring, in genuine queue-like fashion, with the new element referencing the head descriptor (which always has index 0, see above). In turn, after processing, the host always pushes a new "used element" to the Used Ring, in genuine queue-like fashion, with the new element referencing the head descriptor of the chain that was just processed. The same element also reports the number of bytes that the host wrote, consecutively across the host-writeable buffers that were linked by the descriptors. (See "OvmfPkg/VirtioNetDxe/TechNotes.txt" for a diagram about the descriptor area and the rings.) Because at most one descriptor chain can be in flight with VirtioLib at any time, - the Available Ring and the Used Ring proceed in lock-step, - and the head descriptor that the new "available" and "used" elements can ever reference has index 0. Based on the above, we can modify VirtioFlush() to return the number of bytes written by the host across the descriptor chain. The virtio-block and virtio-scsi drivers don't care (they have other ways to parse the data produced by the host), while the virtio-net driver doesn't use VirtioFlush() at all (it employs VirtioLib only to set up its rings). However, the virtio entropy device, to be covered in the upcoming patches, reports the amount of randomness produced by the host only through this quantity. Cc: Jordan Justen Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Signed-off-by: Ard Biesheuvel Reviewed-by: Jordan Justen --- OvmfPkg/Include/Library/VirtioLib.h | 11 +++++++-- OvmfPkg/Library/VirtioLib/VirtioLib.c | 26 ++++++++++++++++++-- OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 3 ++- OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 2 +- 4 files changed, 36 insertions(+), 6 deletions(-) -- 2.5.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h index 36527a523f28..decd4418af3d 100644 --- a/OvmfPkg/Include/Library/VirtioLib.h +++ b/OvmfPkg/Include/Library/VirtioLib.h @@ -2,7 +2,7 @@ Declarations of utility functions used by virtio device drivers. - Copyright (C) 2012, Red Hat, Inc. + Copyright (C) 2012-2016, Red Hat, Inc. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this @@ -167,6 +167,12 @@ VirtioAppendDesc ( Indices->HeadDescIdx identifies the head descriptor of the descriptor chain. + @param[out] UsedLen On success, the total number of bytes, consecutively + across the buffers linked by the descriptor chain, + that the host wrote. May be NULL if the caller + doesn't care, or can compute the same information + from device-specific request structures linked by the + descriptor chain. @return Error code from VirtIo->SetQueueNotify() if it fails. @@ -179,7 +185,8 @@ VirtioFlush ( IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN UINT16 VirtQueueId, IN OUT VRING *Ring, - IN DESC_INDICES *Indices + IN DESC_INDICES *Indices, + OUT UINT32 *UsedLen OPTIONAL ); #endif // _VIRTIO_LIB_H_ diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c index 54cf225c9885..4b1d78b5a03e 100644 --- a/OvmfPkg/Library/VirtioLib/VirtioLib.c +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c @@ -2,7 +2,7 @@ Utility functions used by virtio device drivers. - Copyright (C) 2012, Red Hat, Inc. + Copyright (C) 2012-2016, Red Hat, Inc. Portion of Copyright (C) 2013, ARM Ltd. This program and the accompanying materials are licensed and made available @@ -249,6 +249,12 @@ VirtioAppendDesc ( Indices->HeadDescIdx identifies the head descriptor of the descriptor chain. + @param[out] UsedLen On success, the total number of bytes, consecutively + across the buffers linked by the descriptor chain, + that the host wrote. May be NULL if the caller + doesn't care, or can compute the same information + from device-specific request structures linked by the + descriptor chain. @return Error code from VirtIo->SetQueueNotify() if it fails. @@ -261,10 +267,12 @@ VirtioFlush ( IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN UINT16 VirtQueueId, IN OUT VRING *Ring, - IN DESC_INDICES *Indices + IN DESC_INDICES *Indices, + OUT UINT32 *UsedLen OPTIONAL ) { UINT16 NextAvailIdx; + UINT16 LastUsedIdx; EFI_STATUS Status; UINTN PollPeriodUsecs; @@ -276,6 +284,11 @@ VirtioFlush ( // head descriptor of any given descriptor chain. // NextAvailIdx = *Ring->Avail.Idx; + // + // (Due to our lock-step progress, this is where the host will produce the + // used element with the head descriptor's index in it.) + // + LastUsedIdx = NextAvailIdx; Ring->Avail.Ring[NextAvailIdx++ % Ring->QueueSize] = Indices->HeadDescIdx % Ring->QueueSize; @@ -315,5 +328,14 @@ VirtioFlush ( } MemoryFence(); + + if (UsedLen != NULL) { + volatile CONST VRING_USED_ELEM *UsedElem; + + UsedElem = &Ring->Used.UsedElem[LastUsedIdx % Ring->QueueSize]; + ASSERT (UsedElem->Id == Indices->HeadDescIdx); + *UsedLen = UsedElem->Len; + } + return EFI_SUCCESS; } diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c index 75f85ca6e09a..50511a1e446b 100644 --- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c +++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c @@ -324,7 +324,8 @@ SynchronousRequest ( // // virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D). // - if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices) == EFI_SUCCESS && + if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices, + NULL) == EFI_SUCCESS && HostStatus == VIRTIO_BLK_S_OK) { return EFI_SUCCESS; } diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c index e1e12039b359..f5f412a32e9b 100644 --- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c +++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c @@ -470,7 +470,7 @@ VirtioScsiPassThru ( // caller retry. // if (VirtioFlush (Dev->VirtIo, VIRTIO_SCSI_REQUEST_QUEUE, &Dev->Ring, - &Indices) != EFI_SUCCESS) { + &Indices, NULL) != EFI_SUCCESS) { Packet->InTransferLength = 0; Packet->OutTransferLength = 0; Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;