summaryrefslogtreecommitdiff
path: root/drivers/virtio/virtio_pci_modern.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/virtio/virtio_pci_modern.c')
-rw-r--r--drivers/virtio/virtio_pci_modern.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index d50fe030d825..dd0e65f71d41 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -22,11 +22,11 @@
#define VIRTIO_AVQ_SGS_MAX 4
-static u64 vp_get_features(struct virtio_device *vdev)
+static void vp_get_features(struct virtio_device *vdev, u64 *features)
{
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
- return vp_modern_get_features(&vp_dev->mdev);
+ vp_modern_get_extended_features(&vp_dev->mdev, features);
}
static int vp_avq_index(struct virtio_device *vdev, u16 *index, u16 *num)
@@ -48,6 +48,7 @@ void vp_modern_avq_done(struct virtqueue *vq)
{
struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
struct virtio_pci_admin_vq *admin_vq = &vp_dev->admin_vq;
+ unsigned int status_size = sizeof(struct virtio_admin_cmd_status);
struct virtio_admin_cmd *cmd;
unsigned long flags;
unsigned int len;
@@ -56,7 +57,17 @@ void vp_modern_avq_done(struct virtqueue *vq)
do {
virtqueue_disable_cb(vq);
while ((cmd = virtqueue_get_buf(vq, &len))) {
- cmd->result_sg_size = len;
+ /* If the number of bytes written by the device is less
+ * than the size of struct virtio_admin_cmd_status, the
+ * remaining status bytes will remain zero-initialized,
+ * since the buffer was zeroed during allocation.
+ * In this case, set the size of command_specific_result
+ * to 0.
+ */
+ if (len < status_size)
+ cmd->result_sg_size = 0;
+ else
+ cmd->result_sg_size = len - status_size;
complete(&cmd->completion);
}
} while (!virtqueue_enable_cb(vq));
@@ -426,7 +437,7 @@ static int vp_finalize_features(struct virtio_device *vdev)
if (vp_check_common_size(vdev))
return -EINVAL;
- vp_modern_set_features(&vp_dev->mdev, vdev->features);
+ vp_modern_set_extended_features(&vp_dev->mdev, vdev->features_array);
return 0;
}
@@ -1223,7 +1234,7 @@ static const struct virtio_config_ops virtio_pci_config_nodev_ops = {
.find_vqs = vp_modern_find_vqs,
.del_vqs = vp_del_vqs,
.synchronize_cbs = vp_synchronize_vectors,
- .get_features = vp_get_features,
+ .get_extended_features = vp_get_features,
.finalize_features = vp_finalize_features,
.bus_name = vp_bus_name,
.set_vq_affinity = vp_set_vq_affinity,
@@ -1243,7 +1254,7 @@ static const struct virtio_config_ops virtio_pci_config_ops = {
.find_vqs = vp_modern_find_vqs,
.del_vqs = vp_del_vqs,
.synchronize_cbs = vp_synchronize_vectors,
- .get_features = vp_get_features,
+ .get_extended_features = vp_get_features,
.finalize_features = vp_finalize_features,
.bus_name = vp_bus_name,
.set_vq_affinity = vp_set_vq_affinity,