]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
x86/p2m: limit cache flush in memory_type_changed()
authorRoger Pau Monne <roger.pau@citrix.com>
Wed, 30 Apr 2025 14:46:34 +0000 (16:46 +0200)
committerRoger Pau Monne <roger.pau@citrix.com>
Tue, 6 May 2025 08:02:36 +0000 (10:02 +0200)
Only do the cache flush when there's a p2m type change to propagate,
otherwise there's no change in the p2m effective caching attributes.

If the p2m memory_type_changed hook is not set p2m_memory_type_changed() is
a no-op, no recalculation of caching attributes is needed, nor flushing of
the previous cache contents.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
xen/arch/x86/hvm/mtrr.c
xen/arch/x86/include/asm/p2m.h
xen/arch/x86/mm/p2m.c

index b88e81eb44b1dd1c415fb5bcf10caff283deb149..e7acfb6e8dc4c32c4395f5c075ef9e4f6d044046 100644 (file)
@@ -767,9 +767,8 @@ HVM_REGISTER_SAVE_RESTORE(MTRR, hvm_save_mtrr_msr, NULL, hvm_load_mtrr_msr, 1,
 void memory_type_changed(struct domain *d)
 {
     if ( (is_iommu_enabled(d) || cache_flush_permitted(d)) &&
-         d->vcpu && d->vcpu[0] )
+         d->vcpu && d->vcpu[0] && p2m_memory_type_changed(d) )
     {
-        p2m_memory_type_changed(d);
         flush_all(FLUSH_CACHE);
     }
 }
index b9ce7d8705ba62aa3c3f5cad000b8f2b6fc09a81..4358cc15a2a1dab7d6077c4317782a7902fac80d 100644 (file)
@@ -700,7 +700,7 @@ void p2m_pod_dump_data(struct domain *d);
 #ifdef CONFIG_HVM
 
 /* Report a change affecting memory types. */
-void p2m_memory_type_changed(struct domain *d);
+bool p2m_memory_type_changed(struct domain *d);
 
 /* Called by p2m code when demand-populating a PoD page */
 bool
index 3a39b5d1246ba9531e751aaf40a3bab0fb344e72..b9a7c2dc53026e5a8c94ef93a6e32086a0357009 100644 (file)
@@ -126,12 +126,21 @@ static void _memory_type_changed(struct p2m_domain *p2m)
 {
     if ( p2m->memory_type_changed )
         p2m->memory_type_changed(p2m);
+    else
+        ASSERT_UNREACHABLE();
 }
 
-void p2m_memory_type_changed(struct domain *d)
+bool p2m_memory_type_changed(struct domain *d)
 {
     struct p2m_domain *hostp2m = p2m_get_hostp2m(d);
 
+    /*
+     * The p2m memory_type_changed hook will be the same for the host p2m or
+     * the altp2ms, do the check early and return if not set.
+     */
+    if ( !hostp2m->memory_type_changed )
+        return false;
+
     p2m_lock(hostp2m);
 
     _memory_type_changed(hostp2m);
@@ -154,6 +163,8 @@ void p2m_memory_type_changed(struct domain *d)
     }
 
     p2m_unlock(hostp2m);
+
+    return true;
 }
 
 int p2m_set_ioreq_server(struct domain *d,