aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe@linaro.org>2023-06-06 14:04:19 +0100
committerWill Deacon <will@kernel.org>2023-06-08 22:39:03 +0100
commitcf8358d34f3157e1a891ad00a9959870b65a1861 (patch)
treee4b408ed1bd371f0381faac3134efa761591236c
parent13ea439a1f48a19cc31e5c39abb8079aa8deedef (diff)
downloadkvmtool-cf8358d34f3157e1a891ad00a9959870b65a1861.tar.gz
virtio/vsock: Fix feature selection
We should advertise to the guest only the features supported by vhost and kvmtool. Then we should set in vhost only the features acked by the guest. Move vhost feature query to get_host_features(), and vhost feature setting to device start (after the guest has acked features). This fixes vsock because we used to enable all vhost features including VIRTIO_F_ACCESS_PLATFORM, which forces vhost to use vhost-iotlb and isn't supported by kvmtool. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Link: https://lore.kernel.org/r/20230606130426.978945-11-jean-philippe@linaro.org Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--virtio/vsock.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/virtio/vsock.c b/virtio/vsock.c
index 559fbaba..64512713 100644
--- a/virtio/vsock.c
+++ b/virtio/vsock.c
@@ -51,8 +51,17 @@ static size_t get_config_size(struct kvm *kvm, void *dev)
static u64 get_host_features(struct kvm *kvm, void *dev)
{
- return 1UL << VIRTIO_RING_F_EVENT_IDX
- | 1UL << VIRTIO_RING_F_INDIRECT_DESC;
+ int r;
+ u64 features;
+ struct vsock_dev *vdev = dev;
+
+ r = ioctl(vdev->vhost_fd, VHOST_GET_FEATURES, &features);
+ if (r != 0)
+ die_perror("VHOST_GET_FEATURES failed");
+
+ return features &
+ (1ULL << VIRTIO_RING_F_EVENT_IDX |
+ 1ULL << VIRTIO_RING_F_INDIRECT_DESC);
}
static bool is_event_vq(u32 vq)
@@ -95,12 +104,18 @@ static void notify_status(struct kvm *kvm, void *dev, u32 status)
if (status & VIRTIO__STATUS_CONFIG)
vdev->config.guest_cid = cpu_to_le64(vdev->guest_cid);
- if (status & VIRTIO__STATUS_START)
+ if (status & VIRTIO__STATUS_START) {
start = 1;
- else if (status & VIRTIO__STATUS_STOP)
+
+ r = ioctl(vdev->vhost_fd, VHOST_SET_FEATURES,
+ &vdev->vdev.features);
+ if (r != 0)
+ die_perror("VHOST_SET_FEATURES failed");
+ } else if (status & VIRTIO__STATUS_STOP) {
start = 0;
- else
+ } else {
return;
+ }
r = ioctl(vdev->vhost_fd, VHOST_VSOCK_SET_RUNNING, &start);
if (r != 0)
@@ -162,7 +177,6 @@ static struct virtio_ops vsock_dev_virtio_ops = {
static void virtio_vhost_vsock_init(struct kvm *kvm, struct vsock_dev *vdev)
{
- u64 features;
int r;
vdev->vhost_fd = open("/dev/vhost-vsock", O_RDWR);
@@ -171,14 +185,6 @@ static void virtio_vhost_vsock_init(struct kvm *kvm, struct vsock_dev *vdev)
virtio_vhost_init(kvm, vdev->vhost_fd);
- r = ioctl(vdev->vhost_fd, VHOST_GET_FEATURES, &features);
- if (r != 0)
- die_perror("VHOST_GET_FEATURES failed");
-
- r = ioctl(vdev->vhost_fd, VHOST_SET_FEATURES, &features);
- if (r != 0)
- die_perror("VHOST_SET_FEATURES failed");
-
r = ioctl(vdev->vhost_fd, VHOST_VSOCK_SET_GUEST_CID, &vdev->guest_cid);
if (r != 0)
die_perror("VHOST_VSOCK_SET_GUEST_CID failed");