From 39c2d339621bf1bdcb31a5501379e76996ed6bf6 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Sat, 12 Mar 2016 14:41:26 +0100 Subject: OvmfPkg: VirtioScsiDxe: adapt feature negotiation to virtio-1.0 Relative to virtio-0.9.5, virtio-1.0 reverses the order of queue discovery and feature negotiation. In virtio-1.0, feature negotiation has to complete first, and the device can also reject a self-inconsistent feature request through the new VSTAT_FEATURES_OK status bit. (For example if the driver requests a higher level feature but clears a prerequisite feature.) Furthermore, we retain the VIRTIO_F_VERSION_1 feature bit if the VIRTIO_DEVICE_PROTOCOL provider has high enough revision. Cc: Ard Biesheuvel Cc: Jordan Justen Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Tested-by: Ard Biesheuvel Reviewed-by: Jordan Justen --- OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'OvmfPkg') diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c index 162577bcb9..c080404330 100644 --- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c +++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c @@ -800,6 +800,19 @@ VirtioScsiInit ( goto Failed; } + Features &= VIRTIO_SCSI_F_INOUT | VIRTIO_F_VERSION_1; + + // + // In virtio-1.0, feature negotiation is expected to complete before queue + // discovery, and the device can also reject the selected set of features. + // + if (Dev->VirtIo->Revision >= VIRTIO_SPEC_REVISION (1, 0, 0)) { + Status = Virtio10WriteFeatures (Dev->VirtIo, Features, &NextDevStat); + if (EFI_ERROR (Status)) { + goto Failed; + } + } + // // step 4b -- allocate request virtqueue // @@ -847,14 +860,14 @@ VirtioScsiInit ( } // - // step 5 -- Report understood features and guest-tuneables. We want none of - // the known (or unknown) VIRTIO_SCSI_F_* or VIRTIO_F_* capabilities (see - // virtio-0.9.5, Appendices B and I), except bidirectional transfers. + // step 5 -- Report understood features and guest-tuneables. // - Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, - Features & VIRTIO_SCSI_F_INOUT); - if (EFI_ERROR (Status)) { - goto ReleaseQueue; + if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) { + Features &= ~(UINT64)VIRTIO_F_VERSION_1; + Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features); + if (EFI_ERROR (Status)) { + goto ReleaseQueue; + } } // -- cgit v1.2.3