mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-06 17:35:20 +02:00
vhost_vdpa: assign irq bypass producer token correctly
[ Upstream commit02e9e9366f
] We used to call irq_bypass_unregister_producer() in vhost_vdpa_setup_vq_irq() which is problematic as we don't know if the token pointer is still valid or not. Actually, we use the eventfd_ctx as the token so the life cycle of the token should be bound to the VHOST_SET_VRING_CALL instead of vhost_vdpa_setup_vq_irq() which could be called by set_status(). Fixing this by setting up irq bypass producer's token when handling VHOST_SET_VRING_CALL and un-registering the producer before calling vhost_vring_ioctl() to prevent a possible use after free as eventfd could have been released in vhost_vring_ioctl(). And such registering and unregistering will only be done if DRIVER_OK is set. Reported-by: Dragos Tatulea <dtatulea@nvidia.com> Tested-by: Dragos Tatulea <dtatulea@nvidia.com> Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com> Fixes:2cf1ba9a4d
("vhost_vdpa: implement IRQ offloading in vhost_vdpa") Signed-off-by: Jason Wang <jasowang@redhat.com> Message-Id: <20240816031900.18013-1-jasowang@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
70a180b8d8
commit
ca64edd7ae
|
@ -191,11 +191,9 @@ static void vhost_vdpa_setup_vq_irq(struct vhost_vdpa *v, u16 qid)
|
||||||
if (irq < 0)
|
if (irq < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
irq_bypass_unregister_producer(&vq->call_ctx.producer);
|
|
||||||
if (!vq->call_ctx.ctx)
|
if (!vq->call_ctx.ctx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vq->call_ctx.producer.token = vq->call_ctx.ctx;
|
|
||||||
vq->call_ctx.producer.irq = irq;
|
vq->call_ctx.producer.irq = irq;
|
||||||
ret = irq_bypass_register_producer(&vq->call_ctx.producer);
|
ret = irq_bypass_register_producer(&vq->call_ctx.producer);
|
||||||
if (unlikely(ret))
|
if (unlikely(ret))
|
||||||
|
@ -627,6 +625,14 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
|
||||||
vq->last_avail_idx = vq_state.split.avail_index;
|
vq->last_avail_idx = vq_state.split.avail_index;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case VHOST_SET_VRING_CALL:
|
||||||
|
if (vq->call_ctx.ctx) {
|
||||||
|
if (ops->get_status(vdpa) &
|
||||||
|
VIRTIO_CONFIG_S_DRIVER_OK)
|
||||||
|
vhost_vdpa_unsetup_vq_irq(v, idx);
|
||||||
|
vq->call_ctx.producer.token = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = vhost_vring_ioctl(&v->vdev, cmd, argp);
|
r = vhost_vring_ioctl(&v->vdev, cmd, argp);
|
||||||
|
@ -659,13 +665,16 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
|
||||||
cb.callback = vhost_vdpa_virtqueue_cb;
|
cb.callback = vhost_vdpa_virtqueue_cb;
|
||||||
cb.private = vq;
|
cb.private = vq;
|
||||||
cb.trigger = vq->call_ctx.ctx;
|
cb.trigger = vq->call_ctx.ctx;
|
||||||
|
vq->call_ctx.producer.token = vq->call_ctx.ctx;
|
||||||
|
if (ops->get_status(vdpa) &
|
||||||
|
VIRTIO_CONFIG_S_DRIVER_OK)
|
||||||
|
vhost_vdpa_setup_vq_irq(v, idx);
|
||||||
} else {
|
} else {
|
||||||
cb.callback = NULL;
|
cb.callback = NULL;
|
||||||
cb.private = NULL;
|
cb.private = NULL;
|
||||||
cb.trigger = NULL;
|
cb.trigger = NULL;
|
||||||
}
|
}
|
||||||
ops->set_vq_cb(vdpa, idx, &cb);
|
ops->set_vq_cb(vdpa, idx, &cb);
|
||||||
vhost_vdpa_setup_vq_irq(v, idx);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VHOST_SET_VRING_NUM:
|
case VHOST_SET_VRING_NUM:
|
||||||
|
@ -1316,6 +1325,7 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
|
||||||
for (i = 0; i < nvqs; i++) {
|
for (i = 0; i < nvqs; i++) {
|
||||||
vqs[i] = &v->vqs[i];
|
vqs[i] = &v->vqs[i];
|
||||||
vqs[i]->handle_kick = handle_vq_kick;
|
vqs[i]->handle_kick = handle_vq_kick;
|
||||||
|
vqs[i]->call_ctx.ctx = NULL;
|
||||||
}
|
}
|
||||||
vhost_dev_init(dev, vqs, nvqs, 0, 0, 0, false,
|
vhost_dev_init(dev, vqs, nvqs, 0, 0, 0, false,
|
||||||
vhost_vdpa_process_iotlb_msg);
|
vhost_vdpa_process_iotlb_msg);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user