Index: xen-3.2.1-testing/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c =================================================================== --- xen-3.2.1-testing.orig/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c +++ xen-3.2.1-testing/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c @@ -28,6 +28,7 @@ #include <asm/delay.h> #include <asm/string.h> #include <asm/mm.h> +#include <asm/paging.h> #include <asm/iommu.h> #include <asm/hvm/vmx/intel-iommu.h> #include "dmar.h" @@ -1900,6 +1901,45 @@ void iommu_set_pgd(struct domain *d) } p2m_table = mfn_x(pagetable_get_mfn(d->arch.phys_table)); + if ( paging_mode_hap(d) ) + { + if ( !hd->pgd ) + { + int level = agaw_to_level(hd->agaw); + struct dma_pte *dpte = NULL; + mfn_t pgd_mfn; + + switch ( level ) + { + case VTD_PAGE_TABLE_LEVEL_3: + dpte = map_domain_page(p2m_table); + if ( !dma_pte_present(*dpte) ) + { + gdprintk(XENLOG_ERR VTDPREFIX, + "iommu_set_pgd: second level wasn't there\n"); + unmap_domain_page(dpte); + return; + } + pgd_mfn = _mfn(dma_pte_addr(*dpte) >> PAGE_SHIFT_4K); + unmap_domain_page(dpte); + hd->pgd = maddr_to_virt(pagetable_get_paddr( + pagetable_from_mfn(pgd_mfn))); + break; + + case VTD_PAGE_TABLE_LEVEL_4: + pgd_mfn = _mfn(p2m_table); + hd->pgd = maddr_to_virt(pagetable_get_paddr( + pagetable_from_mfn(pgd_mfn))); + break; + default: + gdprintk(XENLOG_ERR VTDPREFIX, + "iommu_set_pgd:Unsupported p2m table sharing level!\n"); + break; + } + } + } + else + { #if CONFIG_PAGING_LEVELS == 3 if ( !hd->pgd ) { @@ -2005,6 +2045,7 @@ void iommu_set_pgd(struct domain *d) } } #endif + } gdprintk(XENLOG_INFO VTDPREFIX, "iommu_set_pgd: hd->pgd = %p\n", hd->pgd); } Index: xen-3.2.1-testing/xen/arch/x86/mm/p2m-ept.c =================================================================== --- xen-3.2.1-testing.orig/xen/arch/x86/mm/p2m-ept.c +++ xen-3.2.1-testing/xen/arch/x86/mm/p2m-ept.c @@ -157,6 +157,9 @@ ept_set_entry(struct domain *d, unsigned else ept_entry->epte = 0; + if ( vtd_enabled && (p2mt == p2m_mmio_direct) && is_hvm_domain(d) ) + iommu_flush(d, gfn, (u64 *)ept_entry); + /* Success */ rv = 1;