From cecd7a11df7b7fdfccc60fe50cc78e75635db886 Mon Sep 17 00:00:00 2001 From: GuoHan Zhao Date: Tue, 30 Jun 2026 15:27:28 +0800 Subject: [PATCH] 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: a5dab090e142 (hw/virtio: Add boilerplate for vhost-user-scmi device) Signed-off-by: GuoHan Zhao Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Message-ID: <20260630072728.3025097-1-zhaoguohan@kylinos.cn> --- hw/virtio/vhost-user-scmi.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hw/virtio/vhost-user-scmi.c b/hw/virtio/vhost-user-scmi.c index 9470f68c1f..02dc088ea9 100644 --- a/hw/virtio/vhost-user-scmi.c +++ b/hw/virtio/vhost-user-scmi.c @@ -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->event_vq); - g_free(scmi->vhost_dev.vqs); + g_free(vhost_vqs); virtio_cleanup(vdev); 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); VHostUserSCMI *scmi = VHOST_USER_SCMI(dev); + struct vhost_virtqueue *vhost_vqs; int ret; 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->vhost_dev.nvqs = 2; 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, VHOST_BACKEND_TYPE_USER, 0, errp); if (ret < 0) { error_setg_errno(errp, -ret, "vhost-user-scmi: vhost_dev_init() failed"); - do_vhost_user_cleanup(vdev, scmi); + do_vhost_user_cleanup(vdev, scmi, vhost_vqs); return; } @@ -270,10 +273,11 @@ static void vu_scmi_device_unrealize(DeviceState *dev) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); VHostUserSCMI *scmi = VHOST_USER_SCMI(dev); + struct vhost_virtqueue *vhost_vqs = scmi->vhost_dev.vqs; vu_scmi_set_status(vdev, 0); 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 = {