From: "Denis V. Lunev" <den@openvz.org> mainline inclusion from mainline-v7.3-rc1 commit 29536a923a9412812eb3e378258019b54538a220 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19410 CVE: CVE-2026-90129 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- virtballoon_remove() stops all of the balloon's asynchronous work (the free page reporting worker, the inflate/deflate and stats workers, the OOM notifier and the free page shrinker) before tearing the device down. A following change needs the same teardown from a .shutdown handler, so move it into a virtballoon_quiesce() helper. No functional change. Signed-off-by: Denis V. Lunev <den@openvz.org> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20260624140846.2616797-3-den@openvz.org> Conflicts: drivers/virtio/virtio_balloon.c [This tree carries a vendor-specific memop_work worker, whose cancel_work_sync() is kept inside virtballoon_quiesce().] Signed-off-by: Jiacheng Yu <yujiacheng3@huawei.com> --- drivers/virtio/virtio_balloon.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 8f45ee1c959b..b14fafcf8c6e 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -1214,16 +1214,21 @@ static void remove_common(struct virtio_balloon *vb) vb->vdev->config->del_vqs(vb->vdev); } -static void virtballoon_remove(struct virtio_device *vdev) +/* + * Stop all asynchronous balloon work. The device must still be alive so that + * in-flight requests can drain via the host before it is reset or freed. + */ +static void virtballoon_quiesce(struct virtio_balloon *vb) { - struct virtio_balloon *vb = vdev->priv; + struct virtio_device *vdev = vb->vdev; - if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_REPORTING)) + if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_REPORTING)) page_reporting_unregister(&vb->pr_dev_info); - if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) + if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) unregister_oom_notifier(&vb->oom_nb); - if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) + if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) virtio_balloon_unregister_shrinker(vb); + spin_lock_irq(&vb->stop_update_lock); vb->stop_update = true; spin_unlock_irq(&vb->stop_update_lock); @@ -1233,10 +1238,18 @@ static void virtballoon_remove(struct virtio_device *vdev) cancel_work_sync(&vb->memop_work); #endif - if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { + if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) cancel_work_sync(&vb->report_free_page_work); +} + +static void virtballoon_remove(struct virtio_device *vdev) +{ + struct virtio_balloon *vb = vdev->priv; + + virtballoon_quiesce(vb); + + if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) destroy_workqueue(vb->balloon_wq); - } remove_common(vb); kfree(vb); -- 2.34.1