diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2009-12-10 05:03:39 -0500 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2009-12-10 06:21:31 -0500 |
commit | b7cc9554bc73641c9ed4d7eb74b2d6e78f20abea (patch) | |
tree | 42a90d0bcef2932b3aca414bf6620fb13685e9b7 /arch | |
parent | 4528752f49c1f4025473d12bc5fa9181085c3f22 (diff) |
x86/amd-iommu: Fix passthrough mode
The data structure changes to use dev->archdata.iommu field
broke the iommu=pt mode because in this case the
dev->archdata.iommu was left uninitialized. This moves the
inititalization of the devices into the main init function
and fixes the problem.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/amd_iommu_proto.h | 3 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 39 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 7 |
3 files changed, 46 insertions, 3 deletions
diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h index 84786fb9a23b..2566e2606224 100644 --- a/arch/x86/include/asm/amd_iommu_proto.h +++ b/arch/x86/include/asm/amd_iommu_proto.h | |||
@@ -28,7 +28,8 @@ extern void amd_iommu_flush_all_domains(void); | |||
28 | extern void amd_iommu_flush_all_devices(void); | 28 | extern void amd_iommu_flush_all_devices(void); |
29 | extern void amd_iommu_apply_erratum_63(u16 devid); | 29 | extern void amd_iommu_apply_erratum_63(u16 devid); |
30 | extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu); | 30 | extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu); |
31 | 31 | extern int amd_iommu_init_devices(void); | |
32 | extern void amd_iommu_uninit_devices(void); | ||
32 | #ifndef CONFIG_AMD_IOMMU_STATS | 33 | #ifndef CONFIG_AMD_IOMMU_STATS |
33 | 34 | ||
34 | static inline void amd_iommu_stats_init(void) { } | 35 | static inline void amd_iommu_stats_init(void) { } |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 32fb09102a13..450dd6ac03d3 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -166,6 +166,43 @@ static void iommu_uninit_device(struct device *dev) | |||
166 | { | 166 | { |
167 | kfree(dev->archdata.iommu); | 167 | kfree(dev->archdata.iommu); |
168 | } | 168 | } |
169 | |||
170 | void __init amd_iommu_uninit_devices(void) | ||
171 | { | ||
172 | struct pci_dev *pdev = NULL; | ||
173 | |||
174 | for_each_pci_dev(pdev) { | ||
175 | |||
176 | if (!check_device(&pdev->dev)) | ||
177 | continue; | ||
178 | |||
179 | iommu_uninit_device(&pdev->dev); | ||
180 | } | ||
181 | } | ||
182 | |||
183 | int __init amd_iommu_init_devices(void) | ||
184 | { | ||
185 | struct pci_dev *pdev = NULL; | ||
186 | int ret = 0; | ||
187 | |||
188 | for_each_pci_dev(pdev) { | ||
189 | |||
190 | if (!check_device(&pdev->dev)) | ||
191 | continue; | ||
192 | |||
193 | ret = iommu_init_device(&pdev->dev); | ||
194 | if (ret) | ||
195 | goto out_free; | ||
196 | } | ||
197 | |||
198 | return 0; | ||
199 | |||
200 | out_free: | ||
201 | |||
202 | amd_iommu_uninit_devices(); | ||
203 | |||
204 | return ret; | ||
205 | } | ||
169 | #ifdef CONFIG_AMD_IOMMU_STATS | 206 | #ifdef CONFIG_AMD_IOMMU_STATS |
170 | 207 | ||
171 | /* | 208 | /* |
@@ -2145,8 +2182,6 @@ static void prealloc_protection_domains(void) | |||
2145 | if (!check_device(&dev->dev)) | 2182 | if (!check_device(&dev->dev)) |
2146 | continue; | 2183 | continue; |
2147 | 2184 | ||
2148 | iommu_init_device(&dev->dev); | ||
2149 | |||
2150 | /* Is there already any domain for it? */ | 2185 | /* Is there already any domain for it? */ |
2151 | if (domain_for_device(&dev->dev)) | 2186 | if (domain_for_device(&dev->dev)) |
2152 | continue; | 2187 | continue; |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 7ffc39965233..df01c691d130 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -1274,6 +1274,10 @@ static int __init amd_iommu_init(void) | |||
1274 | if (ret) | 1274 | if (ret) |
1275 | goto free; | 1275 | goto free; |
1276 | 1276 | ||
1277 | ret = amd_iommu_init_devices(); | ||
1278 | if (ret) | ||
1279 | goto free; | ||
1280 | |||
1277 | if (iommu_pass_through) | 1281 | if (iommu_pass_through) |
1278 | ret = amd_iommu_init_passthrough(); | 1282 | ret = amd_iommu_init_passthrough(); |
1279 | else | 1283 | else |
@@ -1296,6 +1300,9 @@ out: | |||
1296 | return ret; | 1300 | return ret; |
1297 | 1301 | ||
1298 | free: | 1302 | free: |
1303 | |||
1304 | amd_iommu_uninit_devices(); | ||
1305 | |||
1299 | free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, | 1306 | free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, |
1300 | get_order(MAX_DOMAIN_ID/8)); | 1307 | get_order(MAX_DOMAIN_ID/8)); |
1301 | 1308 | ||