ia64/xen-unstable

changeset 18856:5c121966ad9a

AMD IOMMU: Fix event log interrupt handling

Reset EventLogInt bit in iommu status register(MMIO offset 2020h) in
event log interrupt handler, to show software has handled the
interrupt. Completion wait interrupt is disabled.

Signed-off-by: Wei Wang <wei.wang2@amd.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Dec 03 15:55:32 2008 +0000 (2008-12-03)
parents 00a15b45cae3
children f571834d3f5d
files xen/drivers/passthrough/amd/iommu_init.c
line diff
     1.1 --- a/xen/drivers/passthrough/amd/iommu_init.c	Wed Dec 03 15:54:24 2008 +0000
     1.2 +++ b/xen/drivers/passthrough/amd/iommu_init.c	Wed Dec 03 15:55:32 2008 +0000
     1.3 @@ -235,8 +235,7 @@ static void __init set_iommu_event_log_c
     1.4                           IOMMU_CONTROL_EVENT_LOG_INT_SHIFT, &entry);
     1.5      writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET);
     1.6  
     1.7 -    set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED :
     1.8 -                         IOMMU_CONTROL_DISABLED, entry,
     1.9 +    set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry,
    1.10                           IOMMU_CONTROL_COMP_WAIT_INT_MASK,
    1.11                           IOMMU_CONTROL_COMP_WAIT_INT_SHIFT, &entry);
    1.12      writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET);
    1.13 @@ -391,20 +390,19 @@ static void parse_event_log_entry(u32 en
    1.14      u32 code;
    1.15      u64 *addr;
    1.16      char * event_str[] = {"ILLEGAL_DEV_TABLE_ENTRY",
    1.17 -                                         "IO_PAGE_FALT",
    1.18 -                                         "DEV_TABLE_HW_ERROR",
    1.19 -                                         "PAGE_TABLE_HW_ERROR",
    1.20 -                                         "ILLEGAL_COMMAND_ERROR",
    1.21 -                                         "COMMAND_HW_ERROR",
    1.22 -                                         "IOTLB_INV_TIMEOUT",
    1.23 -                                         "INVALID_DEV_REQUEST"};
    1.24 +                          "IO_PAGE_FALT",
    1.25 +                          "DEV_TABLE_HW_ERROR",
    1.26 +                          "PAGE_TABLE_HW_ERROR",
    1.27 +                          "ILLEGAL_COMMAND_ERROR",
    1.28 +                          "COMMAND_HW_ERROR",
    1.29 +                          "IOTLB_INV_TIMEOUT",
    1.30 +                          "INVALID_DEV_REQUEST"};
    1.31  
    1.32 -    code = get_field_from_reg_u32(entry[1],
    1.33 -                                           IOMMU_EVENT_CODE_MASK,
    1.34 -                                           IOMMU_EVENT_CODE_SHIFT);
    1.35 +    code = get_field_from_reg_u32(entry[1], IOMMU_EVENT_CODE_MASK,
    1.36 +                                            IOMMU_EVENT_CODE_SHIFT);
    1.37  
    1.38 -    if ( (code > IOMMU_EVENT_INVALID_DEV_REQUEST)
    1.39 -        || (code < IOMMU_EVENT_ILLEGAL_DEV_TABLE_ENTRY) )
    1.40 +    if ( (code > IOMMU_EVENT_INVALID_DEV_REQUEST) ||
    1.41 +        (code < IOMMU_EVENT_ILLEGAL_DEV_TABLE_ENTRY) )
    1.42      {
    1.43          amd_iov_error("Invalid event log entry!\n");
    1.44          return;
    1.45 @@ -428,13 +426,20 @@ static void parse_event_log_entry(u32 en
    1.46  static void amd_iommu_page_fault(int vector, void *dev_id,
    1.47                               struct cpu_user_regs *regs)
    1.48  {
    1.49 -    u32  event[4];
    1.50 +    u32 event[4];
    1.51 +    u32 entry;
    1.52      unsigned long flags;
    1.53      int ret = 0;
    1.54      struct amd_iommu *iommu = dev_id;
    1.55  
    1.56      spin_lock_irqsave(&iommu->lock, flags);
    1.57      ret = amd_iommu_read_event_log(iommu, event);
    1.58 +    /* reset interrupt status bit */
    1.59 +    entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
    1.60 +    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,
    1.61 +                         IOMMU_STATUS_EVENT_LOG_INT_MASK,
    1.62 +                         IOMMU_STATUS_EVENT_LOG_INT_SHIFT, &entry);
    1.63 +    writel(entry, iommu->mmio_base+IOMMU_STATUS_MMIO_OFFSET);
    1.64      spin_unlock_irqrestore(&iommu->lock, flags);
    1.65  
    1.66      if ( ret != 0 )
    1.67 @@ -466,7 +471,7 @@ static int set_iommu_interrupt_handler(s
    1.68          amd_iov_error("can't request irq\n");
    1.69          return 0;
    1.70      }
    1.71 -
    1.72 +    iommu->vector = vector;
    1.73      return vector;
    1.74  }
    1.75