From nobody Sat Jul 25 06:37:46 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1784807968; cv=none; d=zohomail.com; s=zohoarc; b=nck/LkxEMg6vMZVP9x1SGul8mkHYPq3F0q6UG9j3om3hYbiuh3qevAJR5hlA0Me8rcD2eTU26CpyiIYaiVGfk2diIQDvoBuaWJ7S+ZFG9MY76U84JLwo738bfIwjaOT1AFZzyfwQ+JtRPDF9xQwgqfoqn+ToPvCG4W67QNj/C6o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784807968; h=Content-Type:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=k3hR2LKB54KqVvBl0oK91dbaFADAaXEYoFZ/tG2rZFM=; b=IzLom76J8t9vDbFPjW51Mb1koKWMdfV/9hSta7FVRKuXbAqZ+mWj4QM8EoBeT9sPVzIh8y1LcNlxSQkkdSYfHXae+G7D5oiB/3FONeO28aQTUyOgh6hRg10rXcbAXeFyYrvn0kNt9o6j6lhgF6H0S9EbKkPMEji/3eVVNQ1kVLY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1784807968488917.0168021988028; Thu, 23 Jul 2026 04:59:28 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wms4r-0003ND-Or; Thu, 23 Jul 2026 07:59:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wms4n-0003Me-U1 for qemu-devel@nongnu.org; Thu, 23 Jul 2026 07:58:58 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wms4l-0002F9-GC for qemu-devel@nongnu.org; Thu, 23 Jul 2026 07:58:57 -0400 Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-670-pgTA8m24OiSVahpK2mMM0w-1; Thu, 23 Jul 2026 07:58:48 -0400 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-4955edc851aso3699285e9.2 for ; Thu, 23 Jul 2026 04:58:48 -0700 (PDT) Received: from redhat.com (IGLD-80-230-37-66.inter.net.il. [80.230.37.66]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47f85c531afsm14445673f8f.24.2026.07.23.04.58.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jul 2026 04:58:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1784807933; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type; bh=k3hR2LKB54KqVvBl0oK91dbaFADAaXEYoFZ/tG2rZFM=; b=D/pp9VowPp/c7Zm84ikI9Bvyou1wlqj9/hu+7tmxTuc2M55UsRTnkrjaAO/GRqkQEuwAnd SqsbHDM/ltFHvXiFcMEkXrmLlKise/ZqNgieLS5sJ15MJLo2x3YIwbqC0zZ1MPl9Zr7l1u nQ8x7SL6rjgRbyoUe7YbZAt/TqeDAQ8= X-MC-Unique: pgTA8m24OiSVahpK2mMM0w-1 X-Mimecast-MFC-AGG-ID: pgTA8m24OiSVahpK2mMM0w_1784807927 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1784807927; x=1785412727; darn=nongnu.org; h=content-disposition:content-type:mime-version:message-id:subject:cc :to:from:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=k3hR2LKB54KqVvBl0oK91dbaFADAaXEYoFZ/tG2rZFM=; b=MceKa0flfiC8sGKtR9G0W7X8FQF7Rluqj/NzHwlbvcYc0leW6bmg+ZfCX9rD6RqTwD LgXgMQIziAKjsroT9cD0HWBiLw6A5+khZRHONmu162FsmSTYR+AD+SnY3NE9ngf2MJrF UnYGJaFUMqSi623Xp3CJOoFQl8o3tJ4SEhaf27f0JScE0wDanA/osBSBf8xFsqnGGdUL Y5xubZ/3X7x38yyGaNIFYPdlRf8GQMH4l4VDiRKwscLjVbU+DxgToFjJaibABJgZDTs6 wr8ttd77dp97lxoLkPbNYMWnMjfYFJdvi3bu6qZlTeQwSPZHQG3LbEbqbFFJeeOkapoC oOrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784807927; x=1785412727; h=content-disposition:content-type:mime-version:message-id:subject:cc :to:from:date:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=k3hR2LKB54KqVvBl0oK91dbaFADAaXEYoFZ/tG2rZFM=; b=Rag9YME6YjDFPUPtMWZFHS1hO8GxWzUEg+ght5bRqqSf2ckjZ9LmTXBmYA/qqRFlEZ yvSMl79IxCOb64994l2Rx17SjWwlOgcoP9x8SjupN9Lyj3hidGr7mBRmjKvpLPj9gGMz HIH7i3/zVRFk/pL7o/r8qjpR4AxgPRuz/Nv21dN/ufywxmV15DnW0hRJ7gYH/DFvMP40 xOXqv3ED9ojzxlp+Ll1AlAH87elM31OV8rmLH4LJIcTQWrmK4qqHoA8DfojkT8TE88ND zhFkDnTQAnAVLeLDuvCZsGC7jC6RfHpBk+aBoDyfigVqOcayaAT1W9t48rzWA7nVH7iq l5iA== X-Gm-Message-State: AOJu0YzScDuBs1+qH6n67gFe3KM3KCi1Mcqdmm2jiNnZ3jzTzcRrMHpZ dUQ8Q75oPKEqVF6lO0x2WtKYhXWZh3mVOaUqftUpizaPXNTGzD/kTsWzP6nvgAEEHstSRsZqzdi GQgizYTlvyaezjzLC7JWkKmS+r2LmzVn1jzTA1iFICXrcKxU78FBgnd2M/UfKvhqImm05WCwlsu Hcrk0uHPBSR3DVodCsfZUQU42lf3qv7sQDkQ== X-Gm-Gg: AR+sD12EsXbMQlFLkP4L3z0dpw7mIgs47txC2YdIbdgk/eslOc/2PHczfzhksHYIwTg GyTMS+G881xNBwxFOeocb+5wZXAHPBn4FRJpVf7CYZ8iWroK408qQpEbVJnsWl7hBH750oQkq5I fL6qMJX6rfHn8ZOkFdMAKeUeiITudHeqvH9Yl9YPw33Z7158VBelASkUa4m//l7XkEA0Yj+x3Pk cY3k07Vf/7QruQn+HL8hT7/MVBCv3NOn39nMLfxsoowu0CY7qxeDY9YxkicXY667c53p4yiIqoG NVkAvAhgbMgJ1cwU41jccoNtgiytE6k4nvshibqYl6BzGXuDX78Xxtg3WFPtpYYr+60Qvkl0Ew4 T7rPbhLFEw/bJ4WWShrX7mw== X-Received: by 2002:a05:600c:5489:b0:495:40aa:d982 with SMTP id 5b1f17b1804b1-49573c8c272mr28724995e9.6.1784807926946; Thu, 23 Jul 2026 04:58:46 -0700 (PDT) X-Received: by 2002:a05:600c:5489:b0:495:40aa:d982 with SMTP id 5b1f17b1804b1-49573c8c272mr28724665e9.6.1784807926297; Thu, 23 Jul 2026 04:58:46 -0700 (PDT) Date: Thu, 23 Jul 2026 07:58:43 -0400 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org Cc: Eric Auger , Jean-Philippe Brucker , Paolo Bonzini , Fam Zheng Subject: [PATCH] virtio-iommu: fix OOM due to unbounded call_rcu Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Mailer: git-send-email 2.51.2.2891.g4157995a80.dirty X-Mutt-Fcc: =sent Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=170.10.133.124; envelope-from=mst@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.951, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, T_SPF_PERMERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-Zoho-Virus-Status: 1 X-Zoho-AV-Stamp: zmail-av-0.2.10.1.5.2/284.802.37 X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1784807973336158500 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, within virtio-iommu, handle_command processes the command vq without any limits on the number of entries processed. This can easily and repeatedly enable/disable multiple memory regions. Within the memory code, this causes an accumulation of an unbounded number of RCU-deferred FlatViews - each of these is supposed to be freed with call_rcu, but that never happens because the main thread never returns to the main loop. Given FlatView is big, it's easy to have this balloon out to multiple Gigabytes of memory. Limit the loop defer any remaining work to a timer. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3930 Cc: Eric Auger Cc: Jean-Philippe Brucker Signed-off-by: Michael S. Tsirkin Reviewed-by: Eric Auger Tested-by: Eric Auger --- include/hw/virtio/virtio-iommu.h | 1 + hw/virtio/virtio-iommu.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-io= mmu.h index 3b86050f2c..1f265540ad 100644 --- a/include/hw/virtio/virtio-iommu.h +++ b/include/hw/virtio/virtio-iommu.h @@ -65,6 +65,7 @@ struct VirtIOIOMMU { GTree *domains; QemuRecMutex mutex; GTree *endpoints; + QEMUTimer *cmd_timer; bool boot_bypass; Notifier machine_done; bool granule_frozen; diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 08f7e8b783..533bd5073f 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -993,6 +993,18 @@ static int virtio_iommu_handle_probe(VirtIOIOMMU *s, return ret ? ret : virtio_iommu_probe(s, &req, buf); } =20 +static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq); + +static void virtio_iommu_handle_command_timer(void *opaque) +{ + VirtIOIOMMU *s =3D opaque; + VirtIODevice *vdev =3D VIRTIO_DEVICE(s); + + if (virtio_device_started(vdev, vdev->status) && !vdev->broken) { + virtio_iommu_handle_command(vdev, s->req_vq); + } +} + static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq) { VirtIOIOMMU *s =3D VIRTIO_IOMMU(vdev); @@ -1003,10 +1015,17 @@ static void virtio_iommu_handle_command(VirtIODevic= e *vdev, VirtQueue *vq) struct iovec *iov; void *buf =3D NULL; size_t sz; + unsigned int batch =3D 0; =20 for (;;) { size_t output_size =3D sizeof(tail); =20 + if (++batch > virtio_queue_get_num(vdev, virtio_get_queue_index(vq= ))) { + timer_mod(s->cmd_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) + 1); + break; + } + elem =3D virtqueue_pop(vq, sizeof(VirtQueueElement)); if (!elem) { return; @@ -1416,6 +1435,8 @@ static void virtio_iommu_device_realize(DeviceState *= dev, Error **errp) s->req_vq =3D virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, virtio_iommu_handle_command); s->event_vq =3D virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, NULL= ); + s->cmd_timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, + virtio_iommu_handle_command_timer, s); =20 /* * config.bypass is needed to get initial address space early, such as @@ -1498,6 +1519,7 @@ static void virtio_iommu_device_unrealize(DeviceState= *dev) =20 qemu_rec_mutex_destroy(&s->mutex); =20 + timer_free(s->cmd_timer); virtio_delete_queue(s->req_vq); virtio_delete_queue(s->event_vq); virtio_cleanup(vdev); @@ -1509,6 +1531,8 @@ static void virtio_iommu_device_reset_exit(Object *ob= j, ResetType type) =20 trace_virtio_iommu_device_reset_exit(); =20 + timer_del(s->cmd_timer); + if (s->domains) { g_tree_destroy(s->domains); } @@ -1628,6 +1652,11 @@ static int iommu_post_load(void *opaque, int version= _id) * still correct. */ virtio_iommu_switch_address_space_all(s); + + if (virtio_device_started(VIRTIO_DEVICE(s), VIRTIO_DEVICE(s)->status))= { + timer_mod(s->cmd_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) + 1); + } return 0; } =20 --=20 MST