aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-05-26 08:24:55 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-05-26 08:24:55 +0100
commit7fefb0d6ae2b0949523e2933ac59d363450a9543 (patch)
tree2864601dc866d561a5149540900e3f4dfad882f8
parenta9f43ccc9e98b225fdcc4e0278313c3f3e563380 (diff)
downloadxen-7fefb0d6ae2b0949523e2933ac59d363450a9543.tar.gz
xen-7fefb0d6ae2b0949523e2933ac59d363450a9543.tar.bz2
xen-7fefb0d6ae2b0949523e2933ac59d363450a9543.zip
VT-d: remove Xen and tboot range from dom0's VT-d table
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>
-rw-r--r--xen/arch/x86/setup.c8
-rw-r--r--xen/arch/x86/tboot.c12
-rw-r--r--xen/drivers/passthrough/vtd/iommu.c14
3 files changed, 33 insertions, 1 deletions
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index bdf3866e01..94504c5561 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1100,6 +1100,14 @@ void arch_get_xen_caps(xen_capabilities_info_t *info)
#endif
}
+int xen_in_range(unsigned long start, unsigned long end)
+{
+ start = max_t(unsigned long, start, xenheap_phys_start);
+ end = min_t(unsigned long, end, xenheap_phys_end);
+
+ return start < end;
+}
+
/*
* Local variables:
* mode: C
diff --git a/xen/arch/x86/tboot.c b/xen/arch/x86/tboot.c
index 697ca9f461..37841c41fa 100644
--- a/xen/arch/x86/tboot.c
+++ b/xen/arch/x86/tboot.c
@@ -96,6 +96,18 @@ int tboot_in_measured_env(void)
return (g_tboot_shared != NULL);
}
+int tboot_in_range(unsigned long start, unsigned long end)
+{
+ if ( g_tboot_shared == NULL || g_tboot_shared->version < 0x02 )
+ return 0;
+
+ start = max_t(unsigned long, start, g_tboot_shared->tboot_base);
+ end = min_t(unsigned long, end,
+ g_tboot_shared->tboot_base + g_tboot_shared->tboot_size);
+
+ return start < end;
+}
+
/*
* Local variables:
* mode: C
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index 0e5186e255..1c831279ba 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1097,9 +1097,21 @@ static int intel_iommu_domain_init(struct domain *d)
if ( d->domain_id == 0 )
{
- /* Set up 1:1 page table for dom0. */
+ extern int xen_in_range(unsigned long start, unsigned long end);
+ extern int tboot_in_range(unsigned long start, unsigned long end);
+
+ /*
+ * Set up 1:1 page table for dom0 except the critical segments
+ * like Xen and tboot.
+ */
for ( i = 0; i < max_page; i++ )
+ {
+ 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(d, i, i);
+ }
setup_dom0_devices(d);
setup_dom0_rmrr(d);