Commit f59281da authored by Jason Wang's avatar Jason Wang Committed by Michael S. Tsirkin

vhost: init used ring after backend was set

Move the used ring initialization after backend was set. This
makes it possible to disable the backend and tweak the used ring,
then restart. This will also make it possible to log the used ring
write correctly.
Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 81fc70d8
...@@ -703,6 +703,10 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) ...@@ -703,6 +703,10 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
vhost_net_disable_vq(n, vq); vhost_net_disable_vq(n, vq);
rcu_assign_pointer(vq->private_data, sock); rcu_assign_pointer(vq->private_data, sock);
vhost_net_enable_vq(n, vq); vhost_net_enable_vq(n, vq);
r = vhost_init_used(vq);
if (r)
goto err_vq;
} }
mutex_unlock(&vq->mutex); mutex_unlock(&vq->mutex);
......
...@@ -195,8 +195,13 @@ static long vhost_test_run(struct vhost_test *n, int test) ...@@ -195,8 +195,13 @@ static long vhost_test_run(struct vhost_test *n, int test)
lockdep_is_held(&vq->mutex)); lockdep_is_held(&vq->mutex));
rcu_assign_pointer(vq->private_data, priv); rcu_assign_pointer(vq->private_data, priv);
r = vhost_init_used(&n->vqs[index]);
mutex_unlock(&vq->mutex); mutex_unlock(&vq->mutex);
if (r)
goto err;
if (oldpriv) { if (oldpriv) {
vhost_test_flush_vq(n, index); vhost_test_flush_vq(n, index);
} }
......
...@@ -629,15 +629,17 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) ...@@ -629,15 +629,17 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
return 0; return 0;
} }
static int init_used(struct vhost_virtqueue *vq, int vhost_init_used(struct vhost_virtqueue *vq)
struct vring_used __user *used)
{ {
int r = put_user(vq->used_flags, &used->flags); int r;
if (!vq->private_data)
return 0;
r = put_user(vq->used_flags, &vq->used->flags);
if (r) if (r)
return r; return r;
vq->signalled_used_valid = false; vq->signalled_used_valid = false;
return get_user(vq->last_used_idx, &used->idx); return get_user(vq->last_used_idx, &vq->used->idx);
} }
static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
...@@ -752,10 +754,6 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) ...@@ -752,10 +754,6 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
} }
} }
r = init_used(vq, (struct vring_used __user *)(unsigned long)
a.used_user_addr);
if (r)
break;
vq->log_used = !!(a.flags & (0x1 << VHOST_VRING_F_LOG)); vq->log_used = !!(a.flags & (0x1 << VHOST_VRING_F_LOG));
vq->desc = (void __user *)(unsigned long)a.desc_user_addr; vq->desc = (void __user *)(unsigned long)a.desc_user_addr;
vq->avail = (void __user *)(unsigned long)a.avail_user_addr; vq->avail = (void __user *)(unsigned long)a.avail_user_addr;
......
...@@ -174,6 +174,7 @@ int vhost_get_vq_desc(struct vhost_dev *, struct vhost_virtqueue *, ...@@ -174,6 +174,7 @@ int vhost_get_vq_desc(struct vhost_dev *, struct vhost_virtqueue *,
struct vhost_log *log, unsigned int *log_num); struct vhost_log *log, unsigned int *log_num);
void vhost_discard_vq_desc(struct vhost_virtqueue *, int n); void vhost_discard_vq_desc(struct vhost_virtqueue *, int n);
int vhost_init_used(struct vhost_virtqueue *);
int vhost_add_used(struct vhost_virtqueue *, unsigned int head, int len); int vhost_add_used(struct vhost_virtqueue *, unsigned int head, int len);
int vhost_add_used_n(struct vhost_virtqueue *, struct vring_used_elem *heads, int vhost_add_used_n(struct vhost_virtqueue *, struct vring_used_elem *heads,
unsigned count); unsigned count);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment