diff mbox

[edk2,wave,3,v2,01/17] OvmfPkg: VIRTIO_DEVICE_PROTOCOL: widen the Features bitmap to 64 bits

Message ID 1459946427-15771-2-git-send-email-lersek@redhat.com
State New
Headers show

Commit Message

Laszlo Ersek April 6, 2016, 12:40 p.m. UTC
The virtio-1.0 spec widens the Features bitmap to 64 bits. Modify the
declarations of the GetDeviceFeatures() and SetGuestFeatures() protocol
member functions accordingly.

Normally, a protocol cannot be changed in incompatible ways if the GUID
stays the same; however, we've always been extremely clear that
VIRTIO_DEVICE_PROTOCOL is internal to edk2. See for example the top of
"OvmfPkg/Include/Protocol/VirtioDevice.h".

In this patch, all producers and consumers of the GetDeviceFeatures() and
SetGuestFeatures() protocol members are updated.

The drivers that currently produce these members are "legacy" drivers (in
virtio-1.0 terminology), and they cannot (and will not) handle feature
bits above BIT31. Therefore their conversion is only for compatibility
with the modified protocol interface. The consumers will be responsible
for checking the VIRTIO_DEVICE_PROTOCOL.Revision field, and for not
passing feature bits that these backends cannot handle.

The VirtioMmioGetDeviceFeatures() implementation stores the result of an
MmioRead32() call with normal assignment, so it needs no change beyond
adapting its prototype.

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>

Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

---
 OvmfPkg/Include/Protocol/VirtioDevice.h                         |  8 ++++----
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h          |  4 ++--
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h                    |  4 ++--
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c | 10 +++++++---
 OvmfPkg/VirtioBlkDxe/VirtioBlk.c                                |  2 +-
 OvmfPkg/VirtioNetDxe/DriverBinding.c                            |  2 +-
 OvmfPkg/VirtioNetDxe/SnpInitialize.c                            |  2 +-
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c                 | 17 +++++++++++++----
 OvmfPkg/VirtioRngDxe/VirtioRng.c                                |  2 +-
 OvmfPkg/VirtioScsiDxe/VirtioScsi.c                              |  2 +-
 10 files changed, 33 insertions(+), 20 deletions(-)

-- 
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/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h
index 48fca2e14c25..15750f450cb2 100644
--- a/OvmfPkg/Include/Protocol/VirtioDevice.h
+++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
@@ -93,41 +93,41 @@  EFI_STATUS
   );
 
 /**
   Read the device features field from the Virtio Header.
 
   @param[in] This                 This instance of VIRTIO_DEVICE_PROTOCOL
 
-  @param[out] DeviceFeatures      The 32-bit device features field.
+  @param[out] DeviceFeatures      The device features field.
 
   @retval EFI_SUCCESS             The data was read successfully.
   @retval EFI_UNSUPPORTED         The underlying IO device doesn't support the
                                   provided address offset and read size.
   @retval EFI_INVALID_PARAMETER   DeviceFeatures is NULL
 **/
 typedef
 EFI_STATUS
 (EFIAPI *VIRTIO_GET_DEVICE_FEATURES) (
   IN VIRTIO_DEVICE_PROTOCOL *This,
-  OUT UINT32                *DeviceFeatures
+  OUT UINT64                *DeviceFeatures
   );
 
 /**
   Write the guest features field in the Virtio Header.
 
   @param[in] This         This instance of VIRTIO_DEVICE_PROTOCOL
 
-  @param[in] Features     The 32-bit guest guest features field
+  @param[in] Features     The guest features field
 
 **/
 typedef
 EFI_STATUS
 (EFIAPI *VIRTIO_SET_GUEST_FEATURES) (
   IN VIRTIO_DEVICE_PROTOCOL  *This,
-  IN UINT32                   Features
+  IN UINT64                   Features
   );
 
 /**
   Read the queue address field from the Virtio Header.
 
   QueueAddress is the address of the virtqueue divided by 4096.
 
diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
index 3e4e5606ccad..d445c3dc197d 100644
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h
@@ -61,15 +61,15 @@  VirtioMmioDeviceWrite (
   IN  UINT64                    Value
   );
 
 EFI_STATUS
 EFIAPI
 VirtioMmioGetDeviceFeatures (
   IN VIRTIO_DEVICE_PROTOCOL *This,
-  OUT UINT32                *DeviceFeatures
+  OUT UINT64                *DeviceFeatures
   );
 
 EFI_STATUS
 EFIAPI
 VirtioMmioGetQueueAddress (
   IN  VIRTIO_DEVICE_PROTOCOL *This,
   OUT UINT32                 *QueueAddress
@@ -137,11 +137,11 @@  VirtioMmioSetPageSize (
   UINT32                  PageSize
   );
 
 EFI_STATUS
 EFIAPI
 VirtioMmioSetGuestFeatures (
   VIRTIO_DEVICE_PROTOCOL *This,
-  UINT32                  Features
+  UINT64                  Features
   );
 
 #endif // _VIRTIO_MMIO_DEVICE_INTERNAL_H_
diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
index 6311ae849d18..812061dc0c25 100644
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h
@@ -79,15 +79,15 @@  VirtioPciDeviceWrite (
   IN UINT64                      Value
   );
 
 EFI_STATUS
 EFIAPI
 VirtioPciGetDeviceFeatures (
   IN VIRTIO_DEVICE_PROTOCOL *This,
-  OUT UINT32                *DeviceFeatures
+  OUT UINT64                *DeviceFeatures
   );
 
 EFI_STATUS
 EFIAPI
 VirtioPciGetQueueAddress (
   IN  VIRTIO_DEVICE_PROTOCOL *This,
   OUT UINT32                 *QueueAddress
@@ -121,15 +121,15 @@  VirtioPciGetDeviceStatus (
   OUT UINT8                   *DeviceStatus
   );
 
 EFI_STATUS
 EFIAPI
 VirtioPciSetGuestFeatures (
   IN VIRTIO_DEVICE_PROTOCOL  *This,
-  IN UINT32                   Features
+  IN UINT64                   Features
   );
 
 EFI_STATUS
 EFIAPI
 VirtioPciSetQueueAddress (
   VIRTIO_DEVICE_PROTOCOL         *This,
   UINT32                         Address
diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
index 3950c07f7f5d..4b7d29328362 100644
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
@@ -18,15 +18,15 @@ 
 
 #include "VirtioMmioDevice.h"
 
 EFI_STATUS
 EFIAPI
 VirtioMmioGetDeviceFeatures (
   IN VIRTIO_DEVICE_PROTOCOL *This,
-  OUT UINT32                *DeviceFeatures
+  OUT UINT64                *DeviceFeatures
   )
 {
   VIRTIO_MMIO_DEVICE *Device;
 
   if (DeviceFeatures == NULL) {
     return EFI_INVALID_PARAMETER;
   }
@@ -213,22 +213,26 @@  VirtioMmioSetQueueAddress (
   return EFI_SUCCESS;
 }
 
 EFI_STATUS
 EFIAPI
 VirtioMmioSetGuestFeatures (
   VIRTIO_DEVICE_PROTOCOL *This,
-  UINT32                  Features
+  UINT64                  Features
   )
 {
   VIRTIO_MMIO_DEVICE *Device;
 
   Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
 
-  VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES, Features);
+  if (Features > MAX_UINT32) {
+    return EFI_UNSUPPORTED;
+  }
+  VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES,
+    (UINT32)Features);
 
   return EFI_SUCCESS;
 }
 
 EFI_STATUS
 EFIAPI
 VirtioMmioDeviceWrite (
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index 50511a1e446b..b35f60c9d233 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -589,15 +589,15 @@  EFIAPI
 VirtioBlkInit (
   IN OUT VBLK_DEV *Dev
   )
 {
   UINT8      NextDevStat;
   EFI_STATUS Status;
 
-  UINT32     Features;
+  UINT64     Features;
   UINT64     NumSectors;
   UINT32     BlockSize;
   UINT8      PhysicalBlockExp;
   UINT8      AlignmentOffset;
   UINT32     OptIoSize;
   UINT16     QueueSize;
 
diff --git a/OvmfPkg/VirtioNetDxe/DriverBinding.c b/OvmfPkg/VirtioNetDxe/DriverBinding.c
index 0ad39cf9729c..bcf9ebbdadbd 100644
--- a/OvmfPkg/VirtioNetDxe/DriverBinding.c
+++ b/OvmfPkg/VirtioNetDxe/DriverBinding.c
@@ -60,15 +60,15 @@  VirtioNetGetFeatures (
   OUT     EFI_MAC_ADDRESS *MacAddress,
   OUT     BOOLEAN         *MediaPresentSupported,
   OUT     BOOLEAN         *MediaPresent
   )
 {
   EFI_STATUS Status;
   UINT8      NextDevStat;
-  UINT32     Features;
+  UINT64     Features;
   UINTN      MacIdx;
   UINT16     LinkStatus;
 
   //
   // Interrogate the device for features (virtio-0.9.5, 2.2.1 Device
   // Initialization Sequence), but don't complete setting it up.
   //
diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
index 223030af9e5d..71b67fa52df9 100644
--- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c
+++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
@@ -356,15 +356,15 @@  VirtioNetInitialize (
   IN UINTN                       ExtraTxBufferSize  OPTIONAL
   )
 {
   VNET_DEV   *Dev;
   EFI_TPL    OldTpl;
   EFI_STATUS Status;
   UINT8      NextDevStat;
-  UINT32     Features;
+  UINT64     Features;
 
   if (This == NULL) {
     return EFI_INVALID_PARAMETER;
   }
   if (ExtraRxBufferSize > 0 || ExtraTxBufferSize > 0) {
     return EFI_UNSUPPORTED;
   }
diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
index 9c40fd94a6e8..d8d30f9af63d 100644
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
@@ -97,27 +97,33 @@  VirtioPciDeviceWrite (
       Dev->DeviceSpecificConfigurationOffset + FieldOffset, FieldSize, Value);
 }
 
 EFI_STATUS
 EFIAPI
 VirtioPciGetDeviceFeatures (
   IN VIRTIO_DEVICE_PROTOCOL *This,
-  OUT UINT32                *DeviceFeatures
+  OUT UINT64                *DeviceFeatures
   )
 {
   VIRTIO_PCI_DEVICE         *Dev;
+  EFI_STATUS                Status;
+  UINT32                    Features32;
 
   if (DeviceFeatures == NULL) {
     return EFI_INVALID_PARAMETER;
   }
 
   Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
 
-  return VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_DEVICE_FEATURES, sizeof (UINT32),
-      sizeof (UINT32), DeviceFeatures);
+  Status = VirtioPciIoRead (Dev, VIRTIO_PCI_OFFSET_DEVICE_FEATURES,
+             sizeof (UINT32), sizeof (UINT32), &Features32);
+  if (!EFI_ERROR (Status)) {
+    *DeviceFeatures = Features32;
+  }
+  return Status;
 }
 
 EFI_STATUS
 EFIAPI
 VirtioPciGetQueueAddress (
   IN  VIRTIO_DEVICE_PROTOCOL *This,
   OUT UINT32                 *QueueAddress
@@ -173,21 +179,24 @@  VirtioPciGetDeviceStatus (
       sizeof (UINT8), sizeof (UINT8), DeviceStatus);
 }
 
 EFI_STATUS
 EFIAPI
 VirtioPciSetGuestFeatures (
   IN VIRTIO_DEVICE_PROTOCOL  *This,
-  IN UINT32                   Features
+  IN UINT64                   Features
   )
 {
   VIRTIO_PCI_DEVICE *Dev;
 
   Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
 
+  if (Features > MAX_UINT32) {
+    return EFI_UNSUPPORTED;
+  }
   return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_GUEST_FEATURES,
       sizeof (UINT32), Features);
 }
 
 EFI_STATUS
 EFIAPI
 VirtioPciSetQueueAddress (
diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c b/OvmfPkg/VirtioRngDxe/VirtioRng.c
index 8eb1aa300b50..de4afefe7000 100644
--- a/OvmfPkg/VirtioRngDxe/VirtioRng.c
+++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
@@ -199,15 +199,15 @@  EFIAPI
 VirtioRngInit (
   IN OUT VIRTIO_RNG_DEV *Dev
   )
 {
   UINT8      NextDevStat;
   EFI_STATUS Status;
   UINT16     QueueSize;
-  UINT32     Features;
+  UINT64     Features;
 
   //
   // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
   //
   NextDevStat = 0;             // step 1 -- reset device
   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
   if (EFI_ERROR (Status)) {
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
index f5f412a32e9b..52952886226b 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
@@ -703,15 +703,15 @@  EFIAPI
 VirtioScsiInit (
   IN OUT VSCSI_DEV *Dev
   )
 {
   UINT8      NextDevStat;
   EFI_STATUS Status;
 
-  UINT32     Features;
+  UINT64     Features;
   UINT16     MaxChannel; // for validation only
   UINT32     NumQueues;  // for validation only
   UINT16     QueueSize;
 
   //
   // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
   //