diff mbox

[edk2,wave,3,07/15] OvmfPkg: VirtioLib: add Virtio10WriteFeatures() function

Message ID 1457960012-29481-8-git-send-email-lersek@redhat.com
State Superseded
Headers show

Commit Message

Laszlo Ersek March 14, 2016, 12:53 p.m. UTC
In VirtIo 1.0, a device can reject a self-inconsistent feature bitmap
through the new VSTAT_FEATURES_OK status bit. (For example if the driver
requests a higher level feature but clears a prerequisite feature.) This
function is a small wrapper around
VIRTIO_DEVICE_PROTOCOL.SetGuestFeatures() that also verifies if the VirtIo
1.0 device accepts the feature bitmap.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>

---
 OvmfPkg/Include/Library/VirtioLib.h   | 47 ++++++++++++
 OvmfPkg/Library/VirtioLib/VirtioLib.c | 75 ++++++++++++++++++++
 2 files changed, 122 insertions(+)

-- 
1.8.3.1


_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
diff mbox

Patch

diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h
index decd4418af3d..989283c67d70 100644
--- a/OvmfPkg/Include/Library/VirtioLib.h
+++ b/OvmfPkg/Include/Library/VirtioLib.h
@@ -16,14 +16,15 @@ 
 
 #ifndef _VIRTIO_LIB_H_
 #define _VIRTIO_LIB_H_
 
 #include <Protocol/VirtioDevice.h>
 
 #include <IndustryStandard/Virtio.h>
+#include <IndustryStandard/Virtio10.h>
 
 
 /**
 
   Configure a virtio ring.
 
   This function sets up internal storage (the guest-host communication area)
@@ -185,8 +186,54 @@  VirtioFlush (
   IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,
   IN     UINT16                 VirtQueueId,
   IN OUT VRING                  *Ring,
   IN     DESC_INDICES           *Indices,
   OUT    UINT32                 *UsedLen    OPTIONAL
   );
 
+
+/**
+
+  Report the feature bits to the VirtIo 1.0 device that the VirtIo 1.0 driver
+  understands.
+
+  In VirtIo 1.0, a device can reject a self-inconsistent feature bitmap through
+  the new VSTAT_FEATURES_OK status bit. (For example if the driver requests a
+  higher level feature but clears a prerequisite feature.) This function is a
+  small wrapper around VIRTIO_DEVICE_PROTOCOL.SetGuestFeatures() that also
+  verifies if the VirtIo 1.0 device accepts the feature bitmap.
+
+  @param[in]     VirtIo        Report feature bits to this device.
+
+  @param[in]     Features      The set of feature bits that the driver wishes
+                               to report. The caller is responsible to perform
+                               any masking before calling this function; the
+                               value is directly written with
+                               VIRTIO_DEVICE_PROTOCOL.SetGuestFeatures().
+
+  @param[in,out] DeviceStatus  On input, the status byte most recently written
+                               to the device's status register. On output (even
+                               on error), DeviceStatus will be updated so that
+                               it is suitable for further status bit
+                               manipulation and writing to the device's status
+                               register.
+
+  @retval  EFI_SUCCESS      The device accepted the configuration in Features.
+
+  @return  EFI_UNSUPPORTED  The device rejected the configuration in Features.
+
+  @retval  EFI_UNSUPPORTED  VirtIo->Revision is smaller than 1.0.0.
+
+  @return                   Error codes from the SetGuestFeatures(),
+                            SetDeviceStatus(), GetDeviceStatus() member
+                            functions.
+
+**/
+EFI_STATUS
+EFIAPI
+Virtio10WriteFeatures (
+  IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN     UINT64                 Features,
+  IN OUT UINT8                  *DeviceStatus
+  );
+
 #endif // _VIRTIO_LIB_H_
diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c
index 4b1d78b5a03e..845f206369a3 100644
--- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
+++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
@@ -335,7 +335,82 @@  VirtioFlush (
     UsedElem = &Ring->Used.UsedElem[LastUsedIdx % Ring->QueueSize];
     ASSERT (UsedElem->Id == Indices->HeadDescIdx);
     *UsedLen = UsedElem->Len;
   }
 
   return EFI_SUCCESS;
 }
+
+
+/**
+
+  Report the feature bits to the VirtIo 1.0 device that the VirtIo 1.0 driver
+  understands.
+
+  In VirtIo 1.0, a device can reject a self-inconsistent feature bitmap through
+  the new VSTAT_FEATURES_OK status bit. (For example if the driver requests a
+  higher level feature but clears a prerequisite feature.) This function is a
+  small wrapper around VIRTIO_DEVICE_PROTOCOL.SetGuestFeatures() that also
+  verifies if the VirtIo 1.0 device accepts the feature bitmap.
+
+  @param[in]     VirtIo        Report feature bits to this device.
+
+  @param[in]     Features      The set of feature bits that the driver wishes
+                               to report. The caller is responsible to perform
+                               any masking before calling this function; the
+                               value is directly written with
+                               VIRTIO_DEVICE_PROTOCOL.SetGuestFeatures().
+
+  @param[in,out] DeviceStatus  On input, the status byte most recently written
+                               to the device's status register. On output (even
+                               on error), DeviceStatus will be updated so that
+                               it is suitable for further status bit
+                               manipulation and writing to the device's status
+                               register.
+
+  @retval  EFI_SUCCESS      The device accepted the configuration in Features.
+
+  @return  EFI_UNSUPPORTED  The device rejected the configuration in Features.
+
+  @retval  EFI_UNSUPPORTED  VirtIo->Revision is smaller than 1.0.0.
+
+  @return                   Error codes from the SetGuestFeatures(),
+                            SetDeviceStatus(), GetDeviceStatus() member
+                            functions.
+
+**/
+EFI_STATUS
+EFIAPI
+Virtio10WriteFeatures (
+  IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,
+  IN     UINT64                 Features,
+  IN OUT UINT8                  *DeviceStatus
+  )
+{
+  EFI_STATUS Status;
+
+  if (VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = VirtIo->SetGuestFeatures (VirtIo, Features);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  *DeviceStatus |= VSTAT_FEATURES_OK;
+  Status = VirtIo->SetDeviceStatus (VirtIo, *DeviceStatus);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = VirtIo->GetDeviceStatus (VirtIo, DeviceStatus);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if ((*DeviceStatus & VSTAT_FEATURES_OK) == 0) {
+    Status = EFI_UNSUPPORTED;
+  }
+
+  return Status;
+}