On Wed, Oct 21, 2015 at 11:19:14AM +0200, Thibaut Collet wrote: > When a live migration is started the log address to mark dirty pages is > provided > to the vhost backend through the vhost_dev_set_log function. > This function is called for each queue pairs but the queue index provided to > the > vhost_virtqueue_set_addr function is wrongly set: always set to the first > queue > pair. Then vhost backend lost descriptor addresses of the queue pairs greater > than 1 and behaviour of the vhost backend is unpredictable. > > The vhost_dev_set_log is modified to provide the correct queue index to the > vhost_virtqueue_set_addr function that calls internally the vhost_get_vq_index > to compute the expected vhost_vq_index for vhost kernel and vhost user. > This change implies a modification of the vhost_virtqueue_start function to > provide the index and not the vhost_vq_index. > > Signed-off-by: Thibaut Collet <thibaut.col...@6wind.com>
I applied v1 already, please post a patch on top. > --- > hw/virtio/vhost.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c > index feeaaa4..9311832 100644 > --- a/hw/virtio/vhost.c > +++ b/hw/virtio/vhost.c > @@ -628,8 +628,9 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev, > struct vhost_virtqueue *vq, > unsigned idx, bool enable_log) > { > + int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx); > struct vhost_vring_addr addr = { > - .index = idx, > + .index = vhost_vq_index, > .desc_user_addr = (uint64_t)(unsigned long)vq->desc, > .avail_user_addr = (uint64_t)(unsigned long)vq->avail, > .used_user_addr = (uint64_t)(unsigned long)vq->used, > @@ -662,7 +663,7 @@ static int vhost_dev_set_log(struct vhost_dev *dev, bool > enable_log) > goto err_features; > } > for (i = 0; i < dev->nvqs; ++i) { > - r = vhost_virtqueue_set_addr(dev, dev->vqs + i, i, > + r = vhost_virtqueue_set_addr(dev, dev->vqs + i, dev->vq_index + i, > enable_log); > if (r < 0) { > goto err_vq; > @@ -671,7 +672,7 @@ static int vhost_dev_set_log(struct vhost_dev *dev, bool > enable_log) > return 0; > err_vq: > for (; i >= 0; --i) { > - t = vhost_virtqueue_set_addr(dev, dev->vqs + i, i, > + t = vhost_virtqueue_set_addr(dev, dev->vqs + i, dev->vq_index + i, > dev->log_enabled); > assert(t >= 0); > } > @@ -836,7 +837,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, > goto fail_alloc_ring; > } > > - r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled); > + r = vhost_virtqueue_set_addr(dev, vq, idx, dev->log_enabled); > if (r < 0) { > r = -errno; > goto fail_alloc; > -- > 2.1.4