diff -r ab0c1bdede53 xen/drivers/passthrough/amd/iommu_init.c --- a/xen/drivers/passthrough/amd/iommu_init.c Wed Nov 26 11:14:26 2008 +0000 +++ b/xen/drivers/passthrough/amd/iommu_init.c Wed Dec 03 15:43:29 2008 +0100 @@ -235,8 +235,7 @@ static void __init set_iommu_event_log_c IOMMU_CONTROL_EVENT_LOG_INT_SHIFT, &entry); writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET); - set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_DISABLED, entry, + set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry, IOMMU_CONTROL_COMP_WAIT_INT_MASK, IOMMU_CONTROL_COMP_WAIT_INT_SHIFT, &entry); writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET); @@ -391,20 +390,19 @@ static void parse_event_log_entry(u32 en u32 code; u64 *addr; char * event_str[] = {"ILLEGAL_DEV_TABLE_ENTRY", - "IO_PAGE_FALT", - "DEV_TABLE_HW_ERROR", - "PAGE_TABLE_HW_ERROR", - "ILLEGAL_COMMAND_ERROR", - "COMMAND_HW_ERROR", - "IOTLB_INV_TIMEOUT", - "INVALID_DEV_REQUEST"}; - - code = get_field_from_reg_u32(entry[1], - IOMMU_EVENT_CODE_MASK, - IOMMU_EVENT_CODE_SHIFT); - - if ( (code > IOMMU_EVENT_INVALID_DEV_REQUEST) - || (code < IOMMU_EVENT_ILLEGAL_DEV_TABLE_ENTRY) ) + "IO_PAGE_FALT", + "DEV_TABLE_HW_ERROR", + "PAGE_TABLE_HW_ERROR", + "ILLEGAL_COMMAND_ERROR", + "COMMAND_HW_ERROR", + "IOTLB_INV_TIMEOUT", + "INVALID_DEV_REQUEST"}; + + code = get_field_from_reg_u32(entry[1], IOMMU_EVENT_CODE_MASK, + IOMMU_EVENT_CODE_SHIFT); + + if ( (code > IOMMU_EVENT_INVALID_DEV_REQUEST) || + (code < IOMMU_EVENT_ILLEGAL_DEV_TABLE_ENTRY) ) { amd_iov_error("Invalid event log entry!\n"); return; @@ -428,13 +426,20 @@ static void amd_iommu_page_fault(int vec static void amd_iommu_page_fault(int vector, void *dev_id, struct cpu_user_regs *regs) { - u32 event[4]; + u32 event[4]; + u32 entry; unsigned long flags; int ret = 0; struct amd_iommu *iommu = dev_id; spin_lock_irqsave(&iommu->lock, flags); ret = amd_iommu_read_event_log(iommu, event); + /* reset interrupt status bit */ + entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); + set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, + IOMMU_STATUS_EVENT_LOG_INT_MASK, + IOMMU_STATUS_EVENT_LOG_INT_SHIFT, &entry); + writel(entry, iommu->mmio_base+IOMMU_STATUS_MMIO_OFFSET); spin_unlock_irqrestore(&iommu->lock, flags); if ( ret != 0 ) @@ -466,7 +471,7 @@ static int set_iommu_interrupt_handler(s amd_iov_error("can't request irq\n"); return 0; } - + iommu->vector = vector; return vector; }