aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/amd_iommu.c
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2008-07-11 11:14:27 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-11 12:01:13 -0400
commit136f78a19cf94d469f31a4009c7c0ac2301fbbf0 (patch)
tree92055e77da5bb4874be1ff3936a16ead059d6701 /arch/x86/kernel/amd_iommu.c
parent9a836de0c9944c42d006ec241712c72e74737c73 (diff)
x86, AMD IOMMU: add an emergency exit to the completion wait loop
To make the loop waiting for the completion wait command not wait forever this patch adds a limit of cycles that loop. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Cc: iommu@lists.linux-foundation.org Cc: bhavna.sarathy@amd.com Cc: robert.richter@amd.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/amd_iommu.c')
-rw-r--r--arch/x86/kernel/amd_iommu.c10
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
35static DEFINE_RWLOCK(amd_iommu_devtable_lock); 37static 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}