vhost-user-scmi: free vhost virtqueue array on cleanup
vhost-user-scmi allocates vhost_dev.vqs during realize, but the
cleanup helper frees scmi->vhost_dev.vqs after vhost_dev_cleanup() has
cleared struct vhost_dev. This turns the free into g_free(NULL), leaking
the allocated vhost virtqueue array.
Keep a copy of the vhost_dev.vqs pointer across vhost_dev_cleanup() and
free that saved pointer from the common cleanup helper.
Fixes: a5dab090e1 (hw/virtio: Add boilerplate for vhost-user-scmi device)
Signed-off-by: GuoHan Zhao <zhaoguohan@kylinos.cn>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260630072728.3025097-1-zhaoguohan@kylinos.cn>
This commit is contained in:
committed by
Michael S. Tsirkin
parent
a2134e938a
commit
cecd7a11df
@@ -220,11 +220,12 @@ static void vu_scmi_event(void *opaque, QEMUChrEvent event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_vhost_user_cleanup(VirtIODevice *vdev, VHostUserSCMI *scmi)
|
static void do_vhost_user_cleanup(VirtIODevice *vdev, VHostUserSCMI *scmi,
|
||||||
|
struct vhost_virtqueue *vhost_vqs)
|
||||||
{
|
{
|
||||||
virtio_delete_queue(scmi->cmd_vq);
|
virtio_delete_queue(scmi->cmd_vq);
|
||||||
virtio_delete_queue(scmi->event_vq);
|
virtio_delete_queue(scmi->event_vq);
|
||||||
g_free(scmi->vhost_dev.vqs);
|
g_free(vhost_vqs);
|
||||||
virtio_cleanup(vdev);
|
virtio_cleanup(vdev);
|
||||||
vhost_user_cleanup(&scmi->vhost_user);
|
vhost_user_cleanup(&scmi->vhost_user);
|
||||||
}
|
}
|
||||||
@@ -233,6 +234,7 @@ static void vu_scmi_device_realize(DeviceState *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
||||||
VHostUserSCMI *scmi = VHOST_USER_SCMI(dev);
|
VHostUserSCMI *scmi = VHOST_USER_SCMI(dev);
|
||||||
|
struct vhost_virtqueue *vhost_vqs;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!scmi->chardev.chr) {
|
if (!scmi->chardev.chr) {
|
||||||
@@ -252,13 +254,14 @@ static void vu_scmi_device_realize(DeviceState *dev, Error **errp)
|
|||||||
scmi->event_vq = virtio_add_queue(vdev, 256, vu_scmi_handle_output);
|
scmi->event_vq = virtio_add_queue(vdev, 256, vu_scmi_handle_output);
|
||||||
scmi->vhost_dev.nvqs = 2;
|
scmi->vhost_dev.nvqs = 2;
|
||||||
scmi->vhost_dev.vqs = g_new0(struct vhost_virtqueue, scmi->vhost_dev.nvqs);
|
scmi->vhost_dev.vqs = g_new0(struct vhost_virtqueue, scmi->vhost_dev.nvqs);
|
||||||
|
vhost_vqs = scmi->vhost_dev.vqs;
|
||||||
|
|
||||||
ret = vhost_dev_init(&scmi->vhost_dev, &scmi->vhost_user,
|
ret = vhost_dev_init(&scmi->vhost_dev, &scmi->vhost_user,
|
||||||
VHOST_BACKEND_TYPE_USER, 0, errp);
|
VHOST_BACKEND_TYPE_USER, 0, errp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg_errno(errp, -ret,
|
error_setg_errno(errp, -ret,
|
||||||
"vhost-user-scmi: vhost_dev_init() failed");
|
"vhost-user-scmi: vhost_dev_init() failed");
|
||||||
do_vhost_user_cleanup(vdev, scmi);
|
do_vhost_user_cleanup(vdev, scmi, vhost_vqs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,10 +273,11 @@ static void vu_scmi_device_unrealize(DeviceState *dev)
|
|||||||
{
|
{
|
||||||
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
||||||
VHostUserSCMI *scmi = VHOST_USER_SCMI(dev);
|
VHostUserSCMI *scmi = VHOST_USER_SCMI(dev);
|
||||||
|
struct vhost_virtqueue *vhost_vqs = scmi->vhost_dev.vqs;
|
||||||
|
|
||||||
vu_scmi_set_status(vdev, 0);
|
vu_scmi_set_status(vdev, 0);
|
||||||
vhost_dev_cleanup(&scmi->vhost_dev);
|
vhost_dev_cleanup(&scmi->vhost_dev);
|
||||||
do_vhost_user_cleanup(vdev, scmi);
|
do_vhost_user_cleanup(vdev, scmi, vhost_vqs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const VMStateDescription vu_scmi_vmstate = {
|
static const VMStateDescription vu_scmi_vmstate = {
|
||||||
|
|||||||
Reference in New Issue
Block a user