[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] vtd: Only enable some VT-d features if all VT-d engines support them.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1237376792 0 # Node ID 6d65dc14d21b5b598de925d1b1e0aa8305092273 # Parent 33270c9a3d2f56006a166b42ae0d717bc6b1644f vtd: Only enable some VT-d features if all VT-d engines support them. By default, we enable snoop control, queued invalidation and interrupt remapping if all VT-d engines support them, and for DMA passthrough we don't enable it by default. A user can use 'iommu=passthrough' to enable DMA passthrough (only for Dom0). A user can use 'iommu=no-snoop,no-qinval,no-intremap' to disable the 3 features. Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>= --- xen/drivers/passthrough/iommu.c | 18 ++++-- xen/drivers/passthrough/vtd/dmar.c | 2 xen/drivers/passthrough/vtd/iommu.c | 95 +++++++++++++++++++++--------------- xen/include/xen/iommu.h | 2 4 files changed, 74 insertions(+), 43 deletions(-) diff -r 33270c9a3d2f -r 6d65dc14d21b xen/drivers/passthrough/iommu.c --- a/xen/drivers/passthrough/iommu.c Wed Mar 18 11:37:59 2009 +0000 +++ b/xen/drivers/passthrough/iommu.c Wed Mar 18 11:46:32 2009 +0000 @@ -32,9 +32,11 @@ int amd_iov_detect(void); * pv Enable IOMMU for PV domains * no-pv Disable IOMMU for PV domains (default) * force|required Don't boot unless IOMMU is enabled - * passthrough Bypass VT-d translation for Dom0 - * snoop Utilize the snoop control for IOMMU (default) - * no-snoop Dont utilize the snoop control for IOMMU + * passthrough Enable VT-d DMA passthrough (no DMA + * translation for Dom0) + * no-snoop Disable VT-d Snoop Control + * no-qinval Disable VT-d Queued Invalidation + * no-intremap Disable VT-d Interrupt Remapping */ custom_param("iommu", parse_iommu_param); int iommu_enabled = 0; @@ -42,12 +44,16 @@ int force_iommu = 0; int force_iommu = 0; int iommu_passthrough = 0; int iommu_snoop = 0; +int iommu_qinval = 0; +int iommu_intremap = 0; static void __init parse_iommu_param(char *s) { char *ss; iommu_enabled = 1; iommu_snoop = 1; + iommu_qinval = 1; + iommu_intremap = 1; do { ss = strchr(s, ','); @@ -65,10 +71,12 @@ static void __init parse_iommu_param(cha force_iommu = 1; else if ( !strcmp(s, "passthrough") ) iommu_passthrough = 1; - else if ( !strcmp(s, "snoop") ) - iommu_snoop = 1; else if ( !strcmp(s, "no-snoop") ) iommu_snoop = 0; + else if ( !strcmp(s, "no-qinval") ) + iommu_qinval = 0; + else if ( !strcmp(s, "no-intremap") ) + iommu_intremap = 0; s = ss + 1; } while ( ss ); diff -r 33270c9a3d2f -r 6d65dc14d21b xen/drivers/passthrough/vtd/dmar.c --- a/xen/drivers/passthrough/vtd/dmar.c Wed Mar 18 11:37:59 2009 +0000 +++ b/xen/drivers/passthrough/vtd/dmar.c Wed Mar 18 11:46:32 2009 +0000 @@ -548,7 +548,7 @@ int acpi_dmar_init(void) if ( list_empty(&acpi_drhd_units) ) goto fail; - printk("Intel VT-d has been enabled\n"); + printk("Intel VT-d DMAR tables have been parsed.\n"); return 0; diff -r 33270c9a3d2f -r 6d65dc14d21b xen/drivers/passthrough/vtd/iommu.c --- a/xen/drivers/passthrough/vtd/iommu.c Wed Mar 18 11:37:59 2009 +0000 +++ b/xen/drivers/passthrough/vtd/iommu.c Wed Mar 18 11:46:32 2009 +0000 @@ -1041,8 +1041,7 @@ static int domain_context_mapping_one( return res; } - if ( iommu_passthrough && - ecap_pass_thru(iommu->ecap) && (domain->domain_id == 0) ) + if ( iommu_passthrough && (domain->domain_id == 0) ) { context_set_translation_type(*context, CONTEXT_TT_PASS_THRU); agaw = level_to_agaw(iommu->nr_pt_levels); @@ -1449,8 +1448,7 @@ int intel_iommu_map_page( iommu = drhd->iommu; /* do nothing if dom0 and iommu supports pass thru */ - if ( iommu_passthrough && - ecap_pass_thru(iommu->ecap) && (d->domain_id == 0) ) + if ( iommu_passthrough && (d->domain_id == 0) ) return 0; spin_lock(&hd->mapping_lock); @@ -1504,8 +1502,7 @@ int intel_iommu_unmap_page(struct domain iommu = drhd->iommu; /* do nothing if dom0 and iommu supports pass thru */ - if ( iommu_passthrough && - ecap_pass_thru(iommu->ecap) && (d->domain_id == 0) ) + if ( iommu_passthrough && (d->domain_id == 0) ) return 0; dma_pte_clear_one(d, (paddr_t)gfn << PAGE_SHIFT_4K); @@ -1682,20 +1679,32 @@ static int init_vtd_hw(void) flush->iotlb = flush_iotlb_reg; } - for_each_drhd_unit ( drhd ) - { - iommu = drhd->iommu; - if ( qinval_setup(iommu) != 0 ) - dprintk(XENLOG_INFO VTDPREFIX, - "Queued Invalidation hardware not found\n"); - } - - for_each_drhd_unit ( drhd ) - { - iommu = drhd->iommu; - if ( intremap_setup(iommu) != 0 ) - dprintk(XENLOG_INFO VTDPREFIX, - "Interrupt Remapping hardware not found\n"); + if ( iommu_qinval ) + { + for_each_drhd_unit ( drhd ) + { + iommu = drhd->iommu; + if ( qinval_setup(iommu) != 0 ) + { + dprintk(XENLOG_INFO VTDPREFIX, + "Failed to enable Queued Invalidation!\n"); + break; + } + } + } + + if ( iommu_intremap ) + { + for_each_drhd_unit ( drhd ) + { + iommu = drhd->iommu; + if ( intremap_setup(iommu) != 0 ) + { + dprintk(XENLOG_INFO VTDPREFIX, + "Failed to enable Interrupt Remapping!\n"); + break; + } + } } return 0; @@ -1744,9 +1753,35 @@ int intel_vtd_setup(void) spin_lock_init(&domid_bitmap_lock); clflush_size = get_cache_line_size(); + /* We enable the following features only if they are supported by all VT-d + * engines: Snoop Control, DMA passthrough, Queued Invalidation and + * Interrupt Remapping. + */ for_each_drhd_unit ( drhd ) + { if ( iommu_alloc(drhd) != 0 ) goto error; + + iommu = drhd->iommu; + + if ( iommu_snoop && !ecap_snp_ctl(iommu->ecap) ) + iommu_snoop = 0; + + if ( iommu_passthrough && !ecap_pass_thru(iommu->ecap) ) + iommu_passthrough = 0; + + if ( iommu_qinval && !ecap_queued_inval(iommu->ecap) ) + iommu_qinval = 0; + + if ( iommu_intremap && !ecap_intr_remap(iommu->ecap) ) + iommu_intremap = 0; + } +#define P(p,s) printk("Intel VT-d %s %ssupported.\n", s, (p)? "" : "not ") + P(iommu_snoop, "Snoop Control"); + P(iommu_passthrough, "DMA Passthrough"); + P(iommu_qinval, "Queued Invalidation"); + P(iommu_intremap, "Interrupt Remapping"); +#undef P /* Allocate IO page directory page for the domain. */ drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list); @@ -1764,23 +1799,6 @@ int intel_vtd_setup(void) if ( init_vtd_hw() ) goto error; - /* Giving that all devices within guest use same io page table, - * enable snoop control only if all VT-d engines support it. - */ - - if ( iommu_snoop ) - { - for_each_drhd_unit ( drhd ) - { - iommu = drhd->iommu; - if ( !ecap_snp_ctl(iommu->ecap) ) { - iommu_snoop = 0; - break; - } - } - } - - printk("Intel VT-d snoop control %sabled\n", iommu_snoop ? "en" : "dis"); register_keyhandler('V', dump_iommu_info, "dump iommu info"); return 0; @@ -1790,6 +1808,9 @@ int intel_vtd_setup(void) iommu_free(drhd); vtd_enabled = 0; iommu_snoop = 0; + iommu_passthrough = 0; + iommu_qinval = 0; + iommu_intremap = 0; return -ENOMEM; } diff -r 33270c9a3d2f -r 6d65dc14d21b xen/include/xen/iommu.h --- a/xen/include/xen/iommu.h Wed Mar 18 11:37:59 2009 +0000 +++ b/xen/include/xen/iommu.h Wed Mar 18 11:46:32 2009 +0000 @@ -32,6 +32,8 @@ extern int force_iommu; extern int force_iommu; extern int iommu_passthrough; extern int iommu_snoop; +extern int iommu_qinval; +extern int iommu_intremap; #define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |