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
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;
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;
#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
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