ia64/xen-unstable
changeset 18834:1975e33b79f1
vtd: cleanups
- potential issues in vtd_page_fault() handler
- wrong print messages
- existing ATS code in dmar.c.
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
- potential issues in vtd_page_fault() handler
- wrong print messages
- existing ATS code in dmar.c.
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Nov 26 11:08:45 2008 +0000 (2008-11-26) |
parents | 4ccee1299bc7 |
children | 32aecede4626 |
files | xen/drivers/passthrough/vtd/dmar.c xen/drivers/passthrough/vtd/dmar.h xen/drivers/passthrough/vtd/iommu.c xen/drivers/passthrough/vtd/iommu.h xen/drivers/passthrough/vtd/qinval.c |
line diff
1.1 --- a/xen/drivers/passthrough/vtd/dmar.c Wed Nov 26 11:07:44 2008 +0000 1.2 +++ b/xen/drivers/passthrough/vtd/dmar.c Wed Nov 26 11:08:45 2008 +0000 1.3 @@ -172,6 +172,28 @@ struct acpi_drhd_unit * acpi_find_matche 1.4 return found ? found : include_all; 1.5 } 1.6 1.7 +struct acpi_atsr_unit * acpi_find_matched_atsr_unit(u8 bus, u8 devfn) 1.8 +{ 1.9 + struct acpi_atsr_unit *atsr; 1.10 + struct acpi_atsr_unit *found = NULL, *include_all = NULL; 1.11 + int i; 1.12 + 1.13 + list_for_each_entry ( atsr, &acpi_atsr_units, list ) 1.14 + { 1.15 + for (i = 0; i < atsr->scope.devices_cnt; i++) 1.16 + if ( atsr->scope.devices[i] == PCI_BDF2(bus, devfn) ) 1.17 + return atsr; 1.18 + 1.19 + if ( test_bit(bus, atsr->scope.buses) ) 1.20 + found = atsr; 1.21 + 1.22 + if ( atsr->all_ports ) 1.23 + include_all = atsr; 1.24 + } 1.25 + 1.26 + return found ? found : include_all; 1.27 +} 1.28 + 1.29 /* 1.30 * Count number of devices in device scope. Do not include PCI sub 1.31 * hierarchies. 1.32 @@ -242,7 +264,6 @@ static int __init acpi_parse_dev_scope(v 1.33 switch ( acpi_scope->dev_type ) 1.34 { 1.35 case ACPI_DEV_P2PBRIDGE: 1.36 - { 1.37 sec_bus = pci_conf_read8( 1.38 bus, path->dev, path->fn, PCI_SECONDARY_BUS); 1.39 sub_bus = pci_conf_read8( 1.40 @@ -253,7 +274,6 @@ static int __init acpi_parse_dev_scope(v 1.41 1.42 dmar_scope_add_buses(scope, sec_bus, sub_bus); 1.43 break; 1.44 - } 1.45 1.46 case ACPI_DEV_MSI_HPET: 1.47 dprintk(XENLOG_INFO VTDPREFIX, "found MSI HPET: bdf = %x:%x.%x\n", 1.48 @@ -268,7 +288,6 @@ static int __init acpi_parse_dev_scope(v 1.49 break; 1.50 1.51 case ACPI_DEV_IOAPIC: 1.52 - { 1.53 dprintk(XENLOG_INFO VTDPREFIX, "found IOAPIC: bdf = %x:%x.%x\n", 1.54 bus, path->dev, path->fn); 1.55 1.56 @@ -288,7 +307,6 @@ static int __init acpi_parse_dev_scope(v 1.57 scope->devices[didx++] = PCI_BDF(bus, path->dev, path->fn); 1.58 break; 1.59 } 1.60 - } 1.61 1.62 start += acpi_scope->length; 1.63 }
2.1 --- a/xen/drivers/passthrough/vtd/dmar.h Wed Nov 26 11:07:44 2008 +0000 2.2 +++ b/xen/drivers/passthrough/vtd/dmar.h Wed Nov 26 11:08:45 2008 +0000 2.3 @@ -80,6 +80,7 @@ struct acpi_atsr_unit { 2.4 idx < rmrr->scope.devices_cnt; idx++) 2.5 2.6 struct acpi_drhd_unit * acpi_find_matched_drhd_unit(u8 bus, u8 devfn); 2.7 +struct acpi_atsr_unit * acpi_find_matched_atsr_unit(u8 bus, u8 devfn); 2.8 void dmar_scope_add_buses(struct dmar_scope *scope, u16 sec, u16 sub); 2.9 void dmar_scope_remove_buses(struct dmar_scope *scope, u16 sec, u16 sub); 2.10
3.1 --- a/xen/drivers/passthrough/vtd/iommu.c Wed Nov 26 11:07:44 2008 +0000 3.2 +++ b/xen/drivers/passthrough/vtd/iommu.c Wed Nov 26 11:08:45 2008 +0000 3.3 @@ -714,22 +714,22 @@ static void iommu_fault_status(u32 fault 3.4 if ( fault_status & DMA_FSTS_PFO ) 3.5 dprintk(XENLOG_ERR VTDPREFIX, 3.6 "iommu_fault_status: Fault Overflow\n"); 3.7 - else if ( fault_status & DMA_FSTS_PPF ) 3.8 + if ( fault_status & DMA_FSTS_PPF ) 3.9 dprintk(XENLOG_ERR VTDPREFIX, 3.10 "iommu_fault_status: Primary Pending Fault\n"); 3.11 - else if ( fault_status & DMA_FSTS_AFO ) 3.12 + if ( fault_status & DMA_FSTS_AFO ) 3.13 dprintk(XENLOG_ERR VTDPREFIX, 3.14 "iommu_fault_status: Advanced Fault Overflow\n"); 3.15 - else if ( fault_status & DMA_FSTS_APF ) 3.16 + if ( fault_status & DMA_FSTS_APF ) 3.17 dprintk(XENLOG_ERR VTDPREFIX, 3.18 "iommu_fault_status: Advanced Pending Fault\n"); 3.19 - else if ( fault_status & DMA_FSTS_IQE ) 3.20 + if ( fault_status & DMA_FSTS_IQE ) 3.21 dprintk(XENLOG_ERR VTDPREFIX, 3.22 "iommu_fault_status: Invalidation Queue Error\n"); 3.23 - else if ( fault_status & DMA_FSTS_ICE ) 3.24 + if ( fault_status & DMA_FSTS_ICE ) 3.25 dprintk(XENLOG_ERR VTDPREFIX, 3.26 "iommu_fault_status: Invalidation Completion Error\n"); 3.27 - else if ( fault_status & DMA_FSTS_ITE ) 3.28 + if ( fault_status & DMA_FSTS_ITE ) 3.29 dprintk(XENLOG_ERR VTDPREFIX, 3.30 "iommu_fault_status: Invalidation Time-out Error\n"); 3.31 } 3.32 @@ -754,10 +754,11 @@ static void iommu_page_fault(int vector, 3.33 3.34 /* FIXME: ignore advanced fault log */ 3.35 if ( !(fault_status & DMA_FSTS_PPF) ) 3.36 - return; 3.37 + goto clear_overflow; 3.38 + 3.39 fault_index = dma_fsts_fault_record_index(fault_status); 3.40 reg = cap_fault_reg_offset(iommu->cap); 3.41 - for ( ; ; ) 3.42 + while (1) 3.43 { 3.44 u8 fault_reason; 3.45 u16 source_id; 3.46 @@ -797,8 +798,9 @@ static void iommu_page_fault(int vector, 3.47 if ( fault_index > cap_num_fault_regs(iommu->cap) ) 3.48 fault_index = 0; 3.49 } 3.50 - 3.51 +clear_overflow: 3.52 /* clear primary fault overflow */ 3.53 + fault_status = readl(iommu->reg + DMAR_FSTS_REG); 3.54 if ( fault_status & DMA_FSTS_PFO ) 3.55 { 3.56 spin_lock_irqsave(&iommu->register_lock, flags);
4.1 --- a/xen/drivers/passthrough/vtd/iommu.h Wed Nov 26 11:07:44 2008 +0000 4.2 +++ b/xen/drivers/passthrough/vtd/iommu.h Wed Nov 26 11:08:45 2008 +0000 4.3 @@ -310,6 +310,10 @@ struct iremap_entry { 4.4 struct qinval_entry { 4.5 union { 4.6 struct { 4.7 + u64 lo; 4.8 + u64 hi; 4.9 + }val; 4.10 + struct { 4.11 struct { 4.12 u64 type : 4, 4.13 granu : 2,
5.1 --- a/xen/drivers/passthrough/vtd/qinval.c Wed Nov 26 11:07:44 2008 +0000 5.2 +++ b/xen/drivers/passthrough/vtd/qinval.c Wed Nov 26 11:08:45 2008 +0000 5.3 @@ -34,13 +34,13 @@ static void print_qi_regs(struct iommu * 5.4 u64 val; 5.5 5.6 val = dmar_readq(iommu->reg, DMAR_IQA_REG); 5.7 - printk("DMAR_IAQ_REG = %"PRIx64"\n", val); 5.8 + printk("DMAR_IQA_REG = %"PRIx64"\n", val); 5.9 5.10 val = dmar_readq(iommu->reg, DMAR_IQH_REG); 5.11 - printk("DMAR_IAH_REG = %"PRIx64"\n", val); 5.12 + printk("DMAR_IQH_REG = %"PRIx64"\n", val); 5.13 5.14 val = dmar_readq(iommu->reg, DMAR_IQT_REG); 5.15 - printk("DMAR_IAT_REG = %"PRIx64"\n", val); 5.16 + printk("DMAR_IQT_REG = %"PRIx64"\n", val); 5.17 } 5.18 5.19 static int qinval_next_index(struct iommu *iommu) 5.20 @@ -252,14 +252,15 @@ static int gen_dev_iotlb_inv_dsc(struct 5.21 qinval_entry->q.dev_iotlb_inv_dsc.lo.res_3 = 0; 5.22 5.23 qinval_entry->q.dev_iotlb_inv_dsc.hi.size = size; 5.24 - qinval_entry->q.dev_iotlb_inv_dsc.hi.addr = addr; 5.25 + qinval_entry->q.dev_iotlb_inv_dsc.hi.res_1 = 0; 5.26 + qinval_entry->q.dev_iotlb_inv_dsc.hi.addr = addr >> PAGE_SHIFT_4K; 5.27 5.28 unmap_vtd_domain_page(qinval_entries); 5.29 spin_unlock_irqrestore(&qi_ctrl->qinval_lock, flags); 5.30 return 0; 5.31 } 5.32 5.33 -int queue_invalidate_device_iotlb(struct iommu *iommu, 5.34 +int qinval_device_iotlb(struct iommu *iommu, 5.35 u32 max_invs_pend, u16 sid, u16 size, u64 addr) 5.36 { 5.37 int ret = -1;