|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 4/4] xen: enable EPT dirty bit for guest live migration
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@xxxxxxxxx>
Signed-off-by: Xudong Hao <xudong.hao@xxxxxxxxx>
---
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
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |