]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
VT-d: remove Xen and tboot range from dom0's VT-d table
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 18 Jul 2008 10:29:29 +0000 (11:29 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 18 Jul 2008 10:29:29 +0000 (11:29 +0100)
This a step forward to fix the security hole introduced by dom0's 1:1
mapping VT-d table: remove the critical code and data from it. The
more flexible solution is to update dom0's VT-d table on demand as
what will be done for other PV domains. However, there could bring a
performance issue even with software optimization. Iotlb flush of some
hardware is time-consuming.

Signed-off-by: Yang, Xiaowei <xiaowei.yang@intel.com>
xen-unstable changeset 17725:c0c0f4fa88509b6f5e4fa9bf0687c7a6df53eeb8
xen-unstable date: Mon May 26 08:24:55 2008 +0100

----------------------------------------------------------------------

Fix 17725:c0c0f4fa8850: use type paddr_t instead of unsigned long for
physcial memory address Otherwise, the address overflows on PAE system
with memory size > 4G.

Signed-off-by: Yang, Xiaowei <xiaowei.yang@intel.com>
xen-unstable changeset 17734:e265878e8f657ca532ebe98b5bac233f395f2814
xen-unstable date: Tue May 27 10:35:10 2008 +0100

xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
xen/arch/x86/setup.c
xen/arch/x86/tboot.c

index 051d6929151207d3a4f8b960af5b98bb1d56df1e..699ea97ef538cd2999415b29aa80f4e462482949 100644 (file)
@@ -1788,7 +1788,7 @@ int iommu_setup(void)
     struct hvm_iommu *hd  = domain_hvm_iommu(dom0);
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu;
-    unsigned long i;
+    u64 i;
 
     if ( !vtd_enabled )
         return 0;
@@ -1814,9 +1814,21 @@ int iommu_setup(void)
     memset(domid_bitmap, 0, domid_bitmap_size / 8);
     set_bit(0, domid_bitmap);
 
-    /* setup 1:1 page table for dom0 */
+    /*
+     * Set up 1:1 page table for dom0 except the critical segments
+     * like Xen and tboot.
+     */
     for ( i = 0; i < max_page; i++ )
+    {
+        extern int xen_in_range(paddr_t start, paddr_t end);
+        extern int tboot_in_range(paddr_t start, paddr_t end);
+
+        if ( xen_in_range(i << PAGE_SHIFT_4K, (i + 1) << PAGE_SHIFT_4K) ||
+            tboot_in_range(i << PAGE_SHIFT_4K, (i + 1) << PAGE_SHIFT_4K) )
+            continue;
+
         iommu_map_page(dom0, i, i);
+    }
 
     if ( init_vtd_hw() )
         goto error;
index 4ffc8d1ae39229a40e822b2ba99d199696106010..5f2793a3bec6a9f18e4f37e973b98cc75a21ba44 100644 (file)
@@ -1082,6 +1082,14 @@ void arch_get_xen_caps(xen_capabilities_info_t *info)
 #endif
 }
 
+int xen_in_range(paddr_t start, paddr_t end)
+{
+    start = max_t(paddr_t, start, xenheap_phys_start);
+    end = min_t(paddr_t, end, xenheap_phys_end);
+    return start < end; 
+}
+
 /*
  * Local variables:
  * mode: C
index 697ca9f4613a116e224aad3935136bdd17f79730..ec4aa9436d5f4125e93aaa493a7fd17586d8fcb1 100644 (file)
@@ -96,6 +96,18 @@ int tboot_in_measured_env(void)
     return (g_tboot_shared != NULL);
 }
 
+int tboot_in_range(paddr_t start, paddr_t end)
+{
+    if ( g_tboot_shared == NULL || g_tboot_shared->version < 0x02 )
+        return 0;
+
+    start = max_t(paddr_t, start, g_tboot_shared->tboot_base);
+    end = min_t(paddr_t, end, 
+                g_tboot_shared->tboot_base + g_tboot_shared->tboot_size);
+    return start < end; 
+}
+
 /*
  * Local variables:
  * mode: C