From: Marc Zyngier <maz@kernel.org>
To: francesco.boccola@unina.it
Cc: Oliver Upton <oupton@kernel.org>,
Fuad Tabba <fuad.tabba@linux.dev>,
Joey Gouly <joey.gouly@arm.com>,
Steffen Eiden <seiden@linux.ibm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH RFC v2] KVM: arm64: nVHE: Flush all TLBs when freeing a VM's stage-2
Date: Thu, 29 Oct 2026 17:05:08 +0000 [thread overview]
Message-ID: <86ik2kxwsb.wl-maz@kernel.org> (raw)
In-Reply-To: <20261029-nvhe-stage2-flush-v2-1-096723b28bef@unina.it>
On Thu, 29 Oct 2026 15:34:48 +0000,
Francesco Boccola via B4 Relay <devnull+francesco.boccola.unina.it@kernel.org> wrote:
>
> From: Francesco Boccola <francesco.boccola@unina.it>
>
> kvm_free_stage2_pgd() frees a VM's stage-2 page tables without invalidating
> the TLBs. That is correct: the VM's VMID is not reused before the next VMID
> rollover, and flush_context() then invalidates the entries of all VMIDs on
> all CPUs (TLBI ALLE1IS).
>
> In nVHE mode, however, a CPU that ran a guest makes the host's broadcast
> TLB invalidations more expensive for the whole system until then, which
> with 16-bit VMIDs usually means until the host reboots.
Does it? Why? What permanent state is kept in the CPU TLBs that makes
invalidation slower?
> With stress-ng
> --tlb-shootdown on three CPUs of a cluster, the cyclictest maximum on a
> fourth, isolated CPU goes, before and after one guest:
> - Cortex-A53 (Zynq UltraScale+ KV260, no VHE, 6.1.70-rt): 53-72 us ->
> 83-164 us;
> - Cortex-A55 (RK3588, kvm-arm.mode=nvhe, kvmarm/next): 18-23 -> 78-97 us;
> - Cortex-A76 (RK3588, kvm-arm.mode=nvhe, kvmarm/next): 16-30 -> 74-80 us.
> It crosses clusters: after a guest on an A55, an isolated A76 goes from
> 14-18 us to 129-154 us. The same happens on kernel 6.12.113 (20-24 -> 44-49
> us on the A55) and on 7.1.9 with and without PREEMPT_RT.
>
> One guest that turns its stage-1 MMU on, even for a few microseconds, is
> enough; a guest that keeps its MMU off is not. With VHE nothing changes.
>
> The state is in the CPU that ran the guest: a local TLBI ALLE1 on that CPU
> at teardown removes the effect on every CPU, the same on all the other CPUs
I note that the hack you are adding in this patch is a broadcast TLBI,
not a local one.
> does not. Invalidating the dead VM's VMID (TLBI VMALLS12E1IS, as pKVM does
> at teardown) does not remove it either, whether stage 2 is disabled while
> it is issued (as __kvm_tlb_flush_vmid() does from the host's context) or
> enabled; nor does invalidating VMID 0 or the host's stage 1 (A53).
VMID 0 is not special. This is just a convention, and you could use
VMID $(RANDOM) as long as you use it consistently everywhere.
>
> So do the rollover's invalidation when the stage 2 of a VM that has run is
> freed, in nVHE mode. That costs one TLB refill on every CPU per VM
> teardown; 500 VMs created, run and torn down one after the other take 32.1
> ms each with it and 33.4 ms without, and an isolated CPU meanwhile sees no
> change in latency (15 us against 13 us).
Not a lot in this report makes sense, I'm afraid. I'm not pretending
that what you are seeing isn't real (I haven't tried it), but without
a actual description of what the root cause of the problem is, we're
not going to randomly sprinkle TLB invalidations that are not
architecturally required.
M.
--
Without deviation from the norm, progress is not possible.
prev parent reply other threads:[~2026-10-29 17:05 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 15:34 [PATCH RFC v2] KVM: arm64: nVHE: Flush all TLBs when freeing a VM's stage-2 Francesco Boccola via B4 Relay
2026-10-29 15:34 ` Francesco Boccola
2026-10-29 17:05 ` Marc Zyngier [this message]
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=86ik2kxwsb.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=francesco.boccola@unina.it \
--cc=fuad.tabba@linux.dev \
--cc=joey.gouly@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=oupton@kernel.org \
--cc=seiden@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
--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.