diff options
| -rw-r--r-- | arch/x86/kernel/amd_iommu.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 9098f047c1a9..7fa2d5d57dd8 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #define to_pages(addr, size) \ | 32 | #define to_pages(addr, size) \ |
| 33 | (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT) | 33 | (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT) |
| 34 | 34 | ||
| 35 | #define EXIT_LOOP_COUNT 10000000 | ||
| 36 | |||
| 35 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); | 37 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); |
| 36 | 38 | ||
| 37 | /* | 39 | /* |
| @@ -106,6 +108,7 @@ static int iommu_completion_wait(struct amd_iommu *iommu) | |||
| 106 | struct command cmd; | 108 | struct command cmd; |
| 107 | volatile u64 ready = 0; | 109 | volatile u64 ready = 0; |
| 108 | unsigned long ready_phys = virt_to_phys(&ready); | 110 | unsigned long ready_phys = virt_to_phys(&ready); |
| 111 | unsigned long i = 0; | ||
| 109 | 112 | ||
| 110 | memset(&cmd, 0, sizeof(cmd)); | 113 | memset(&cmd, 0, sizeof(cmd)); |
| 111 | cmd.data[0] = LOW_U32(ready_phys) | CMD_COMPL_WAIT_STORE_MASK; | 114 | cmd.data[0] = LOW_U32(ready_phys) | CMD_COMPL_WAIT_STORE_MASK; |
| @@ -120,8 +123,13 @@ static int iommu_completion_wait(struct amd_iommu *iommu) | |||
| 120 | if (ret) | 123 | if (ret) |
| 121 | return ret; | 124 | return ret; |
| 122 | 125 | ||
| 123 | while (!ready) | 126 | while (!ready && (i < EXIT_LOOP_COUNT)) { |
| 127 | ++i; | ||
| 124 | cpu_relax(); | 128 | cpu_relax(); |
| 129 | } | ||
| 130 | |||
| 131 | if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit())) | ||
| 132 | printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n"); | ||
| 125 | 133 | ||
| 126 | return 0; | 134 | return 0; |
| 127 | } | 135 | } |
