xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Xudong Hao <xudong.hao@intel.com>
To: xen-devel@lists.xen.org
Cc: Haitao Shan <haitao.shan@intel.com>,
	Xudong Hao <xudong.hao@intel.com>,
	keir@xen.org, xiantao.zhang@intel.com, JBeulich@suse.com
Subject: [PATCH 4/4] xen: enable EPT dirty bit for guest live migration
Date: Tue, 19 Jun 2012 14:28:26 +0800	[thread overview]
Message-ID: <1340087306-6096-5-git-send-email-xudong.hao@intel.com> (raw)
In-Reply-To: <1340087306-6096-1-git-send-email-xudong.hao@intel.com>

When p2m type is p2m_ram_logdirty, page should be read/write/execute(d) with EPT
dirty bit support.

When guest live migration with EPT dirty bit support, it does not trigger EPT
violation any longer, we flush dirty bitmap in ept_change_entry_type_page()
function, by walking the EPT page table.

Signed-off-by: Haitao Shan<haitao.shan@intel.com>
Signed-off-by: Xudong Hao <xudong.hao@intel.com>
---
 xen/arch/x86/mm/p2m-ept.c |   50 ++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index f373905..e07004d 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -24,6 +24,7 @@
 #include <asm/types.h>
 #include <asm/domain.h>
 #include <asm/p2m.h>
+#include <asm/hap.h>
 #include <asm/hvm/vmx/vmx.h>
 #include <asm/hvm/vmx/vmcs.h>
 #include <xen/iommu.h>
@@ -69,6 +70,11 @@ 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->w = hap_has_dirty_bit;
+            entry->r = entry->x = 1;
+            /* Not necessarily need to clear A bit, but it is safe anyway */
+            entry->a = entry->d = 0;
+            break;
         case p2m_ram_ro:
         case p2m_ram_shared:
             entry->r = entry->x = 1;
@@ -373,6 +379,9 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
                 need_modify_vtd_table = 0;
 
             ept_p2m_type_to_flags(&new_entry, p2mt, p2ma);
+
+            if ( old_entry.d && (old_entry.sa_p2mt == p2m_ram_logdirty) )
+                paging_mark_dirty(d, mfn_x(mfn));
         }
 
         atomic_write_ept_entry(ept_entry, new_entry);
@@ -749,7 +758,8 @@ void ept_change_entry_emt_with_range(struct domain *d,
  * quickly enable or diable log-dirty tracking
  */
 static void ept_change_entry_type_page(mfn_t ept_page_mfn, int ept_page_level,
-                                       p2m_type_t ot, p2m_type_t nt)
+                                       p2m_type_t ot, p2m_type_t nt,
+                                       struct domain *d, int mask)
 {
     ept_entry_t e, *epte = map_domain_page(mfn_x(ept_page_mfn));
 
@@ -760,15 +770,33 @@ static void ept_change_entry_type_page(mfn_t ept_page_mfn, int ept_page_level,
 
         if ( (ept_page_level > 0) && !is_epte_superpage(epte + i) )
             ept_change_entry_type_page(_mfn(epte[i].mfn),
-                                       ept_page_level - 1, ot, nt);
+                                       ept_page_level - 1, ot, nt, d, mask);
         else
         {
             e = atomic_read_ept_entry(&epte[i]);
             if ( e.sa_p2mt != ot )
                 continue;
 
+            if ( e.d && (e.sa_p2mt == p2m_ram_logdirty) )
+            {
+                int j, nr_pages;
+                struct p2m_domain *p2m = p2m_get_hostp2m(d);
+                for ( j = 0, nr_pages = 1; j < ept_page_level;
+                      j++, nr_pages *= 512 ) {}
+                for ( j = 0; j < nr_pages; j++ )
+                    paging_mark_dirty(d, e.mfn + j);
+
+                /* split super page to 4k page, so that dirty bitmap can 
+                 * map the dirty page
+                 */
+                if ( !ept_split_super_page(p2m, &e, ept_page_level, 0) )
+                    continue;
+                atomic_write_ept_entry(&epte[i], e);
+            }
             e.sa_p2mt = nt;
             ept_p2m_type_to_flags(&e, nt, e.access);
+            if (!mask)
+                e.a = e.d = 0;
             atomic_write_ept_entry(&epte[i], e);
         }
     }
@@ -786,7 +814,22 @@ static void ept_change_entry_type_global(struct p2m_domain *p2m,
     BUG_ON(p2m_is_grant(ot) || p2m_is_grant(nt));
     BUG_ON(ot != nt && (ot == p2m_mmio_direct || nt == p2m_mmio_direct));
 
-    ept_change_entry_type_page(_mfn(ept_get_asr(d)), ept_get_wl(d), ot, nt);
+    ept_change_entry_type_page(_mfn(ept_get_asr(d)), ept_get_wl(d),
+                               ot, nt, p2m->domain, WALK_EPT_UNUSED);
+
+    ept_sync_domain(d);
+}
+
+static void ept_query_entry_global(struct p2m_domain *p2m, int mask)
+{
+    struct domain *d = p2m->domain;
+    p2m_type_t ot = p2m_ram_logdirty;
+    p2m_type_t nt = p2m_ram_logdirty;
+    if ( ept_get_asr(d) == 0 )
+        return;
+
+    ept_change_entry_type_page(_mfn(ept_get_asr(d)), ept_get_wl(d),
+                               ot, nt, p2m->domain, mask);
 
     ept_sync_domain(d);
 }
@@ -796,6 +839,7 @@ void ept_p2m_init(struct p2m_domain *p2m)
     p2m->set_entry = ept_set_entry;
     p2m->get_entry = ept_get_entry;
     p2m->change_entry_type_global = ept_change_entry_type_global;
+    p2m->query_entry_global = ept_query_entry_global;
     p2m->audit_p2m = NULL;
 }
 
-- 
1.5.5

      parent reply	other threads:[~2012-06-19  6:28 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-19  6:28 [PATCH 0/4] xen: enable EPT A/D bit feature Xudong Hao
2012-06-19  6:28 ` [PATCH 1/4] xen: Add EPT A/D bits definitions Xudong Hao
2012-06-19  6:28 ` [PATCH 2/4] xen: add xen parameter to control A/D bits support Xudong Hao
2012-06-19  9:56   ` Jan Beulich
2012-06-20  1:24     ` Hao, Xudong
2012-06-19  6:28 ` [PATCH 3/4] xen: introduce new function update_dirty_bitmap Xudong Hao
2012-06-19  6:28 ` Xudong Hao [this message]

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=1340087306-6096-5-git-send-email-xudong.hao@intel.com \
    --to=xudong.hao@intel.com \
    --cc=JBeulich@suse.com \
    --cc=haitao.shan@intel.com \
    --cc=keir@xen.org \
    --cc=xen-devel@lists.xen.org \
    --cc=xiantao.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 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).