diff options
author | Jean-Philippe Brucker <jean-philippe@linaro.org> | 2023-06-06 14:04:20 +0100 |
---|---|---|
committer | Will Deacon <will@kernel.org> | 2023-06-08 22:39:03 +0100 |
commit | 53171d59b081aa7176b1fab2e78ba61fb54c8ab3 (patch) | |
tree | 489895d4e07e96200b84e7486e5c0ce01903cea9 | |
parent | cf8358d34f3157e1a891ad00a9959870b65a1861 (diff) | |
download | kvmtool-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.c | 22 |
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); } |