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 | |
| 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>
| -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 | ||
