[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] x86/ept: limit calls to memory_type_changed()


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Roger Pau Monne <roger.pau@xxxxxxxxxx>
  • Date: Thu, 22 Sep 2022 18:05:16 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=yEY/skUulMhqe3KZ9qY/Gi9Gi3W1WPOcX5qKjCaqIwI=; b=LPgvO4a2I0IAjA1z5mjhwWQDhCBg2I7yB+ORk5KIv9ubL6pvUU/vDKvqRZb3hzzAMeictMO7GaxGO4CActQJq5tANfs5bI86/sPF62uwhXw00IzHSNNWJYbqXOs8hVaoLSvmaRWNwOxh26Y313CKafdZvQhBzxh5bUtyPZAi3IJmIcbadaWghs0mTorVFBw4fxRydAFxAeiOCoLAt9U43GxM4tJqWpgS56bok9gBWCc67BLNQsWHMkpHSO3Q1hej2p7B2RqQ00HIB2Bx2ekXk9oC+V5Adujk6FtNP7Sq68p3+phDsQsR5GEh5JbZiJjygoa22EDn75l4PMfMpU/MnQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TJUgu2uz3cWtVrgkBACbDHApZr5VRfRROi342ut+0ka+qws3Cyw6p0QSvvL8Okp7sVF7UrHZGdGZ5m6G6x4IDlsy2nPvv1itwv/Ku/kBv9oUDVYjle8TcXEK/+nCMK/ntvHmBSz/8ojHFf/SpzUoYyWpjRmZYENtoUMmtwJYWg5P2/dblTh7X+xDC3iwJEnD0ivqNOAC65GwMS7VKzjt4uxEW6gc/w7B7sh4lHwuUHAi0riITqUALASCWsdTc3xhYWb2kAXjnntA0zZz+E4Jcz9Aj8yQhWOq49+sR7oAT6B3n1Jocx2QgPIIEpoIuUfL3uMmC9AtkP5y0iIiB3tNqA==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: Roger Pau Monne <roger.pau@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>
  • Delivery-date: Thu, 22 Sep 2022 16:05:58 +0000
  • Ironport-data: A9a23:gE1MVa5RZUiThttvugkkvgxRtALGchMFZxGqfqrLsTDasY5as4F+v jRKDWDQafbfYWTzc9t3b4vi9R5T6p/Vn9cyQQc/qn9kHi5G8cbLO4+Ufxz6V8+wwmwvb67FA +E2MISowBUcFyeEzvuVGuG96yM6jclkf5KkYMbcICd9WAR4fykojBNnioYRj5VhxNO0GGthg /uryyHkEALjimUc3l48sfrZ8ks+5q6q4lv0g3RlDRx1lA6G/5UqJMp3yZGZdxPQXoRSF+imc OfPpJnRErTxpkpF5nuNy94XQ2VSKlLgFVHmZkl+AsBOtiNqtC0qupvXAdJHAathZ5dlqPgqo DlFncTYpQ7EpcQgksxFO/VTO3kW0aGrZNYriJVw2CCe5xSuTpfi/xlhJFMqHIcZxMxGOnBh/ KI0ChooaQq7if3jldpXSsE07igiBO/CGdpH/1tGknTeB/tgRo3fSaLX49MexC03ms1FAffZY YwedCZraxPDJRZIPz/7CrpnxLvu2ia5LGUe8QrJzUY0yzG7IAhZyr/iPcCTYtWXbc5UglyZt iTN+GGR7hQyZITPkWLUqS3EaunntCbHdIwiLqWE7N1PhAOz1kFLGCIfSg7uyRW+ogvkMz5FE GQE9yxroaUs+UiDStjmQwb+sHOCpgQbWddbD6s98g7l4qje7hudB2MEZiVcc9Fgv8gzLRQ10 neZktWvAiZg2JWXVHac+7G8vT60fy8PIgcqfjQYRAEI593ipoAbjR/VSNtnVqmvgbXI9SrYx jmLqG00geoVhMtSj6Gjpwmf33Sru4TDSRMz6kPPRGW54whlZYmjIYu19Vzc6vUGJ4GcJrWcg EU5dwGlxLhmJfmweOalGY3hwJnBCy65DQDh
  • Ironport-hdrordr: A9a23:yXIQQa4qCpgyVslJCQPXwSeBI+orL9Y04lQ7vn2ZFiY5TiXIra qTdaogviMc6Ax/ZJjvo6HjBEDmewKlyXcV2/hpAV7GZmXbUQSTXeVfBOfZowEIeBeOi9K1q5 0QFJSWYeeYZTYasS+T2njDLz9K+qjjzEnHv5a88587JjsaEJ2Ioj0JfjqzIwlTfk1rFJA5HJ 2T6o5uoCehQ20eaoCeCmMeV+bOitXXnNa+CCR2cSIP2U2rt3eF+bT6Gx+X0lM3VC5O+64r9S zgnxbi7quunvmnwlv31nPV7b5RhNz9o+Ezc/Cku4wwEHHBmwyobINuV/mruy00mvim7BIQnN zFs34bTrdOwkKUWlvwjQrm2gHm3jprwWTl00WkjXzqptG8bC4mCuJa7LgpOCfx2g4FhpVRwa hL12WWu958FhXbhhnw4NDOSlVDile0m3w/iuQe5kYvGrf2UIUh4bD3wXklX6vpREnBmc4a+a hVfYnhDc9tAB6nhyuzhBgv/DSuNk5DbituDHJy+vB96AIm4kyR/3FouPD3oU1wi67VM6M0gd gsEp4Y5o2mHfVmGJ5VNaMmffadLFDrbFblDF+ySG6XZZ3vfUi94qLK3A==
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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@xxxxxxxxxx>
---
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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.