[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] vt-d: Clean up VT-d code
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1195232510 0 # Node ID 03d6d0f96e12d3a3c818709b26a19fb63ca4d09f # Parent 614dad9f8fdcda21b5e0083cce3320b17bfcefdd vt-d: Clean up VT-d code Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx> --- xen/arch/x86/hvm/vmx/vtd/dmar.c | 463 ++++++++++++++++++--------------- xen/arch/x86/hvm/vmx/vtd/intel-iommu.c | 89 ++---- xen/arch/x86/hvm/vmx/vtd/pci-direct.h | 22 - 3 files changed, 306 insertions(+), 268 deletions(-) diff -r 614dad9f8fdc -r 03d6d0f96e12 xen/arch/x86/hvm/vmx/vtd/dmar.c --- a/xen/arch/x86/hvm/vmx/vtd/dmar.c Fri Nov 16 16:53:43 2007 +0000 +++ b/xen/arch/x86/hvm/vmx/vtd/dmar.c Fri Nov 16 17:01:50 2007 +0000 @@ -38,7 +38,8 @@ boolean_param("vtd", vtd_enabled); #define PREFIX VTDPREFIX "ACPI DMAR:" #define DEBUG -#define MIN_SCOPE_LEN (sizeof(struct acpi_pci_path) + sizeof(struct acpi_dev_scope)) +#define MIN_SCOPE_LEN (sizeof(struct acpi_pci_path) + \ + sizeof(struct acpi_dev_scope)) LIST_HEAD(acpi_drhd_units); LIST_HEAD(acpi_rmrr_units); @@ -53,7 +54,7 @@ static int __init acpi_register_drhd_uni * add INCLUDE_ALL at the tail, so scan the list will find it at * the very end. */ - if (drhd->include_all) + if ( drhd->include_all ) list_add_tail(&drhd->list, &acpi_drhd_units); else list_add(&drhd->list, &acpi_drhd_units); @@ -67,13 +68,14 @@ static int __init acpi_register_rmrr_uni } static int acpi_pci_device_match(struct pci_dev *devices, int cnt, - struct pci_dev *dev) + struct pci_dev *dev) { int i; - for (i = 0; i < cnt; i++) { - if ((dev->bus == devices->bus) && - (dev->devfn == devices->devfn)) + for ( i = 0; i < cnt; i++ ) + { + if ( (dev->bus == devices->bus) && + (dev->devfn == devices->devfn) ) return 1; devices++; } @@ -86,7 +88,7 @@ static int __init acpi_register_atsr_uni * add ALL_PORTS at the tail, so scan the list will find it at * the very end. */ - if (atsr->all_ports) + if ( atsr->all_ports ) list_add_tail(&atsr->list, &acpi_atsr_units); else list_add(&atsr->list, &acpi_atsr_units); @@ -99,11 +101,12 @@ struct acpi_drhd_unit * acpi_find_matche struct acpi_drhd_unit *include_all_drhd; include_all_drhd = NULL; - list_for_each_entry(drhd, &acpi_drhd_units, list) { - if (drhd->include_all) + list_for_each_entry ( drhd, &acpi_drhd_units, list ) + { + if ( drhd->include_all ) include_all_drhd = drhd; - if (acpi_pci_device_match(drhd->devices, - drhd->devices_cnt, dev)) + if ( acpi_pci_device_match(drhd->devices, + drhd->devices_cnt, dev) ) { gdprintk(XENLOG_INFO VTDPREFIX, "acpi_find_matched_drhd_unit: drhd->address = %lx\n", @@ -112,28 +115,29 @@ struct acpi_drhd_unit * acpi_find_matche } } - if (include_all_drhd) { + if ( include_all_drhd ) + { gdprintk(XENLOG_INFO VTDPREFIX, "acpi_find_matched_drhd_unit:include_all_drhd->addr = %lx\n", include_all_drhd->address); return include_all_drhd;; } - return(NULL); + return NULL; } struct acpi_rmrr_unit * acpi_find_matched_rmrr_unit(struct pci_dev *dev) { struct acpi_rmrr_unit *rmrr; - list_for_each_entry(rmrr, &acpi_rmrr_units, list) { - if (acpi_pci_device_match(rmrr->devices, - rmrr->devices_cnt, dev)) - goto out; - } - rmrr = NULL; -out: - return rmrr; + list_for_each_entry ( rmrr, &acpi_rmrr_units, list ) + { + if ( acpi_pci_device_match(rmrr->devices, + rmrr->devices_cnt, dev) ) + return rmrr; + } + + return NULL; } struct acpi_atsr_unit * acpi_find_matched_atsr_unit(struct pci_dev *dev) @@ -142,142 +146,186 @@ struct acpi_atsr_unit * acpi_find_matche struct acpi_atsr_unit *all_ports_atsru; all_ports_atsru = NULL; - list_for_each_entry(atsru, &acpi_atsr_units, list) { - if (atsru->all_ports) + list_for_each_entry ( atsru, &acpi_atsr_units, list ) + { + if ( atsru->all_ports ) all_ports_atsru = atsru; - if (acpi_pci_device_match(atsru->devices, atsru->devices_cnt, dev)) + if ( acpi_pci_device_match(atsru->devices, + atsru->devices_cnt, dev) ) return atsru; } - if (all_ports_atsru) { - gdprintk(XENLOG_INFO VTDPREFIX, + + if ( all_ports_atsru ) + { + gdprintk(XENLOG_INFO VTDPREFIX, "acpi_find_matched_atsr_unit: all_ports_atsru\n"); return all_ports_atsru;; } - return(NULL); + + return NULL; +} + +static int scope_device_count(void *start, void *end) +{ + struct acpi_dev_scope *scope; + u8 bus, sub_bus, sec_bus; + struct acpi_pci_path *path; + int depth, count = 0; + u8 dev, func; + u32 l; + + while ( start < end ) + { + scope = start; + if ( scope->length < MIN_SCOPE_LEN ) + { + printk(KERN_WARNING PREFIX "Invalid device scope\n"); + return -EINVAL; + } + + path = (struct acpi_pci_path *)(scope + 1); + bus = scope->start_bus; + depth = (scope->length - sizeof(struct acpi_dev_scope)) + / sizeof(struct acpi_pci_path); + while ( --depth ) + { + bus = read_pci_config_byte( + bus, path->dev, path->fn, PCI_SECONDARY_BUS); + path++; + } + + if ( scope->dev_type == ACPI_DEV_ENDPOINT ) + { + printk(KERN_INFO PREFIX + "found endpoint: bdf = %x:%x:%x\n", + bus, path->dev, path->fn); + count++; + } + else if ( scope->dev_type == ACPI_DEV_P2PBRIDGE ) + { + printk(KERN_INFO PREFIX + "found bridge: bdf = %x:%x:%x\n", + bus, path->dev, path->fn); + sec_bus = read_pci_config_byte( + bus, path->dev, path->fn, PCI_SECONDARY_BUS); + sub_bus = read_pci_config_byte( + bus, path->dev, path->fn, PCI_SUBORDINATE_BUS); + + while ( sec_bus <= sub_bus ) + { + for ( dev = 0; dev < 32; dev++ ) + { + for ( func = 0; func < 8; func++ ) + { + l = read_pci_config( + sec_bus, dev, func, PCI_VENDOR_ID); + + /* some broken boards return 0 or + * ~0 if a slot is empty + */ + if ( l == 0xffffffff || l == 0x00000000 || + l == 0x0000ffff || l == 0xffff0000 ) + break; + count++; + } + } + sec_bus++; + } + } + else if ( scope->dev_type == ACPI_DEV_IOAPIC ) + { + printk(KERN_INFO PREFIX + "found IOAPIC: bdf = %x:%x:%x\n", + bus, path->dev, path->fn); + count++; + } + else + { + printk(KERN_INFO PREFIX + "found MSI HPET: bdf = %x:%x:%x\n", + bus, path->dev, path->fn); + count++; + } + + start += scope->length; + } + + return count; } static int __init acpi_parse_dev_scope(void *start, void *end, int *cnt, - struct pci_dev **devices) + struct pci_dev **devices) { struct acpi_dev_scope *scope; u8 bus, sub_bus, sec_bus; struct acpi_pci_path *path; struct acpi_ioapic_unit *acpi_ioapic_unit = NULL; - int count, dev_count=0; + int depth; struct pci_dev *pdev; u8 dev, func; u32 l; - void *tmp; - - *cnt = 0; - tmp = start; - while (start < end) { - scope = start; - if (scope->length < MIN_SCOPE_LEN || - (scope->dev_type != ACPI_DEV_ENDPOINT && - scope->dev_type != ACPI_DEV_P2PBRIDGE)) { - printk(KERN_WARNING PREFIX "Invalid device scope\n"); - return -EINVAL; - } - (*cnt)++; - start += scope->length; - } - - start = tmp; - while (start < end) { + + *cnt = scope_device_count(start, end); + if ( *cnt == 0 ) + { + printk(KERN_INFO PREFIX "acpi_parse_dev_scope: no device\n"); + return 0; + } + + *devices = xmalloc_array(struct pci_dev, *cnt); + if ( !*devices ) + return -ENOMEM; + memset(*devices, 0, sizeof(struct pci_dev) * (*cnt)); + + pdev = *devices; + while ( start < end ) + { scope = start; path = (struct acpi_pci_path *)(scope + 1); - count = (scope->length - sizeof(struct acpi_dev_scope)) - /sizeof(struct acpi_pci_path); + depth = (scope->length - sizeof(struct acpi_dev_scope)) + / sizeof(struct acpi_pci_path); bus = scope->start_bus; - while (--count) { - bus = read_pci_config_byte(bus, path->dev, - path->fn, PCI_SECONDARY_BUS); + while ( --depth ) + { + bus = read_pci_config_byte( + bus, path->dev, path->fn, PCI_SECONDARY_BUS); path++; } - if (scope->dev_type == ACPI_DEV_ENDPOINT) { - printk(KERN_WARNING PREFIX - "found endpoint: bdf = %x:%x:%x\n", bus, path->dev, path->fn); - dev_count++; - } else if (scope->dev_type == ACPI_DEV_P2PBRIDGE) { - printk(KERN_WARNING PREFIX - "found bridge: bdf = %x:%x:%x\n", bus, path->dev, path->fn); - - sec_bus = read_pci_config_byte(bus, path->dev, - path->fn, PCI_SECONDARY_BUS); - sub_bus = read_pci_config_byte(bus, path->dev, - path->fn, PCI_SUBORDINATE_BUS); - while (sec_bus <= sub_bus) { - for (dev = 0; dev < 32; dev++) { - for (func = 0; func < 8; func++) { - l = read_pci_config(sec_bus, dev, func, PCI_VENDOR_ID); - - /* some broken boards return 0 or ~0 if a slot is empty: */ - if (l == 0xffffffff || l == 0x00000000 || - l == 0x0000ffff || l == 0xffff0000) - break; - dev_count++; - } - } - sec_bus++; - } - } else if (scope->dev_type == ACPI_DEV_IOAPIC) { - printk(KERN_WARNING PREFIX - "found IOAPIC: bdf = %x:%x:%x\n", bus, path->dev, path->fn); - dev_count++; - } else { - printk(KERN_WARNING PREFIX - "found MSI HPET: bdf = %x:%x:%x\n", bus, path->dev, path->fn); - dev_count++; - } - - start += scope->length; - } - - *cnt = dev_count; - *devices = xmalloc_array(struct pci_dev, *cnt); - if (!*devices) - return -ENOMEM; - memset(*devices, 0, sizeof(struct pci_dev) * (*cnt)); - - pdev = *devices; - start = tmp; - while (start < end) { - scope = start; - path = (struct acpi_pci_path *)(scope + 1); - count = (scope->length - sizeof(struct acpi_dev_scope)) - /sizeof(struct acpi_pci_path); - bus = scope->start_bus; - - while (--count) { - bus = read_pci_config_byte(bus, path->dev, path->fn, PCI_SECONDARY_BUS); - path++; - } - - if (scope->dev_type == ACPI_DEV_ENDPOINT) { - printk(KERN_WARNING PREFIX - "found endpoint: bdf = %x:%x:%x\n", bus, path->dev, path->fn); - + if ( scope->dev_type == ACPI_DEV_ENDPOINT ) + { + printk(KERN_INFO PREFIX + "found endpoint: bdf = %x:%x:%x\n", + bus, path->dev, path->fn); pdev->bus = bus; pdev->devfn = PCI_DEVFN(path->dev, path->fn); pdev++; - } else if (scope->dev_type == ACPI_DEV_P2PBRIDGE) { - printk(KERN_WARNING PREFIX - "found bridge: bus = %x dev = %x func = %x\n", bus, path->dev, path->fn); - - sec_bus = read_pci_config_byte(bus, path->dev, path->fn, PCI_SECONDARY_BUS); - sub_bus = read_pci_config_byte(bus, path->dev, path->fn, PCI_SUBORDINATE_BUS); - - while (sec_bus <= sub_bus) { - for (dev = 0; dev < 32; dev++) { - for (func = 0; func < 8; func++) { - l = read_pci_config(sec_bus, dev, func, PCI_VENDOR_ID); - - /* some broken boards return 0 or ~0 if a slot is empty: */ - if (l == 0xffffffff || l == 0x00000000 || - l == 0x0000ffff || l == 0xffff0000) + } + else if ( scope->dev_type == ACPI_DEV_P2PBRIDGE ) + { + printk(KERN_INFO PREFIX + "found bridge: bus = %x dev = %x func = %x\n", + bus, path->dev, path->fn); + sec_bus = read_pci_config_byte( + bus, path->dev, path->fn, PCI_SECONDARY_BUS); + sub_bus = read_pci_config_byte( + bus, path->dev, path->fn, PCI_SUBORDINATE_BUS); + + while ( sec_bus <= sub_bus ) + { + for ( dev = 0; dev < 32; dev++ ) + { + for ( func = 0; func < 8; func++ ) + { + l = read_pci_config( + sec_bus, dev, func, PCI_VENDOR_ID); + + /* some broken boards return 0 or + * ~0 if a slot is empty + */ + if ( l == 0xffffffff || l == 0x00000000 || + l == 0x0000ffff || l == 0xffff0000 ) break; pdev->bus = sec_bus; @@ -287,19 +335,25 @@ static int __init acpi_parse_dev_scope(v } sec_bus++; } - } else if (scope->dev_type == ACPI_DEV_IOAPIC) { + } + else if ( scope->dev_type == ACPI_DEV_IOAPIC ) + { acpi_ioapic_unit = xmalloc(struct acpi_ioapic_unit); + if ( !acpi_ioapic_unit ) + return -ENOMEM; acpi_ioapic_unit->apic_id = scope->enum_id; acpi_ioapic_unit->ioapic.bdf.bus = bus; acpi_ioapic_unit->ioapic.bdf.dev = path->dev; acpi_ioapic_unit->ioapic.bdf.func = path->fn; list_add(&acpi_ioapic_unit->list, &acpi_ioapic_units); - printk(KERN_WARNING PREFIX - "found IOAPIC: bus = %x dev = %x func = %x\n", bus, path->dev, path->fn); - } else { - printk(KERN_WARNING PREFIX - "found MSI HPET: bus = %x dev = %x func = %x\n", bus, path->dev, path->fn); - } + printk(KERN_INFO PREFIX + "found IOAPIC: bus = %x dev = %x func = %x\n", + bus, path->dev, path->fn); + } + else + printk(KERN_INFO PREFIX + "found MSI HPET: bus = %x dev = %x func = %x\n", + bus, path->dev, path->fn); start += scope->length; } @@ -316,31 +370,33 @@ acpi_parse_one_drhd(struct acpi_dmar_ent static int include_all; dmaru = xmalloc(struct acpi_drhd_unit); - if (!dmaru) + if ( !dmaru ) return -ENOMEM; memset(dmaru, 0, sizeof(struct acpi_drhd_unit)); dmaru->address = drhd->address; dmaru->include_all = drhd->flags & 1; /* BIT0: INCLUDE_ALL */ - printk(KERN_WARNING PREFIX "dmaru->address = %lx\n", dmaru->address); - - if (!dmaru->include_all) { - ret = acpi_parse_dev_scope((void *)(drhd + 1), - ((void *)drhd) + header->length, - &dmaru->devices_cnt, &dmaru->devices); - } - else { - printk(KERN_WARNING PREFIX "found INCLUDE_ALL\n"); + printk(KERN_INFO PREFIX "dmaru->address = %lx\n", dmaru->address); + + if ( !dmaru->include_all ) + ret = acpi_parse_dev_scope( + (void *)(drhd + 1), + ((void *)drhd) + header->length, + &dmaru->devices_cnt, &dmaru->devices); + else + { + printk(KERN_INFO PREFIX "found INCLUDE_ALL\n"); /* Only allow one INCLUDE_ALL */ - if (include_all) { + if ( include_all ) + { printk(KERN_WARNING PREFIX "Only one INCLUDE_ALL " - "device scope is allowed\n"); + "device scope is allowed\n"); ret = -EINVAL; } include_all = 1; } - if (ret) + if ( ret ) xfree(dmaru); else acpi_register_drhd_unit(dmaru); @@ -355,23 +411,22 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent int ret = 0; rmrru = xmalloc(struct acpi_rmrr_unit); - if (!rmrru) + if ( !rmrru ) return -ENOMEM; memset(rmrru, 0, sizeof(struct acpi_rmrr_unit)); -#ifdef VTD_DEBUG - gdprintk(XENLOG_INFO VTDPREFIX, - "acpi_parse_one_rmrr: base = %lx end = %lx\n", - rmrr->base_address, rmrr->end_address); -#endif - rmrru->base_address = rmrr->base_address; rmrru->end_address = rmrr->end_address; - ret = acpi_parse_dev_scope((void *)(rmrr + 1), - ((void*)rmrr) + header->length, - &rmrru->devices_cnt, &rmrru->devices); - - if (ret || (rmrru->devices_cnt == 0)) + printk(KERN_INFO PREFIX + "acpi_parse_one_rmrr: base=%"PRIx64" end=%"PRIx64"\n", + rmrr->base_address, rmrr->end_address); + + ret = acpi_parse_dev_scope( + (void *)(rmrr + 1), + ((void*)rmrr) + header->length, + &rmrru->devices_cnt, &rmrru->devices); + + if ( ret || (rmrru->devices_cnt == 0) ) xfree(rmrru); else acpi_register_rmrr_unit(rmrru); @@ -387,90 +442,79 @@ acpi_parse_one_atsr(struct acpi_dmar_ent static int all_ports; atsru = xmalloc(struct acpi_atsr_unit); - if (!atsru) + if ( !atsru ) return -ENOMEM; memset(atsru, 0, sizeof(struct acpi_atsr_unit)); atsru->all_ports = atsr->flags & 1; /* BIT0: ALL_PORTS */ - if (!atsru->all_ports) { - ret = acpi_parse_dev_scope((void *)(atsr + 1), - ((void *)atsr) + header->length, - &atsru->devices_cnt, &atsru->devices); - } - else { - printk(KERN_WARNING PREFIX "found ALL_PORTS\n"); + if ( !atsru->all_ports ) + ret = acpi_parse_dev_scope( + (void *)(atsr + 1), + ((void *)atsr) + header->length, + &atsru->devices_cnt, &atsru->devices); + else + { + printk(KERN_INFO PREFIX "found ALL_PORTS\n"); /* Only allow one ALL_PORTS */ - if (all_ports) { + if ( all_ports ) + { printk(KERN_WARNING PREFIX "Only one ALL_PORTS " - "device scope is allowed\n"); + "device scope is allowed\n"); ret = -EINVAL; } all_ports = 1; } - if (ret) + if ( ret ) xfree(atsr); else acpi_register_atsr_unit(atsru); return ret; } -static void __init -acpi_table_print_dmar_entry(struct acpi_dmar_entry_header *header) -{ - struct acpi_table_drhd *drhd; - struct acpi_table_rmrr *rmrr; - - switch (header->type) { - case ACPI_DMAR_DRHD: - drhd = (struct acpi_table_drhd *)header; - break; - case ACPI_DMAR_RMRR: - rmrr = (struct acpi_table_rmrr *)header; - break; - } -} - -static int __init -acpi_parse_dmar(unsigned long phys_addr, unsigned long size) +static int __init acpi_parse_dmar(unsigned long phys_addr, + unsigned long size) { struct acpi_table_dmar *dmar = NULL; struct acpi_dmar_entry_header *entry_header; int ret = 0; - if (!phys_addr || !size) + if ( !phys_addr || !size ) return -EINVAL; dmar = (struct acpi_table_dmar *)__acpi_map_table(phys_addr, size); - if (!dmar) { - printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); + if ( !dmar ) + { + printk(KERN_WARNING PREFIX "Unable to map DMAR\n"); return -ENODEV; } - if (!dmar->haw) { - printk (KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n"); + if ( !dmar->haw ) + { + printk(KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n"); return -EINVAL; } dmar_host_address_width = dmar->haw; - printk (KERN_INFO PREFIX "Host address width %d\n", - dmar_host_address_width); + printk(KERN_INFO PREFIX "Host address width %d\n", + dmar_host_address_width); entry_header = (struct acpi_dmar_entry_header *)(dmar + 1); - while (((unsigned long)entry_header) < (((unsigned long)dmar) + size)) { - acpi_table_print_dmar_entry(entry_header); - - switch (entry_header->type) { + while ( ((unsigned long)entry_header) < + (((unsigned long)dmar) + size) ) + { + switch ( entry_header->type ) + { case ACPI_DMAR_DRHD: - printk (KERN_INFO PREFIX "found ACPI_DMAR_DRHD\n"); + printk(KERN_INFO PREFIX "found ACPI_DMAR_DRHD\n"); ret = acpi_parse_one_drhd(entry_header); break; case ACPI_DMAR_RMRR: - printk (KERN_INFO PREFIX "found ACPI_DMAR_RMRR\n"); + printk(KERN_INFO PREFIX "found ACPI_DMAR_RMRR\n"); ret = acpi_parse_one_rmrr(entry_header); break; case ACPI_DMAR_ATSR: - printk (KERN_INFO PREFIX "found ACPI_DMAR_RMRR\n"); + printk(KERN_INFO PREFIX "found ACPI_DMAR_RMRR\n"); ret = acpi_parse_one_atsr(entry_header); break; default: @@ -478,7 +522,7 @@ acpi_parse_dmar(unsigned long phys_addr, ret = -EINVAL; break; } - if (ret) + if ( ret ) break; entry_header = ((void *)entry_header + entry_header->length); @@ -494,15 +538,16 @@ int acpi_dmar_init(void) { int rc; - if (!vtd_enabled) + if ( !vtd_enabled ) return -ENODEV; - if ((rc = vtd_hw_check()) != 0) + if ( (rc = vtd_hw_check()) != 0 ) return rc; acpi_table_parse(ACPI_DMAR, acpi_parse_dmar); - if (list_empty(&acpi_drhd_units)) { + if ( list_empty(&acpi_drhd_units) ) + { printk(KERN_ERR PREFIX "No DMAR devices found\n"); vtd_enabled = 0; return -ENODEV; diff -r 614dad9f8fdc -r 03d6d0f96e12 xen/arch/x86/hvm/vmx/vtd/intel-iommu.c --- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c Fri Nov 16 16:53:43 2007 +0000 +++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c Fri Nov 16 17:01:50 2007 +0000 @@ -533,6 +533,7 @@ static void dma_pte_clear_one(struct dom iommu_flush_write_buffer(iommu); } } + unmap_domain_page(pte); } /* clear last level pte, a tlb flush should be followed */ @@ -899,7 +900,7 @@ struct iommu *iommu_alloc(void *hw_data) { struct acpi_drhd_unit *drhd = (struct acpi_drhd_unit *) hw_data; struct iommu *iommu; - + if ( nr_iommus > MAX_IOMMUS ) { gdprintk(XENLOG_ERR VTDPREFIX, @@ -914,7 +915,7 @@ struct iommu *iommu_alloc(void *hw_data) 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); - dprintk(XENLOG_INFO VTDPREFIX, + dprintk(XENLOG_ERR VTDPREFIX, "iommu_alloc: iommu->reg = %p drhd->address = %lx\n", iommu->reg, drhd->address); nr_iommus++; @@ -1009,28 +1010,22 @@ static int domain_context_mapping_one( context = device_to_context_entry(iommu, bus, devfn); if ( !context ) { - gdprintk(XENLOG_INFO VTDPREFIX, + gdprintk(XENLOG_ERR VTDPREFIX, "domain_context_mapping_one:context == NULL:" "bdf = %x:%x:%x\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); return -ENOMEM; } - spin_lock_irqsave(&iommu->lock, flags); + if ( context_present(*context) ) { - spin_unlock_irqrestore(&iommu->lock, flags); gdprintk(XENLOG_INFO VTDPREFIX, "domain_context_mapping_one:context present:bdf=%x:%x:%x\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); return 0; } -#ifdef VTD_DEBUG - dprintk(XENLOG_INFO VTDPREFIX, - "context_mapping_one_1-%x:%x:%x-*context = %lx %lx\n", - bus, PCI_SLOT(devfn), PCI_FUNC(devfn), context->hi, context->lo); -#endif - + spin_lock_irqsave(&iommu->lock, flags); /* * domain_id 0 is not valid on Intel's IOMMU, force domain_id to * be 1 based as required by intel's iommu hw. @@ -1039,9 +1034,7 @@ static int domain_context_mapping_one( context_set_address_width(*context, hd->agaw); if ( ecap_pass_thru(iommu->ecap) ) - { context_set_translation_type(*context, CONTEXT_TT_PASS_THRU); - } else { context_set_address_root(*context, virt_to_maddr(hd->pgd)); @@ -1052,15 +1045,14 @@ static int domain_context_mapping_one( context_set_present(*context); iommu_flush_cache_entry(iommu, context); -#ifdef VTD_DEBUG - dprintk(XENLOG_INFO VTDPREFIX, - "context_mapping_one_2-%x:%x:%x-*context=%lx %lx hd->pgd = %p\n", - bus, PCI_SLOT(devfn), PCI_FUNC(devfn), - context->hi, context->lo, hd->pgd); -#endif + gdprintk(XENLOG_INFO VTDPREFIX, + "context_mapping_one-%x:%x:%x-*context=%"PRIx64":%"PRIx64 + " hd->pgd=%p\n", + bus, PCI_SLOT(devfn), PCI_FUNC(devfn), + context->hi, context->lo, hd->pgd); if ( iommu_flush_context_device(iommu, domain->domain_id, - (((u16)bus) << 8) | devfn, + (((u16)bus) << 8) | devfn, DMA_CCMD_MASK_NOBIT, 1) ) iommu_flush_write_buffer(iommu); else @@ -1177,14 +1169,12 @@ static int domain_context_mapping( pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); if ( pdev->bus == 0 ) - { ret = domain_context_mapping_one( domain, iommu, (u8)(pdev->bus), (u8)(pdev->devfn)); - } else { if ( bus2bridge[pdev->bus].bus != 0 ) - gdprintk(XENLOG_ERR VTDPREFIX, + gdprintk(XENLOG_WARNING VTDPREFIX, "domain_context_mapping:bus2bridge" "[pdev->bus].bus != 0\n"); @@ -1229,17 +1219,15 @@ static int domain_context_unmap_one( context = device_to_context_entry(iommu, bus, devfn); if ( !context ) { - gdprintk(XENLOG_INFO VTDPREFIX, + gdprintk(XENLOG_ERR VTDPREFIX, "domain_context_unmap_one-%x:%x:%x- context == NULL:return\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); return -ENOMEM; } - spin_lock_irqsave(&iommu->lock, flags); if ( !context_present(*context) ) { - spin_unlock_irqrestore(&iommu->lock, flags); - gdprintk(XENLOG_INFO VTDPREFIX, + gdprintk(XENLOG_WARNING VTDPREFIX, "domain_context_unmap_one-%x:%x:%x- " "context NOT present:return\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); @@ -1247,19 +1235,16 @@ static int domain_context_unmap_one( } gdprintk(XENLOG_INFO VTDPREFIX, - "domain_context_unmap_one_1:bdf = %x:%x:%x\n", + "domain_context_unmap_one: bdf = %x:%x:%x\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); + spin_lock_irqsave(&iommu->lock, flags); context_clear_present(*context); context_clear_entry(*context); iommu_flush_cache_entry(iommu, context); iommu_flush_context_global(iommu, 0); iommu_flush_iotlb_global(iommu, 0); spin_unlock_irqrestore(&iommu->lock, flags); - - gdprintk(XENLOG_INFO VTDPREFIX, - "domain_context_unmap_one_2:bdf = %x:%x:%x\n", - bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); return 0; } @@ -1302,15 +1287,13 @@ static int domain_context_unmap( "domain_context_unmap:PCI: bdf = %x:%x:%x\n", pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); if ( pdev->bus == 0 ) - { ret = domain_context_unmap_one( domain, iommu, (u8)(pdev->bus), (u8)(pdev->devfn)); - } else { if ( bus2bridge[pdev->bus].bus != 0 ) - gdprintk(XENLOG_INFO VTDPREFIX, + gdprintk(XENLOG_WARNING VTDPREFIX, "domain_context_mapping:" "bus2bridge[pdev->bus].bus != 0\n"); @@ -1318,7 +1301,7 @@ static int domain_context_unmap( (u8)(bus2bridge[pdev->bus].bus), (u8)(bus2bridge[pdev->bus].devfn)); - /* now map everything behind the PCI bridge */ + /* Unmap everything behind the PCI bridge */ for ( dev = 0; dev < 32; dev++ ) { for ( func = 0; func < 8; func++ ) @@ -1356,7 +1339,7 @@ void reassign_device_ownership( int status; unsigned long flags; - gdprintk(XENLOG_ERR VTDPREFIX, + gdprintk(XENLOG_INFO VTDPREFIX, "reassign_device-%x:%x:%x- source = %d target = %d\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn), source->domain_id, target->domain_id); @@ -1366,8 +1349,6 @@ void reassign_device_ownership( if ( (pdev->bus != bus) || (pdev->devfn != devfn) ) continue; - pdev->bus = bus; - pdev->devfn = devfn; drhd = acpi_find_matched_drhd_unit(pdev); iommu = drhd->iommu; domain_context_unmap(source, iommu, pdev); @@ -1825,9 +1806,9 @@ int assign_device(struct domain *d, u8 b if ( list_empty(&acpi_drhd_units) ) return ret; - dprintk(XENLOG_INFO VTDPREFIX, - "assign_device: bus = %x dev = %x func = %x\n", - bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); + gdprintk(XENLOG_INFO VTDPREFIX, + "assign_device: bus = %x dev = %x func = %x\n", + bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); reassign_device_ownership(dom0, d, bus, devfn); @@ -1870,12 +1851,16 @@ void iommu_set_pgd(struct domain *d) if ( !hd->pgd ) { pgd = (struct dma_pte *)alloc_xenheap_page(); - memset((u8*)pgd, 0, PAGE_SIZE); - if ( !hd->pgd ) - hd->pgd = pgd; - else /* somebody is fast */ - free_xenheap_page((void *) pgd); - } + if ( !pgd ) + { + spin_unlock_irqrestore(&hd->mapping_lock, flags); + gdprintk(XENLOG_ERR VTDPREFIX, + "Allocate pgd memory failed!\n"); + return; + } + memset(pgd, 0, PAGE_SIZE); + hd->pgd = pgd; + } l3e = map_domain_page(p2m_table); switch ( level ) @@ -1892,6 +1877,14 @@ void iommu_set_pgd(struct domain *d) case VTD_PAGE_TABLE_LEVEL_4: /* Stoakley */ /* We allocate one more page for the top vtd page table. */ pmd = (struct dma_pte *)alloc_xenheap_page(); + if ( !pmd ) + { + unmap_domain_page(l3e); + spin_unlock_irqrestore(&hd->mapping_lock, flags); + gdprintk(XENLOG_ERR VTDPREFIX, + "Allocate pmd memory failed!\n"); + return; + } memset((u8*)pmd, 0, PAGE_SIZE); pte = &pgd[0]; dma_set_pte_addr(*pte, virt_to_maddr(pmd)); diff -r 614dad9f8fdc -r 03d6d0f96e12 xen/arch/x86/hvm/vmx/vtd/pci-direct.h --- a/xen/arch/x86/hvm/vmx/vtd/pci-direct.h Fri Nov 16 16:53:43 2007 +0000 +++ b/xen/arch/x86/hvm/vmx/vtd/pci-direct.h Fri Nov 16 17:01:50 2007 +0000 @@ -5,15 +5,15 @@ #include <asm/io.h> /* Direct PCI access. This is used for PCI accesses in early boot before - the PCI subsystem works. */ + the PCI subsystem works. */ #define PDprintk(x...) static inline u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) { - u32 v; + u32 v; outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - v = inl(0xcfc); + v = inl(0xcfc); if (v != 0xffffffff) PDprintk("%x reading 4 from %x: %x\n", slot, offset, v); return v; @@ -21,28 +21,28 @@ static inline u32 read_pci_config(u8 bus static inline u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset) { - u8 v; + u8 v; outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - v = inb(0xcfc + (offset&3)); + v = inb(0xcfc + (offset&3)); PDprintk("%x reading 1 from %x: %x\n", slot, offset, v); return v; } static inline u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset) { - u16 v; + u16 v; outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - v = inw(0xcfc + (offset&2)); + v = inw(0xcfc + (offset&2)); PDprintk("%x reading 2 from %x: %x\n", slot, offset, v); return v; } -static inline void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, - u32 val) +static inline void write_pci_config( + u8 bus, u8 slot, u8 func, u8 offset, u32 val) { - PDprintk("%x writing to %x: %x\n", slot, offset, val); + PDprintk("%x writing to %x: %x\n", slot, offset, val); outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - outl(val, 0xcfc); + outl(val, 0xcfc); } #endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |