diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 480459ae51..5804a8819b 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1831,6 +1831,7 @@ p2m_get_nestedp2m_locked(struct vcpu *v) struct p2m_domain *p2m; uint64_t np2m_base = nhvm_vcpu_p2m_base(v); unsigned int i; + bool vcpu_flush = true; /* Mask out low bits; this avoids collisions with P2M_BASE_EADDR */ np2m_base &= ~(0xfffull); @@ -1847,14 +1848,9 @@ p2m_get_nestedp2m_locked(struct vcpu *v) if ( p2m->np2m_base == np2m_base ) { /* Check if np2m was flushed just before the lock */ - if ( nv->np2m_generation != p2m->np2m_generation ) - nvcpu_flush(v); - /* np2m is up-to-date */ - p2m->np2m_base = np2m_base; - assign_np2m(v, p2m); - nestedp2m_unlock(d); - - return p2m; + if ( nv->np2m_generation == p2m->np2m_generation ) + needs_flush = false; + goto found; } else if ( p2m->np2m_base != P2M_BASE_EADDR ) { @@ -1869,15 +1865,10 @@ p2m_get_nestedp2m_locked(struct vcpu *v) { p2m = d->arch.nested_p2m[i]; p2m_lock(p2m); + if ( p2m->np2m_base == np2m_base ) - { - nvcpu_flush(v); - p2m->np2m_base = np2m_base; - assign_np2m(v, p2m); - nestedp2m_unlock(d); + goto found; - return p2m; - } p2m_unlock(p2m); } @@ -1886,8 +1877,10 @@ p2m_get_nestedp2m_locked(struct vcpu *v) p2m = p2m_getlru_nestedp2m(d, NULL); p2m_flush_table(p2m); p2m_lock(p2m); +found: + if ( needs_flush ) + nvcpu_flush(v); p2m->np2m_base = np2m_base; - nvcpu_flush(v); assign_np2m(v, p2m); nestedp2m_unlock(d);