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>
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;