Reviewed-by: Jordan Justen <[email protected]>
On 2016-02-19 09:15:07, Laszlo Ersek wrote: > 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: Ard Biesheuvel <[email protected]> > Cc: Jordan Justen <[email protected]> > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Laszlo Ersek <[email protected]> > --- > 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(-) > > 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; > -- > 1.8.3.1 > _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

