All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kai Huang <kai.huang@linux.intel.com>
To: jbeulich@suse.com, andrew.cooper3@citrix.com, tim@xen.org,
	kevin.tian@intel.com, yang.z.zhang@intel.com,
	xen-devel@lists.xen.org
Cc: Kai Huang <kai.huang@linux.intel.com>
Subject: [PATCH 10/10] p2m/ept: Enable PML in p2m-ept for log-dirty.
Date: Fri, 27 Mar 2015 10:35:54 +0800	[thread overview]
Message-ID: <1427423754-11841-11-git-send-email-kai.huang@linux.intel.com> (raw)
In-Reply-To: <1427423754-11841-1-git-send-email-kai.huang@linux.intel.com>

This patch adds PML support in p2m-ept for log-dirty.

In case of PML is used, we just need to clear EPT entry's D-bit in order to log
that GFN instead of setting EPT entry to read-only. And for partial log-dirty,
we also set D-bit for guest memory in normal mode to avoid unnecessary GPA
logging, as PML works globally at entire valid EPT table.

Signed-off-by: Kai Huang <kai.huang@linux.intel.com>
---
 xen/arch/x86/mm/hap/hap.c | 15 ++++++++--
 xen/arch/x86/mm/p2m-ept.c | 73 +++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 80 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
index 25f2f58..15fb5de 100644
--- a/xen/arch/x86/mm/hap/hap.c
+++ b/xen/arch/x86/mm/hap/hap.c
@@ -198,7 +198,10 @@ static int hap_enable_log_dirty(struct domain *d, bool_t log_global)
 
     if ( log_global )
     {
-        /* set l1e entries of P2M table to be read-only. */
+        /*
+         * switch to log dirty mode. either set l1e entries of P2M table to be
+         * read-only, or enable log dirty in hardware-assisted way.
+         */
         p2m_change_entry_type_global(d, p2m_ram_rw, p2m_ram_logdirty);
         flush_tlb_mask(d->domain_dirty_cpumask);
     }
@@ -213,14 +216,20 @@ static int hap_disable_log_dirty(struct domain *d)
 
     p2m_disable_hardware_log_dirty(d);
 
-    /* set l1e entries of P2M table with normal mode */
+    /*
+     * switch back to normal mode. either set l1e entries of P2M table with
+     * normal mode, or disable log dirty in hardware-assisted way.
+     */
     p2m_change_entry_type_global(d, p2m_ram_logdirty, p2m_ram_rw);
     return 0;
 }
 
 static void hap_clean_dirty_bitmap(struct domain *d)
 {
-    /* set l1e entries of P2M table to be read-only. */
+    /*
+     * switch to log dirty mode. either set l1e entries of P2M table to be
+     * read-only, or enable log dirty in hardware-assisted way.
+     */
     p2m_change_entry_type_global(d, p2m_ram_rw, p2m_ram_logdirty);
     flush_tlb_mask(d->domain_dirty_cpumask);
 }
diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index 8650092..9a719f6 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -102,7 +102,8 @@ static int atomic_write_ept_entry(ept_entry_t *entryptr, ept_entry_t new,
     return rc;
 }
 
-static void ept_p2m_type_to_flags(ept_entry_t *entry, p2m_type_t type, p2m_access_t access)
+static void ept_p2m_type_to_flags(struct p2m_domain *p2m, ept_entry_t *entry,
+                                  p2m_type_t type, p2m_access_t access)
 {
     /* First apply type permissions */
     switch(type)
@@ -118,6 +119,12 @@ static void ept_p2m_type_to_flags(ept_entry_t *entry, p2m_type_t type, p2m_acces
             break;
         case p2m_ram_rw:
             entry->r = entry->w = entry->x = 1;
+            /*
+             * This is about to avoid unnecessary GPA logging in PML buffer,
+             * such as normal memory in partial log-dirty
+             */
+            if ( vmx_domain_pml_enabled(p2m->domain) )
+                entry->d = 1;
             break;
         case p2m_mmio_direct:
             entry->r = entry->x = 1;
@@ -125,6 +132,26 @@ static void ept_p2m_type_to_flags(ept_entry_t *entry, p2m_type_t type, p2m_acces
                                                     entry->mfn);
             break;
         case p2m_ram_logdirty:
+            entry->r = entry->x = 1;
+            if ( vmx_domain_pml_enabled(p2m->domain) )
+            {
+                /*
+                 * In case of PML, we don't have to write protect 4K page, but
+                 * only need to clear D-bit for it. Note we still need to write
+                 * protect super page in order to split it to 4K pages in EPT
+                 * violation.
+                 */
+                if ( !is_epte_superpage(entry) )
+                {
+                    entry->w = 1;
+                    entry->d = 0;
+                }
+                else
+                    entry->w = 0;
+            }
+            else
+                entry->w = 0;
+            break;
         case p2m_ram_ro:
         case p2m_ram_shared:
             entry->r = entry->x = 1;
@@ -250,7 +277,7 @@ static int ept_split_super_page(struct p2m_domain *p2m, ept_entry_t *ept_entry,
         /* A/D bits are inherited from superpage */
         ASSERT(!epte->avail3);
 
-        ept_p2m_type_to_flags(epte, epte->sa_p2mt, epte->access);
+        ept_p2m_type_to_flags(p2m, epte, epte->sa_p2mt, epte->access);
 
         if ( (level - 1) == target )
             continue;
@@ -492,7 +519,7 @@ static int resolve_misconfig(struct p2m_domain *p2m, unsigned long gfn)
                     {
                          e.sa_p2mt = p2m_is_logdirty_range(p2m, gfn + i, gfn + i)
                                      ? p2m_ram_logdirty : p2m_ram_rw;
-                         ept_p2m_type_to_flags(&e, e.sa_p2mt, e.access);
+                         ept_p2m_type_to_flags(p2m, &e, e.sa_p2mt, e.access);
                     }
                     e.recalc = 0;
                     wrc = atomic_write_ept_entry(&epte[i], e, level);
@@ -544,7 +571,7 @@ static int resolve_misconfig(struct p2m_domain *p2m, unsigned long gfn)
                 e.ipat = ipat;
                 e.recalc = 0;
                 if ( recalc && p2m_is_changeable(e.sa_p2mt) )
-                    ept_p2m_type_to_flags(&e, e.sa_p2mt, e.access);
+                    ept_p2m_type_to_flags(p2m, &e, e.sa_p2mt, e.access);
                 wrc = atomic_write_ept_entry(&epte[i], e, level);
                 ASSERT(wrc == 0);
             }
@@ -755,7 +782,7 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
         if ( ept_entry->mfn == new_entry.mfn )
              need_modify_vtd_table = 0;
 
-        ept_p2m_type_to_flags(&new_entry, p2mt, p2ma);
+        ept_p2m_type_to_flags(p2m, &new_entry, p2mt, p2ma);
     }
 
     rc = atomic_write_ept_entry(ept_entry, new_entry, target);
@@ -1057,6 +1084,35 @@ void ept_sync_domain(struct p2m_domain *p2m)
                      __ept_sync_domain, p2m, 1);
 }
 
+static void ept_enable_pml(struct p2m_domain *p2m)
+{
+    /*
+     * No need to check if vmx_domain_enable_pml has succeeded or not, as
+     * ept_p2m_type_to_flags will check if PML has been enabled or not, and
+     * traditional write protection will be used if PML has not been enabled.
+     */
+    if ( vmx_domain_pml_enabled(p2m->domain) )
+        return;
+
+    vmx_domain_enable_pml(p2m->domain);
+}
+
+static void ept_disable_pml(struct p2m_domain *p2m)
+{
+    if ( !vmx_domain_pml_enabled(p2m->domain) )
+        return;
+
+    vmx_domain_disable_pml(p2m->domain);
+}
+
+static void ept_flush_pml_buffers(struct p2m_domain *p2m)
+{
+    if ( !vmx_domain_pml_enabled(p2m->domain) )
+        return;
+
+    vmx_domain_flush_pml_buffers(p2m->domain);
+}
+
 int ept_p2m_init(struct p2m_domain *p2m)
 {
     struct ept_data *ept = &p2m->ept;
@@ -1077,6 +1133,13 @@ int ept_p2m_init(struct p2m_domain *p2m)
     /* Enable EPT A/D bit if it's supported by hardware */
     ept->ept_ad = cpu_has_vmx_ept_ad_bit ? 1 : 0;
 
+    if ( cpu_has_vmx_pml )
+    {
+        p2m->enable_hardware_log_dirty = ept_enable_pml;
+        p2m->disable_hardware_log_dirty = ept_disable_pml;
+        p2m->flush_hardware_cached_dirty = ept_flush_pml_buffers;
+    }
+
     if ( !zalloc_cpumask_var(&ept->synced_mask) )
         return -ENOMEM;
 
-- 
2.1.0

  parent reply	other threads:[~2015-03-27  2:35 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-27  2:35 [PATCH 00/10] PML (Paging Modification Logging) support Kai Huang
2015-03-27  2:35 ` [PATCH 01/10] VMX: Enable EPT A/D bit support Kai Huang
2015-03-27 20:38   ` Andrew Cooper
2015-03-30  6:11     ` Kai Huang
2015-03-30  9:36       ` Andrew Cooper
2015-03-30 13:35         ` Kai Huang
2015-03-30 13:39           ` Andrew Cooper
2015-04-02  6:32     ` Kai Huang
2015-04-02  9:55       ` Andrew Cooper
2015-04-09 11:21   ` Tim Deegan
2015-04-10  6:40     ` Kai Huang
2015-04-10  8:54       ` Tim Deegan
2015-04-10  9:26         ` Kai Huang
2015-04-10  9:51           ` Tim Deegan
2015-04-10 13:14             ` Kai Huang
2015-03-27  2:35 ` [PATCH 02/10] VMX: New parameter to control PML enabling Kai Huang
2015-03-27 20:42   ` Andrew Cooper
2015-03-30  6:16     ` Kai Huang
2015-04-02  5:46     ` Kai Huang
2015-04-02  9:58       ` Andrew Cooper
2015-04-02 13:34         ` Kai Huang
2015-03-27  2:35 ` [PATCH 03/10] VMX: Add PML definition and feature detection Kai Huang
2015-03-27 20:46   ` Andrew Cooper
2015-03-30  6:18     ` Kai Huang
2015-03-27  2:35 ` [PATCH 04/10] VMX: New data structure member to support PML Kai Huang
2015-03-27 20:48   ` Andrew Cooper
2015-03-30  6:19     ` Kai Huang
2015-03-27  2:35 ` [PATCH 05/10] VMX: add help functions " Kai Huang
2015-03-27 21:09   ` Andrew Cooper
2015-03-30  6:43     ` Kai Huang
2015-03-30  9:54       ` Andrew Cooper
2015-03-30 13:40         ` Kai Huang
2015-04-09 12:00   ` Tim Deegan
2015-04-10  7:05     ` Kai Huang
2015-04-10  9:03       ` Tim Deegan
2015-04-10  9:28         ` Kai Huang
2015-04-09 12:31   ` Tim Deegan
2015-04-10  7:07     ` Kai Huang
2015-03-27  2:35 ` [PATCH 06/10] VMX: handle PML buffer full VMEXIT Kai Huang
2015-03-27  2:35 ` [PATCH 07/10] VMX: handle PML enabling in vmx_vcpu_initialise Kai Huang
2015-03-27 21:12   ` Andrew Cooper
2015-03-30  7:03     ` Kai Huang
2015-03-30 10:00       ` Andrew Cooper
2015-03-27  2:35 ` [PATCH 08/10] VMX: disable PML in vmx_vcpu_destroy Kai Huang
2015-04-09 12:04   ` Tim Deegan
2015-04-10  7:25     ` Kai Huang
2015-04-10  9:30       ` Tim Deegan
2015-03-27  2:35 ` [PATCH 09/10] log-dirty: Refine common code to support PML Kai Huang
2015-04-09 12:27   ` Tim Deegan
2015-04-10  7:38     ` Kai Huang
2015-04-10  9:31       ` Tim Deegan
2015-04-10  9:33         ` Kai Huang
2015-03-27  2:35 ` Kai Huang [this message]
2015-04-09 12:20   ` [PATCH 10/10] p2m/ept: Enable PML in p2m-ept for log-dirty Tim Deegan
2015-04-10  8:44     ` Kai Huang
2015-04-10  9:46       ` Tim Deegan
2015-04-10 13:18         ` Kai Huang
2015-04-10 14:35           ` Tim Deegan
2015-03-27 21:26 ` [PATCH 00/10] PML (Paging Modification Logging) support Andrew Cooper
2015-03-30  5:50   ` Kai Huang
2015-04-07  8:30     ` Kai Huang
2015-04-07  9:24       ` Tim Deegan
2015-04-08  2:23         ` Kai Huang
2015-04-09 12:32         ` Tim Deegan
2015-04-10  6:40           ` Kai Huang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1427423754-11841-11-git-send-email-kai.huang@linux.intel.com \
    --to=kai.huang@linux.intel.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=kevin.tian@intel.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.org \
    --cc=yang.z.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.