From d0ece0d85050022f96f31291e2f0033ebcdb3c6f Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Sat, 12 Mar 2016 20:37:42 +0100 Subject: OvmfPkg: VirtioLib: add Virtio10WriteFeatures() function 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 Cc: Jordan Justen Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Tested-by: Ard Biesheuvel Reviewed-by: Jordan Justen --- OvmfPkg/Include/Library/VirtioLib.h | 46 +++++++++++++++++++++ OvmfPkg/Library/VirtioLib/VirtioLib.c | 75 +++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h index decd4418af..5badfb3291 100644 --- a/OvmfPkg/Include/Library/VirtioLib.h +++ b/OvmfPkg/Include/Library/VirtioLib.h @@ -189,4 +189,50 @@ VirtioFlush ( 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 4b1d78b5a0..845f206369 100644 --- a/OvmfPkg/Library/VirtioLib/VirtioLib.c +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c @@ -339,3 +339,78 @@ VirtioFlush ( 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; +} -- cgit v1.2.3