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;