# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1278690342 -3600
# Node ID 42ccccfe1a6a3e418f86893a4457289adae8fe4d
# Parent 510c797ee115ba31f849d5377607f2193295ed3e
iommu: New options iommu=dom-strict and iommu=dom0-passthrough
The former strips dom0 of its usual 1:1 mapping of all memory, and
only provides it with mappings of its own memory, like any other
domain. The latter is a new consistent name for iommu=passthrough.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
xen/arch/x86/x86_64/mm.c | 22 ++++++++++---------
xen/drivers/passthrough/amd/pci_amd_iommu.c | 2 -
xen/drivers/passthrough/iommu.c | 31 ++++++++++++++++++++--------
xen/drivers/passthrough/vtd/iommu.c | 3 +-
4 files changed, 38 insertions(+), 20 deletions(-)
diff -r 510c797ee115 -r 42ccccfe1a6a xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c Fri Jul 09 15:39:35 2010 +0100
+++ b/xen/arch/x86/x86_64/mm.c Fri Jul 09 16:45:42 2010 +0100
@@ -1462,12 +1462,18 @@ int memory_add(unsigned long spfn, unsig
if ( ret )
goto destroy_m2p;
- for ( i = spfn; i < epfn; i++ )
- if ( iommu_map_page(dom0, i, i, IOMMUF_readable|IOMMUF_writable) )
- break;
-
- if ( i != epfn )
- goto destroy_iommu;
+ if ( !need_iommu(dom0) )
+ {
+ for ( i = spfn; i < epfn; i++ )
+ if ( iommu_map_page(dom0, i, i, IOMMUF_readable|IOMMUF_writable) )
+ break;
+ if ( i != epfn )
+ {
+ while (i-- > old_max)
+ iommu_unmap_page(dom0, i);
+ goto destroy_m2p;
+ }
+ }
/* We can't revert any more */
transfer_pages_to_heap(&info);
@@ -1475,10 +1481,6 @@ int memory_add(unsigned long spfn, unsig
share_hotadd_m2p_table(&info);
return 0;
-
-destroy_iommu:
- while (i-- > old_max)
- iommu_unmap_page(dom0, i);
destroy_m2p:
destroy_m2p_mapping(&info);
diff -r 510c797ee115 -r 42ccccfe1a6a xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Fri Jul 09 15:39:35
2010 +0100
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Fri Jul 09 16:45:42
2010 +0100
@@ -231,7 +231,7 @@ static int amd_iommu_domain_init(struct
{
unsigned long i;
- if ( !iommu_passthrough )
+ if ( !iommu_passthrough && !need_iommu(domain) )
{
/* setup 1:1 page table for dom0 */
for ( i = 0; i < max_page; i++ )
diff -r 510c797ee115 -r 42ccccfe1a6a xen/drivers/passthrough/iommu.c
--- a/xen/drivers/passthrough/iommu.c Fri Jul 09 15:39:35 2010 +0100
+++ b/xen/drivers/passthrough/iommu.c Fri Jul 09 16:45:42 2010 +0100
@@ -30,8 +30,8 @@ static int iommu_populate_page_table(str
* force|required Don't boot unless IOMMU is enabled
* workaround_bios_bug Workaround some bios issue to still enable
VT-d, don't guarantee security
- * passthrough Enable VT-d DMA passthrough (no DMA
- * translation for Dom0)
+ * dom0-passthrough No DMA translation at all for Dom0
+ * dom0-strict No 1:1 memory mapping for Dom0
* no-snoop Disable VT-d Snoop Control
* no-qinval Disable VT-d Queued Invalidation
* no-intremap Disable VT-d Interrupt Remapping
@@ -39,6 +39,7 @@ custom_param("iommu", parse_iommu_param)
custom_param("iommu", parse_iommu_param);
bool_t __read_mostly iommu_enabled = 1;
bool_t __read_mostly force_iommu;
+bool_t __read_mostly iommu_dom0_strict;
bool_t __read_mostly iommu_verbose;
bool_t __read_mostly iommu_workaround_bios_bug;
bool_t __read_mostly iommu_passthrough;
@@ -64,8 +65,6 @@ static void __init parse_iommu_param(cha
force_iommu = 1;
else if ( !strcmp(s, "workaround_bios_bug") )
iommu_workaround_bios_bug = 1;
- else if ( !strcmp(s, "passthrough") )
- iommu_passthrough = 1;
else if ( !strcmp(s, "verbose") )
iommu_verbose = 1;
else if ( !strcmp(s, "no-snoop") )
@@ -78,14 +77,18 @@ static void __init parse_iommu_param(cha
amd_iommu_debug = 1;
else if ( !strcmp(s, "amd-iommu-perdev-intremap") )
amd_iommu_perdev_intremap = 1;
+ else if ( !strcmp(s, "dom0-passthrough") )
+ iommu_passthrough = 1;
+ else if ( !strcmp(s, "dom0-strict") )
+ iommu_dom0_strict = 1;
s = ss + 1;
} while ( ss );
}
-int iommu_domain_init(struct domain *domain)
-{
- struct hvm_iommu *hd = domain_hvm_iommu(domain);
+int iommu_domain_init(struct domain *d)
+{
+ struct hvm_iommu *hd = domain_hvm_iommu(d);
spin_lock_init(&hd->mapping_lock);
INIT_LIST_HEAD(&hd->g2m_ioport_list);
@@ -94,8 +97,10 @@ int iommu_domain_init(struct domain *dom
if ( !iommu_enabled )
return 0;
+ d->need_iommu = ((d->domain_id == 0) && iommu_dom0_strict);
+
hd->platform_ops = iommu_get_ops();
- return hd->platform_ops->init(domain);
+ return hd->platform_ops->init(d);
}
int iommu_add_device(struct pci_dev *pdev)
@@ -276,6 +281,9 @@ int __init iommu_setup(void)
{
int rc = -ENODEV;
+ if ( iommu_dom0_strict )
+ iommu_passthrough = 0;
+
if ( iommu_enabled )
{
rc = iommu_hardware_setup();
@@ -290,8 +298,15 @@ int __init iommu_setup(void)
iommu_snoop = 0;
iommu_qinval = 0;
iommu_intremap = 0;
+ iommu_passthrough = 0;
+ iommu_dom0_strict = 0;
}
printk("I/O virtualisation %sabled\n", iommu_enabled ? "en" : "dis");
+ if ( iommu_enabled )
+ printk(" - Dom0 mode: %s\n",
+ iommu_passthrough ? "Passthrough" :
+ iommu_dom0_strict ? "Strict" : "Relaxed");
+
return rc;
}
diff -r 510c797ee115 -r 42ccccfe1a6a xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c Fri Jul 09 15:39:35 2010 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c Fri Jul 09 16:45:42 2010 +0100
@@ -1179,7 +1179,8 @@ static int intel_iommu_domain_init(struc
if ( d->domain_id == 0 )
{
/* Set up 1:1 page table for dom0 */
- iommu_set_dom0_mapping(d);
+ if ( !need_iommu(d) )
+ iommu_set_dom0_mapping(d);
setup_dom0_devices(d);
setup_dom0_rmrr(d);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|