[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] iommu: initialisation cleanup and bugfix.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1208796089 -3600 # Node ID 8d20c24238ad21d7fb2457aebe523df2b6779a01 # Parent 84b5dee690f52236b7d048276b300028fef3a54a iommu: initialisation cleanup and bugfix. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/domain.c | 11 +- xen/arch/x86/setup.c | 2 xen/drivers/passthrough/iommu.c | 3 xen/drivers/passthrough/vtd/iommu.c | 133 +++++++++++------------------------- xen/include/xen/iommu.h | 1 5 files changed, 49 insertions(+), 101 deletions(-) diff -r 84b5dee690f5 -r 8d20c24238ad xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Mon Apr 21 14:59:25 2008 +0100 +++ b/xen/arch/x86/domain.c Mon Apr 21 17:41:29 2008 +0100 @@ -521,10 +521,10 @@ int arch_domain_create(struct domain *d, clear_page(d->shared_info); share_xen_page_with_guest( virt_to_page(d->shared_info), d, XENSHARE_writable); - } - - if ( (rc = iommu_domain_init(d)) != 0 ) - goto fail; + + if ( (rc = iommu_domain_init(d)) != 0 ) + goto fail; + } if ( is_hvm_domain(d) ) { @@ -562,7 +562,8 @@ void arch_domain_destroy(struct domain * if ( is_hvm_domain(d) ) hvm_domain_destroy(d); - iommu_domain_destroy(d); + if ( !is_idle_domain(d) ) + iommu_domain_destroy(d); paging_final_teardown(d); diff -r 84b5dee690f5 -r 8d20c24238ad xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Mon Apr 21 14:59:25 2008 +0100 +++ b/xen/arch/x86/setup.c Mon Apr 21 17:41:29 2008 +0100 @@ -1019,8 +1019,6 @@ void __init __start_xen(unsigned long mb _initrd_len = mod[initrdidx].mod_end - mod[initrdidx].mod_start; } - iommu_setup(); - /* * We're going to setup domain0 using the module(s) that we stashed safely * above our heap. The second module, if present, is an initrd ramdisk. diff -r 84b5dee690f5 -r 8d20c24238ad xen/drivers/passthrough/iommu.c --- a/xen/drivers/passthrough/iommu.c Mon Apr 21 14:59:25 2008 +0100 +++ b/xen/drivers/passthrough/iommu.c Mon Apr 21 17:41:29 2008 +0100 @@ -140,7 +140,7 @@ void deassign_device(struct domain *d, u return hd->platform_ops->reassign_device(d, dom0, bus, devfn); } -int iommu_setup(void) +static int iommu_setup(void) { int rc = -ENODEV; @@ -163,3 +163,4 @@ int iommu_setup(void) printk("I/O virtualisation %sabled\n", iommu_enabled ? "en" : "dis"); return rc; } +__initcall(iommu_setup); diff -r 84b5dee690f5 -r 8d20c24238ad xen/drivers/passthrough/vtd/iommu.c --- a/xen/drivers/passthrough/vtd/iommu.c Mon Apr 21 14:59:25 2008 +0100 +++ b/xen/drivers/passthrough/vtd/iommu.c Mon Apr 21 17:41:29 2008 +0100 @@ -78,7 +78,7 @@ static struct intel_iommu *alloc_intel_i struct intel_iommu *intel; intel = xmalloc(struct intel_iommu); - if ( !intel ) + if ( intel == NULL ) { gdprintk(XENLOG_ERR VTDPREFIX, "Allocate intel_iommu failed.\n"); @@ -88,7 +88,6 @@ static struct intel_iommu *alloc_intel_i spin_lock_init(&intel->qi_ctrl.qinval_lock); spin_lock_init(&intel->qi_ctrl.qinval_poll_lock); - spin_lock_init(&intel->ir_ctrl.iremap_lock); return intel; @@ -96,68 +95,22 @@ static struct intel_iommu *alloc_intel_i static void free_intel_iommu(struct intel_iommu *intel) { - if ( intel ) - { - xfree(intel); - intel = NULL; - } + xfree(intel); } struct qi_ctrl *iommu_qi_ctrl(struct iommu *iommu) { - if ( !iommu ) - return NULL; - - if ( !iommu->intel ) - { - iommu->intel = alloc_intel_iommu(); - if ( !iommu->intel ) - { - dprintk(XENLOG_ERR VTDPREFIX, - "iommu_qi_ctrl: Allocate iommu->intel failed.\n"); - return NULL; - } - } - - return &(iommu->intel->qi_ctrl); + return iommu ? &iommu->intel->qi_ctrl : NULL; } struct ir_ctrl *iommu_ir_ctrl(struct iommu *iommu) { - if ( !iommu ) - return NULL; - - if ( !iommu->intel ) - { - iommu->intel = alloc_intel_iommu(); - if ( !iommu->intel ) - { - dprintk(XENLOG_ERR VTDPREFIX, - "iommu_ir_ctrl: Allocate iommu->intel failed.\n"); - return NULL; - } - } - - return &(iommu->intel->ir_ctrl); + return iommu ? &iommu->intel->ir_ctrl : NULL; } struct iommu_flush *iommu_get_flush(struct iommu *iommu) { - if ( !iommu ) - return NULL; - - if ( !iommu->intel ) - { - iommu->intel = alloc_intel_iommu(); - if ( !iommu->intel ) - { - dprintk(XENLOG_ERR VTDPREFIX, - "iommu_get_flush: Allocate iommu->intel failed.\n"); - return NULL; - } - } - - return &(iommu->intel->flush); + return iommu ? &iommu->intel->flush : NULL; } unsigned int clflush_size; @@ -1039,69 +992,65 @@ int iommu_set_interrupt(struct iommu *io return vector; } -struct iommu *iommu_alloc(void *hw_data) -{ - struct acpi_drhd_unit *drhd = (struct acpi_drhd_unit *) hw_data; +static int iommu_alloc(struct acpi_drhd_unit *drhd) +{ struct iommu *iommu; if ( nr_iommus > MAX_IOMMUS ) { gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: nr_iommus %d > MAX_IOMMUS\n", nr_iommus); - return NULL; + return -ENOMEM; } iommu = xmalloc(struct iommu); - if ( !iommu ) - return NULL; + if ( iommu == NULL ) + return -ENOMEM; memset(iommu, 0, sizeof(struct iommu)); + iommu->intel = alloc_intel_iommu(); + if ( iommu->intel == NULL ) + { + xfree(iommu); + return -ENOMEM; + } + set_fixmap_nocache(FIX_IOMMU_REGS_BASE_0 + nr_iommus, drhd->address); - iommu->reg = (void *) fix_to_virt(FIX_IOMMU_REGS_BASE_0 + nr_iommus); - - printk("iommu_alloc: iommu->reg = %p drhd->address = %lx\n", - iommu->reg, drhd->address); - + iommu->reg = (void *)fix_to_virt(FIX_IOMMU_REGS_BASE_0 + nr_iommus); nr_iommus++; - - if ( !iommu->reg ) - { - printk(KERN_ERR VTDPREFIX "IOMMU: can't mapping the region\n"); - goto error; - } iommu->cap = dmar_readq(iommu->reg, DMAR_CAP_REG); iommu->ecap = dmar_readq(iommu->reg, DMAR_ECAP_REG); - printk("iommu_alloc: cap = %"PRIx64"\n",iommu->cap); - printk("iommu_alloc: ecap = %"PRIx64"\n", iommu->ecap); - spin_lock_init(&iommu->lock); spin_lock_init(&iommu->register_lock); - iommu->intel = alloc_intel_iommu(); drhd->iommu = iommu; - return iommu; - error: - xfree(iommu); - return NULL; -} - -static void free_iommu(struct iommu *iommu) -{ - if ( !iommu ) + return 0; +} + +static void iommu_free(struct acpi_drhd_unit *drhd) +{ + struct iommu *iommu = drhd->iommu; + + if ( iommu == NULL ) return; + if ( iommu->root_maddr != 0 ) { free_pgtable_maddr(iommu->root_maddr); iommu->root_maddr = 0; } + if ( iommu->reg ) iounmap(iommu->reg); + free_intel_iommu(iommu->intel); free_irq(iommu->vector); xfree(iommu); + + drhd->iommu = NULL; } #define guestwidth_to_adjustwidth(gaw) ({ \ @@ -1120,10 +1069,10 @@ static int intel_iommu_domain_init(struc unsigned long sagaw; struct acpi_drhd_unit *drhd; - for_each_drhd_unit ( drhd ) - iommu = drhd->iommu ? : iommu_alloc(drhd); - - /* calculate AGAW */ + drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list); + iommu = drhd->iommu; + + /* Calculate AGAW. */ if ( guest_width > cap_mgaw(iommu->cap) ) guest_width = cap_mgaw(iommu->cap); adjust_width = guestwidth_to_adjustwidth(guest_width); @@ -1913,8 +1862,11 @@ int intel_vtd_setup(void) spin_lock_init(&domid_bitmap_lock); INIT_LIST_HEAD(&hd->pdev_list); - /* setup clflush size */ clflush_size = get_clflush_size(); + + for_each_drhd_unit ( drhd ) + if ( iommu_alloc(drhd) != 0 ) + goto error; /* Allocate IO page directory page for the domain. */ drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list); @@ -1929,7 +1881,7 @@ int intel_vtd_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. */ for ( i = 0; i < max_page; i++ ) iommu_map_page(dom0, i, i); @@ -1944,10 +1896,7 @@ int intel_vtd_setup(void) error: for_each_drhd_unit ( drhd ) - { - iommu = drhd->iommu; - free_iommu(iommu); - } + iommu_free(drhd); vtd_enabled = 0; return -ENOMEM; } diff -r 84b5dee690f5 -r 8d20c24238ad xen/include/xen/iommu.h --- a/xen/include/xen/iommu.h Mon Apr 21 14:59:25 2008 +0100 +++ b/xen/include/xen/iommu.h Mon Apr 21 17:41:29 2008 +0100 @@ -71,7 +71,6 @@ struct iommu { struct intel_iommu *intel; }; -int iommu_setup(void); int iommu_domain_init(struct domain *d); void iommu_domain_destroy(struct domain *d); int device_assigned(u8 bus, u8 devfn); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |