[PATCH v2 0/8] KVM: arm64: VNCR TLB invalidation fixes

Marc Zyngier <[email protected]> Thu, 6 Aug 2026 10:10:18 +0100
Newsgroups dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.kvm
Message-ID <[email protected]>
Prompted by a patch [0] from Hyunwoo Kim which was addressing a pretty
annoying corner case, I spent some time looking at what was wrong in
our VNCR TLBI code. And there was a few things to say about it...

- The TLB tracking to get into the slow path is wrong. It tracks what
  is mapped, but not the established TLBs. Kind of annoying.

- Handling IPA invalidation when the TLB was established with the S1
  MMU disabled is failing for a number of reasons. This is the bug
  that Hyunwoo Kim found, but I decided to address it at its root
  rather than just fixing the symptoms.

- Deciding to run with a VNCR TLB doesn't take the state of
  SCTLR_EL2.M into account. Yes, it is a special sort of sport to run
  a hypervisor with its MMU disabled...

- TLB invalidation by VA targeting the last page/block of TTBR1_EL2 is
  dropped on the floor, because I cannot count. This was amusing. Not.

Additionally, Sashiko kindly provided some extra horrors to look at:

- A missing sign extension for range invalidation results in the wrong
  VA range being considered.

- TLBI doesn't participate in the general MMU invalidation retry
  machinery, meaning that VNCR faults and TLBIs race in an
  uncontrolled way.

- TLBI and vcpu_put() can race badly, leading to a TOCTOU pattern
  which results in either a BUG_ON() or a call to vncr_fixmap(-1).

I have fixes for each of these issues, all stable candidates.

On top of that, I have a patch reintroducing the tracking that the
first patch removes, this time in a way that is actually functional.
Or at least I think it is...

I'd like to thank Hyunwoo Kim for their initial patch and for
providing a reproducer that helped me finding these issues by running
it at multiple levels of nesting.

It is now too late for 7.2, so let's try to make this 7.3 material
(hence the early repost).

* From v1 [1]

  - Added sign extension to range invalidation (Sashiko)

  - Use mmu_invalidate_seq to resolve fault vs TLBI races (Sashiko)

  - Speculatively bump the TLB refcount on fault to make sure the TLBI
    takes the slow path when we are going for a S1 walk

  - Clarify the check for the TLB matching for the S1 MMU state

  - Extra sanitisation added on the S2 invalidation path

  - Applied RBs from Yao Yuan to the patches that didn't change, with
    thanks.
    
[0] https://lore.kernel.org/r/ameGoxbn2wzBq2kL@v4bel
[1] https://lore.kernel.org/r/[email protected]

Marc Zyngier (8):
  KVM: arm64: Remove VM-wide VNCR mapping counter
  KVM: arm64: Handle negative S1 walk levels in VNCR TLB size evaluation
  KVM: arm64: Consider SCTLR_EL2.M when mapping the L1 VNCR page
  KVM: arm64: Correctly handle end of VA space TLBI invalidation
  KVM: arm64: Handle VNCR TLB invalidation race with vcpu_put() VNCR
    unmapping
  KVM: arm64: Sign-extend VA for range-based TLBI invalidation
  KVM: arm64: Make VNCR invalidation participate in MMU invalidation
    retry
  KVM: arm64: Add VNCR TLB tracking again

 arch/arm64/include/asm/kvm_host.h   |   4 +-
 arch/arm64/include/asm/kvm_nested.h |  14 +++
 arch/arm64/kvm/at.c                 |   2 -
 arch/arm64/kvm/hyp/vhe/switch.c     |  10 +-
 arch/arm64/kvm/nested.c             | 173 +++++++++++++++++++---------
 arch/arm64/kvm/sys_regs.c           |  11 ++
 6 files changed, 155 insertions(+), 59 deletions(-)

-- 
2.47.3