[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 |