From: Bhavna Sarathy <bnagendr@redhat.com> Date: Thu, 22 Oct 2009 20:01:31 -0400 Subject: [xen] iommu-amd: extend loop ctr for polling completion wait Message-id: <20091022200354.3419.94246.sendpatchset@localhost.localdomain> Patchwork-id: 21204 O-Subject: [RHEL5.5 PATCH 5/5] Extend the loop counter for polling completion wait Bugzilla: 518474 526766 RH-Acked-by: Christopher Lalancette <clalance@redhat.com> RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com> RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com> This patch extended the loop counter for polling completion wait, and we have found that certain APIC errors that occur after prolonged running goes away by extending the loop counter. Resolves BZ 526766 and 518474 diff --git a/drivers/passthrough/amd/iommu_map.c b/drivers/passthrough/amd/iommu_map.c index 7c01a1e..2ca2e14 100644 --- a/drivers/passthrough/amd/iommu_map.c +++ b/drivers/passthrough/amd/iommu_map.c @@ -23,8 +23,6 @@ #include <asm/amd-iommu.h> #include <asm/hvm/svm/amd-iommu-proto.h> -long amd_iommu_poll_comp_wait = COMPLETION_WAIT_DEFAULT_POLLING_COUNT; - static int queue_iommu_command(struct amd_iommu *iommu, u32 cmd[]) { u32 tail, head, *cmd_buffer; @@ -132,31 +130,23 @@ void flush_command_buffer(struct amd_iommu *iommu) send_iommu_command(iommu, cmd); /* wait for 'ComWaitInt' to signal comp#endifletion? */ - if ( amd_iommu_poll_comp_wait ) + loop_count = 1000; + do { + status = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); + comp_wait = get_field_from_reg_u32(status, + IOMMU_STATUS_COMP_WAIT_INT_MASK, + IOMMU_STATUS_COMP_WAIT_INT_SHIFT); + --loop_count; + } while ( !comp_wait && loop_count ); + + if ( comp_wait ) { - loop_count = amd_iommu_poll_comp_wait; - do { - status = readl(iommu->mmio_base + - IOMMU_STATUS_MMIO_OFFSET); - comp_wait = get_field_from_reg_u32( - status, - IOMMU_STATUS_COMP_WAIT_INT_MASK, - IOMMU_STATUS_COMP_WAIT_INT_SHIFT); - --loop_count; - } while ( loop_count && !comp_wait ); - - if ( comp_wait ) - { - /* clear 'ComWaitInt' in status register (WIC) */ - status &= IOMMU_STATUS_COMP_WAIT_INT_MASK; - writel(status, iommu->mmio_base + - IOMMU_STATUS_MMIO_OFFSET); - } - else - { - AMD_IOMMU_DEBUG("Warning: ComWaitInt bit did not assert!\n"); - } + /* clear 'ComWaitInt' in status register (WIC) */ + status &= IOMMU_STATUS_COMP_WAIT_INT_MASK; + writel(status, iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); + return; } + AMD_IOMMU_DEBUG("Warning: ComWaitInt bit did not assert!\n"); } static void clear_iommu_l1e_present(u64 l2e, unsigned long gfn) diff --git a/include/asm-x86/amd-iommu.h b/include/asm-x86/amd-iommu.h index 767ca2d..1b06a38 100644 --- a/include/asm-x86/amd-iommu.h +++ b/include/asm-x86/amd-iommu.h @@ -58,9 +58,6 @@ struct amd_iommu { u8 pass_pw; u8 ht_tunnel_enable; - int last_downstream_bus; - int downstream_bus_present[PCI_MAX_BUS_COUNT]; - void *mmio_base; unsigned long mmio_base_phys; diff --git a/include/asm-x86/hvm/svm/amd-iommu-defs.h b/include/asm-x86/hvm/svm/amd-iommu-defs.h index be801b7..463121b 100644 --- a/include/asm-x86/hvm/svm/amd-iommu-defs.h +++ b/include/asm-x86/hvm/svm/amd-iommu-defs.h @@ -21,25 +21,12 @@ #ifndef _ASM_X86_64_AMD_IOMMU_DEFS_H #define _ASM_X86_64_AMD_IOMMU_DEFS_H -/* Reserve some non-mapped pages to handle error conditions. - * 'bad_dma_address' will point to these reserved pages, and - * the mapping funtions will return 'bad_dma_address' if there - * are not enough page table entries available. - */ -#define IOMMU_RESERVED_BASE_ADDR 0 -#define IOMMU_RESERVED_PAGES 32 - -/* IOMMU ComWaitInt polling after issuing a COMPLETION_WAIT command */ -#define COMPLETION_WAIT_DEFAULT_POLLING_COUNT 10 - /* IOMMU Command Buffer entries: in power of 2 increments, minimum of 256 */ #define IOMMU_CMD_BUFFER_DEFAULT_ENTRIES 512 /* IOMMU Event Log entries: in power of 2 increments, minimum of 256 */ #define IOMMU_EVENT_LOG_DEFAULT_ENTRIES 512 -#define BITMAP_ENTRIES_PER_BYTE 8 - #define PTE_PER_TABLE_SHIFT 9 #define PTE_PER_TABLE_SIZE (1 << PTE_PER_TABLE_SHIFT) #define PTE_PER_TABLE_MASK (~(PTE_PER_TABLE_SIZE - 1)) @@ -48,41 +35,6 @@ #define PTE_PER_TABLE_ALLOC(entries) \ PAGE_SIZE * (PTE_PER_TABLE_ALIGN(entries) >> PTE_PER_TABLE_SHIFT) -/* 0-based aperture order (represents virtual address space for DMA mappings */ -#define APERTURE_ORDER_FOR_32B_APERTURE 0 -#define APERTURE_ORDER_FOR_64MB_APERTURE 1 -#define APERTURE_ORDER_FOR_128MB_APERTURE 2 -#define APERTURE_ORDER_FOR_256MB_APERTURE 3 -#define APERTURE_ORDER_FOR_512MB_APERTURE 4 -#define APERTURE_ORDER_FOR_1GB_APERTURE 5 -#define APERTURE_ORDER_FOR_MAX_APERTURE APERTURE_ORDER_FOR_1GB_APERTURE - -/* The minimum 32MB aperture requires 2**13 level-1 page table entries */ -#define SHIFT_FOR_MIN_APERTURE 13 -#define PAGES_FROM_APERTURE_ORDER(order) \ - ((1 << (order)) << SHIFT_FOR_MIN_APERTURE) -#define ORDER_FROM_APERTURE_PAGES(pages) \ - get_order(((pages) * PAGE_SIZE) >> SHIFT_FOR_MIN_APERTURE) - -/* - * PCI config-space - */ -#define VALID_PCI_VENDOR_ID(id) (((id) != 0) && ((id) != 0xFFFF)) -#define IS_PCI_MULTI_FUNCTION(hdr) ((hdr) & 0x80) -#define IS_PCI_TYPE0_HEADER(hdr) (((hdr) & 0x7f) == 0) -#define IS_PCI_TYPE1_HEADER(hdr) (((hdr) & 0x7f) == 1) - -#define PCI_MAX_BUS_COUNT 256 -#define PCI_MAX_DEV_COUNT 32 -#define PCI_MAX_FUNC_COUNT 8 -#define PCI_MIN_DEVFN 0 -#define PCI_MAX_DEVFN 0xFF - -/* - * Capability blocks are 4-byte aligned, and must start at >= offset 0x40, - * for a max of 48 possible cap_blocks (256 - 0x40 = 192; 192 / 4 = 48) - * The lower 2 bits of each pointer are reserved, and must be masked off. - */ #define PCI_MIN_CAP_OFFSET 0x40 #define PCI_MAX_CAP_BLOCKS 48 #define PCI_CAP_PTR_MASK 0xFC @@ -105,7 +57,6 @@ #define PCI_CAP_RESET_MASK 0x80000000 #define PCI_CAP_RESET_SHIFT 31 -#define PCI_CAP_ID_SECURE_DEVICE 0x0F #define PCI_CAP_TYPE_IOMMU 0x3 #define PCI_CAP_MMIO_BAR_LOW_OFFSET 0x04