mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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:
1 parent
847d34f232
commit
5e529e4e7b
1 file changed
+4
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||