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: 6df4b481b0 ("x86/np2m: implement sharing of np2m between vCPUs")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Stephen Cheng <stephen.cheng@citrix.com>
Reviewed-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Stephen Cheng authored and Jan Beulich committed 2026-10-27 08:57:45 +01:00
1 parent 847d34f232
commit 5e529e4e7b
1 file changed
+4
+4
View File
@@ -1547,7 +1547,11 @@ p2m_get_nestedp2m_locked(struct vcpu *v)
p2m_lock(p2m); p2m_lock(p2m);
if ( p2m->np2m_base == np2m_base ) if ( p2m->np2m_base == np2m_base )
{
if ( nv->nv_flushp2m )
p2m_flush_table_locked(p2m);
goto found; goto found;
}
p2m_unlock(p2m); p2m_unlock(p2m);
} }
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.