xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86/ept: limit calls to memory_type_changed()
@ 2022-09-22 16:05 Roger Pau Monne
  2022-09-22 19:21 ` Jan Beulich
  2022-09-26 18:03 ` Andrew Cooper
  0 siblings, 2 replies; 12+ messages in thread
From: Roger Pau Monne @ 2022-09-22 16:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Roger Pau Monne, Jan Beulich, Andrew Cooper, Wei Liu,
	George Dunlap, Julien Grall, Stefano Stabellini

memory_type_changed() is currently only implemented for Intel EPT, and
results in the invalidation of EMT attributes on all the entries in
the EPT page tables.  Such invalidation causes EPT_MISCONFIG vmexits
when the guest tries to access any gfns for the first time, which
results in the recalculation of the EMT for the accessed page.  The
vmexit and the recalculations are expensive, and as such should be
avoided when possible.

Remove the call to memory_type_changed() from
XEN_DOMCTL_memory_mapping: there are no modifications of the
iomem_caps ranges anymore that could alter the return of
cache_flush_permitted() from that domctl.

Calls to memory_type_changed() resulting from changes to the domain
iomem_caps or ioport_caps ranges are only relevant for EMT
calculations if the IOMMU is not enabled, and the call has resulted in
a change to the return value of cache_flush_permitted().

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
I feel it's a bit weird to have calls to memory_type_changed() in
common domctl code - for once the domctl that trigger the call doesn't
change memory types, just adds or removes ranges from iomem_caps
(which in turn affects the behaviour of epte_get_entry_emt()).
---
 xen/arch/x86/domctl.c | 18 ++++++++++++++++--
 xen/common/domctl.c   | 11 ++++++++---
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 020df615bd..f1150dffa5 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -222,6 +222,7 @@ long arch_do_domctl(
         unsigned int fp = domctl->u.ioport_permission.first_port;
         unsigned int np = domctl->u.ioport_permission.nr_ports;
         int allow = domctl->u.ioport_permission.allow_access;
+        bool flush_permitted = cache_flush_permitted(d);
 
         if ( (fp + np) <= fp || (fp + np) > MAX_IOPORTS )
             ret = -EINVAL;
@@ -232,7 +233,13 @@ long arch_do_domctl(
             ret = ioports_permit_access(d, fp, fp + np - 1);
         else
             ret = ioports_deny_access(d, fp, fp + np - 1);
-        if ( !ret )
+        if ( !ret && !is_iommu_enabled(d) &&
+             flush_permitted != cache_flush_permitted(d) )
+            /*
+             * Only flush if the output of cache_flush_permitted() changes and
+             * IOMMU is not enabled for the domain, otherwise it makes no
+             * difference for EMT calculation purposes.
+             */
             memory_type_changed(d);
         break;
     }
@@ -586,6 +593,7 @@ long arch_do_domctl(
         struct hvm_domain *hvm;
         struct g2m_ioport *g2m_ioport;
         int found = 0;
+        bool flush_permitted = cache_flush_permitted(d);
 
         ret = -EOPNOTSUPP;
         if ( !is_hvm_domain(d) )
@@ -666,7 +674,13 @@ long arch_do_domctl(
                        "ioport_map: error %ld denying dom%d access to [%x,%x]\n",
                        ret, d->domain_id, fmp, fmp + np - 1);
         }
-        if ( !ret )
+        if ( !ret && !is_iommu_enabled(d) &&
+             flush_permitted != cache_flush_permitted(d) )
+            /*
+             * Only flush if the output of cache_flush_permitted() changes and
+             * IOMMU is not enabled for the domain, otherwise it makes no
+             * difference for EMT calculation purposes.
+             */
             memory_type_changed(d);
         break;
     }
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 452266710a..1f2f2dfcc2 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -703,6 +703,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
         unsigned long mfn = op->u.iomem_permission.first_mfn;
         unsigned long nr_mfns = op->u.iomem_permission.nr_mfns;
         int allow = op->u.iomem_permission.allow_access;
+        bool flush_permitted = cache_flush_permitted(d);
 
         ret = -EINVAL;
         if ( (mfn + nr_mfns - 1) < mfn ) /* wrap? */
@@ -716,7 +717,13 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
         else
             ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
-        if ( !ret )
+        if ( !ret && !is_iommu_enabled(d) &&
+             flush_permitted != cache_flush_permitted(d) )
+            /*
+             * Only flush if the output of cache_flush_permitted() changes and
+             * IOMMU is not enabled for the domain, otherwise it makes no
+             * difference for effective cache attribute calculation purposes.
+             */
             memory_type_changed(d);
         break;
     }
@@ -778,8 +785,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
                        "memory_map: error %ld removing dom%d access to [%lx,%lx]\n",
                        ret, d->domain_id, mfn, mfn_end);
         }
-        /* Do this unconditionally to cover errors on above failure paths. */
-        memory_type_changed(d);
         break;
     }
 
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-09-27  9:34 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-22 16:05 [PATCH] x86/ept: limit calls to memory_type_changed() Roger Pau Monne
2022-09-22 19:21 ` Jan Beulich
2022-09-23  8:35   ` Roger Pau Monné
2022-09-26  7:33     ` Jan Beulich
2022-09-26 14:50       ` Roger Pau Monné
2022-09-26 15:25         ` Roger Pau Monné
2022-09-26 15:36           ` Jan Beulich
2022-09-26 15:58             ` Roger Pau Monné
2022-09-27  6:35               ` Jan Beulich
2022-09-27  8:40                 ` Roger Pau Monné
2022-09-26 18:03 ` Andrew Cooper
2022-09-27  9:33   ` Roger Pau Monné

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).