aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe@linaro.org>2023-06-06 14:04:20 +0100
committerWill Deacon <will@kernel.org>2023-06-08 22:39:03 +0100
commit53171d59b081aa7176b1fab2e78ba61fb54c8ab3 (patch)
tree489895d4e07e96200b84e7486e5c0ce01903cea9
parentcf8358d34f3157e1a891ad00a9959870b65a1861 (diff)
downloadkvmtool-53171d59b081aa7176b1fab2e78ba61fb54c8ab3.tar.gz
virtio/net: Fix feature selection
Move VHOST_GET_FEATURES to get_host_features() so the guest is aware of what will actually be supported. This removes the invalid guess about VIRTIO_NET_F_MRG_RXBUF (if vhost didn't support it, we shouldn't let the guest negotiate it). Note the masking of VHOST_NET_F_VIRTIO_NET_HDR when handing features to vhost. Unfortunately the vhost-net driver interprets VIRTIO_F_ANY_LAYOUT as VHOST_NET_F_VIRTIO_NET_HDR, which is specific to vhost and forces vhost-net to supply the vnet header. Since this is done by tap, we don't want to set the bit. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Link: https://lore.kernel.org/r/20230606130426.978945-12-jean-philippe@linaro.org Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--virtio/net.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/virtio/net.c b/virtio/net.c
index 3e1aedf7..c4d20f22 100644
--- a/virtio/net.c
+++ b/virtio/net.c
@@ -505,21 +505,23 @@ static u64 get_host_features(struct kvm *kvm, void *dev)
features |= (1UL << VIRTIO_NET_F_HOST_UFO
| 1UL << VIRTIO_NET_F_GUEST_UFO);
+ if (ndev->vhost_fd) {
+ u64 vhost_features;
+
+ if (ioctl(ndev->vhost_fd, VHOST_GET_FEATURES, &vhost_features) != 0)
+ die_perror("VHOST_GET_FEATURES failed");
+
+ features &= vhost_features;
+ }
+
return features;
}
static int virtio_net__vhost_set_features(struct net_dev *ndev)
{
- u64 features = 1UL << VIRTIO_RING_F_EVENT_IDX;
- u64 vhost_features;
-
- if (ioctl(ndev->vhost_fd, VHOST_GET_FEATURES, &vhost_features) != 0)
- die_perror("VHOST_GET_FEATURES failed");
-
- /* make sure both side support mergable rx buffers */
- if (vhost_features & 1UL << VIRTIO_NET_F_MRG_RXBUF &&
- has_virtio_feature(ndev, VIRTIO_NET_F_MRG_RXBUF))
- features |= 1UL << VIRTIO_NET_F_MRG_RXBUF;
+ /* VHOST_NET_F_VIRTIO_NET_HDR clashes with VIRTIO_F_ANY_LAYOUT! */
+ u64 features = ndev->vdev.features &
+ ~(1UL << VHOST_NET_F_VIRTIO_NET_HDR);
return ioctl(ndev->vhost_fd, VHOST_SET_FEATURES, &features);
}