]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
x86/HVM: consolidate passthrough handling in epte_get_entry_emt()
authorJan Beulich <jbeulich@suse.com>
Mon, 10 Mar 2014 10:04:36 +0000 (11:04 +0100)
committerJan Beulich <jbeulich@suse.com>
Mon, 10 Mar 2014 10:04:36 +0000 (11:04 +0100)
It is inconsistent to depend on iommu_enabled alone: For a guest
without devices passed through to it, it is of no concern whether the
IOMMU is enabled.

There's one rather special case to take care of: VMX code marks the
LAPIC access page as MMIO. The added assertion needs to take this into
consideration, and the subsequent handling of the direct MMIO case was
inconsistent too: That page would have been WB in the absence of an
IOMMU, but UC in the presence of it, while in fact the cachabilty of
this page is entirely unrelated to an IOMMU being in use.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: "Xu, Dongxiao" <dongxiao.xu@intel.com>
Acked-by: Keir Fraser <keir@xen.org>
xen/arch/x86/hvm/mtrr.c
xen/arch/x86/hvm/vmx/vmx.c

index b33bf34200e299c1b5d3d5576998bc2f582150b7..dd1561ead6f0af2b3e9d24b2287f23aa4dcc54b1 100644 (file)
@@ -698,14 +698,20 @@ uint8_t epte_get_entry_emt(struct domain *d, unsigned long gfn, mfn_t mfn,
     if ( hvm_get_mem_pinned_cacheattr(d, gfn, &type) )
         return type;
 
-    if ( !iommu_enabled )
+    if ( !iommu_enabled ||
+         (rangeset_is_empty(d->iomem_caps) &&
+          rangeset_is_empty(d->arch.ioport_caps) &&
+          !has_arch_pdevs(d)) )
     {
+        ASSERT(!direct_mmio ||
+               mfn_x(mfn) == d->arch.hvm_domain.vmx.apic_access_mfn);
         *ipat = 1;
         return MTRR_TYPE_WRBACK;
     }
 
     if ( direct_mmio )
-        return MTRR_TYPE_UNCACHABLE;
+        return mfn_x(mfn) != d->arch.hvm_domain.vmx.apic_access_mfn
+               ? MTRR_TYPE_UNCACHABLE : MTRR_TYPE_WRBACK;
 
     if ( iommu_snoop )
     {
index 8395e8698ee5b6154cf2791455ee005cacfb2ce6..94dc968d41a94f6be042d2e4ca8ba9ae572f22ed 100644 (file)
@@ -2090,9 +2090,9 @@ static int vmx_alloc_vlapic_mapping(struct domain *d)
     if ( apic_va == NULL )
         return -ENOMEM;
     share_xen_page_with_guest(virt_to_page(apic_va), d, XENSHARE_writable);
+    d->arch.hvm_domain.vmx.apic_access_mfn = virt_to_mfn(apic_va);
     set_mmio_p2m_entry(d, paddr_to_pfn(APIC_DEFAULT_PHYS_BASE),
         _mfn(virt_to_mfn(apic_va)));
-    d->arch.hvm_domain.vmx.apic_access_mfn = virt_to_mfn(apic_va);
 
     return 0;
 }