From 5e529e4e7b1a0b27f25017e18e8665e864b72fdb Mon Sep 17 00:00:00 2001 From: Stephen Cheng Date: Tue, 27 Oct 2026 08:57:45 +0100 Subject: [PATCH] x86/np2m: flush the np2m on an SVM nested TLB flush On SVM, L1 flushes what is cached from its nested page tables by setting TLB_CONTROL or using a new ASID on VMRUN. Either sets nv_flushp2m, which p2m_get_nestedp2m_locked() handles by only dropping nv_p2m. Since np2ms are shared between vCPUs, the lookup then finds the np2m for the same N_CR3 and reuses it as is, so L2 keeps the mappings from before L1 changed its NPT. The obvious fix, flushing nv_p2m (the np2m this vCPU used last) before dropping it, is not enough. It covers a vCPU re-entering the same N_CR3, but not one entering an N_CR3 whose np2m another vCPU filled: on its first VMRUN (nv_p2m is NULL), with an ASID new to it, or when switching N_CR3. Instead, flush the np2m for the incoming N_CR3 before reusing it, as nested VMX does via np2m_flush_base() on INVEPT. Fixes: 6df4b481b0c5 ("x86/np2m: implement sharing of np2m between vCPUs") Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Stephen Cheng Reviewed-by: Ross Lagerwall Acked-by: Jan Beulich --- xen/arch/x86/mm/p2m.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 027b9ae69b..52cadd9b25 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1547,7 +1547,11 @@ p2m_get_nestedp2m_locked(struct vcpu *v) p2m_lock(p2m); if ( p2m->np2m_base == np2m_base ) + { + if ( nv->nv_flushp2m ) + p2m_flush_table_locked(p2m); goto found; + } p2m_unlock(p2m); }