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>