From: Jing Zhang <jingzhangos@google.com>
To: KVM <kvm@vger.kernel.org>, KVMARM <kvmarm@lists.linux.dev>
Cc: Marc Zyngier <maz@kernel.org>,
Oliver Upton <oliver.upton@linux.dev>,
Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Jing Zhang <jingzhangos@google.com>
Subject: [PATCH] KVM: arm64: vgic-its: Fix O(C*I) loop in vgic_its_free_collection_list
Date: Tue, 18 Aug 2026 15:34:22 -0700 [thread overview]
Message-ID: <20260818223422.367803-1-jingzhangos@google.com> (raw)
When destroying the vgic-its collection list,
vgic_its_free_collection_list() iterates over every collection and for
each, calls vgic_its_free_collection(). This function walks every
Interrupt Translation Entry (ITE) across all devices via
for_each_lpi_its() to nullify the collection pointer.
A guest can allocate up to 65536 collections and hundreds of thousands
of ITEs. By clearing GITS_CTLR.Enable and writing Valid=0 to
GITS_BASER1, the guest can trigger this teardown path from a single MMIO
exit. The resulting O(Collections * ITEs) nested loop executes billions
of iterations without a single cond_resched(). This pins a physical CPU
and stalls RCU grace periods for seconds or minutes on PREEMPT_NONE
kernels.
Fix this by replacing the O(Collections * ITEs) teardown with an
O(Collections + ITEs) pass. Since the entire collection list is being
freed, we can safely bulk-clear the collection pointers from all ITEs in
a single pass, and then free all the collections in a second pass.
Signed-off-by: Jing Zhang <jingzhangos@google.com>
---
arch/arm64/kvm/vgic/vgic-its.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 36ab3e4929154..a8e819fe97898 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -1133,9 +1133,21 @@ static void vgic_its_free_device_list(struct kvm *kvm, struct vgic_its *its)
static void vgic_its_free_collection_list(struct kvm *kvm, struct vgic_its *its)
{
struct its_collection *cur, *temp;
+ struct its_device *device;
+ struct its_ite *ite;
- list_for_each_entry_safe(cur, temp, &its->collection_list, coll_list)
- vgic_its_free_collection(its, cur->collection_id);
+ /*
+ * Bulk-clear the collection pointers for all ITEs.
+ * This transforms the teardown complexity from O(Collections * ITEs)
+ * to O(Collections + ITEs), avoiding guest-triggered host RCU stalls.
+ */
+ for_each_lpi_its(device, ite, its)
+ ite->collection = NULL;
+
+ list_for_each_entry_safe(cur, temp, &its->collection_list, coll_list) {
+ list_del(&cur->coll_list);
+ kfree(cur);
+ }
}
/* Must be called with its_lock mutex held */
--
2.55.0.737.g08866a6d13-goog
next reply other threads:[~2026-08-18 22:34 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-18 22:34 Jing Zhang [this message]
2026-08-18 22:47 ` [PATCH] KVM: arm64: vgic-its: Fix O(C*I) loop in vgic_its_free_collection_list sashiko-bot
2026-08-20 13:11 ` Marc Zyngier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260818223422.367803-1-jingzhangos@google.com \
--to=jingzhangos@google.com \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=maz@kernel.org \
--cc=oliver.upton@linux.dev \
--cc=pbonzini@redhat.com \
--cc=suzuki.poulose@arm.com \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.