aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/amd_iommu_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/amd_iommu_init.c')
-rw-r--r--arch/x86/kernel/amd_iommu_init.c119
1 files changed, 62 insertions, 57 deletions
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index c20001e4f556..9dc91b431470 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. 2 * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
3 * Author: Joerg Roedel <joerg.roedel@amd.com> 3 * Author: Joerg Roedel <joerg.roedel@amd.com>
4 * Leo Duran <leo.duran@amd.com> 4 * Leo Duran <leo.duran@amd.com>
5 * 5 *
@@ -25,10 +25,12 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/msi.h> 26#include <linux/msi.h>
27#include <asm/pci-direct.h> 27#include <asm/pci-direct.h>
28#include <asm/amd_iommu_proto.h>
28#include <asm/amd_iommu_types.h> 29#include <asm/amd_iommu_types.h>
29#include <asm/amd_iommu.h> 30#include <asm/amd_iommu.h>
30#include <asm/iommu.h> 31#include <asm/iommu.h>
31#include <asm/gart.h> 32#include <asm/gart.h>
33#include <asm/x86_init.h>
32 34
33/* 35/*
34 * definitions for the ACPI scanning code 36 * definitions for the ACPI scanning code
@@ -123,18 +125,29 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have
123 to handle */ 125 to handle */
124LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings 126LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings
125 we find in ACPI */ 127 we find in ACPI */
126#ifdef CONFIG_IOMMU_STRESS
127bool amd_iommu_isolate = false;
128#else
129bool amd_iommu_isolate = true; /* if true, device isolation is
130 enabled */
131#endif
132
133bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ 128bool amd_iommu_unmap_flush; /* if true, flush on every unmap */
134 129
135LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the 130LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the
136 system */ 131 system */
137 132
133/* Array to assign indices to IOMMUs*/
134struct amd_iommu *amd_iommus[MAX_IOMMUS];
135int amd_iommus_present;
136
137/* IOMMUs have a non-present cache? */
138bool amd_iommu_np_cache __read_mostly;
139
140/*
141 * Set to true if ACPI table parsing and hardware intialization went properly
142 */
143static bool amd_iommu_initialized;
144
145/*
146 * List of protection domains - used during resume
147 */
148LIST_HEAD(amd_iommu_pd_list);
149spinlock_t amd_iommu_pd_lock;
150
138/* 151/*
139 * Pointer to the device table which is shared by all AMD IOMMUs 152 * Pointer to the device table which is shared by all AMD IOMMUs
140 * it is indexed by the PCI device id or the HT unit id and contains 153 * it is indexed by the PCI device id or the HT unit id and contains
@@ -157,12 +170,6 @@ u16 *amd_iommu_alias_table;
157struct amd_iommu **amd_iommu_rlookup_table; 170struct amd_iommu **amd_iommu_rlookup_table;
158 171
159/* 172/*
160 * The pd table (protection domain table) is used to find the protection domain
161 * data structure a device belongs to. Indexed with the PCI device id too.
162 */
163struct protection_domain **amd_iommu_pd_table;
164
165/*
166 * AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap 173 * AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap
167 * to know which ones are already in use. 174 * to know which ones are already in use.
168 */ 175 */
@@ -838,7 +845,18 @@ static void __init free_iommu_all(void)
838static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) 845static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
839{ 846{
840 spin_lock_init(&iommu->lock); 847 spin_lock_init(&iommu->lock);
848
849 /* Add IOMMU to internal data structures */
841 list_add_tail(&iommu->list, &amd_iommu_list); 850 list_add_tail(&iommu->list, &amd_iommu_list);
851 iommu->index = amd_iommus_present++;
852
853 if (unlikely(iommu->index >= MAX_IOMMUS)) {
854 WARN(1, "AMD-Vi: System has more IOMMUs than supported by this driver\n");
855 return -ENOSYS;
856 }
857
858 /* Index is fine - add IOMMU to the array */
859 amd_iommus[iommu->index] = iommu;
842 860
843 /* 861 /*
844 * Copy data from ACPI table entry to the iommu struct 862 * Copy data from ACPI table entry to the iommu struct
@@ -868,6 +886,9 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
868 init_iommu_from_acpi(iommu, h); 886 init_iommu_from_acpi(iommu, h);
869 init_iommu_devices(iommu); 887 init_iommu_devices(iommu);
870 888
889 if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))
890 amd_iommu_np_cache = true;
891
871 return pci_enable_device(iommu->dev); 892 return pci_enable_device(iommu->dev);
872} 893}
873 894
@@ -913,6 +934,8 @@ static int __init init_iommu_all(struct acpi_table_header *table)
913 } 934 }
914 WARN_ON(p != end); 935 WARN_ON(p != end);
915 936
937 amd_iommu_initialized = true;
938
916 return 0; 939 return 0;
917} 940}
918 941
@@ -925,7 +948,7 @@ static int __init init_iommu_all(struct acpi_table_header *table)
925 * 948 *
926 ****************************************************************************/ 949 ****************************************************************************/
927 950
928static int __init iommu_setup_msi(struct amd_iommu *iommu) 951static int iommu_setup_msi(struct amd_iommu *iommu)
929{ 952{
930 int r; 953 int r;
931 954
@@ -1176,19 +1199,10 @@ static struct sys_device device_amd_iommu = {
1176 * functions. Finally it prints some information about AMD IOMMUs and 1199 * functions. Finally it prints some information about AMD IOMMUs and
1177 * the driver state and enables the hardware. 1200 * the driver state and enables the hardware.
1178 */ 1201 */
1179int __init amd_iommu_init(void) 1202static int __init amd_iommu_init(void)
1180{ 1203{
1181 int i, ret = 0; 1204 int i, ret = 0;
1182 1205
1183
1184 if (no_iommu) {
1185 printk(KERN_INFO "AMD-Vi disabled by kernel command line\n");
1186 return 0;
1187 }
1188
1189 if (!amd_iommu_detected)
1190 return -ENODEV;
1191
1192 /* 1206 /*
1193 * First parse ACPI tables to find the largest Bus/Dev/Func 1207 * First parse ACPI tables to find the largest Bus/Dev/Func
1194 * we need to handle. Upon this information the shared data 1208 * we need to handle. Upon this information the shared data
@@ -1225,15 +1239,6 @@ int __init amd_iommu_init(void)
1225 if (amd_iommu_rlookup_table == NULL) 1239 if (amd_iommu_rlookup_table == NULL)
1226 goto free; 1240 goto free;
1227 1241
1228 /*
1229 * Protection Domain table - maps devices to protection domains
1230 * This table has the same size as the rlookup_table
1231 */
1232 amd_iommu_pd_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
1233 get_order(rlookup_table_size));
1234 if (amd_iommu_pd_table == NULL)
1235 goto free;
1236
1237 amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages( 1242 amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages(
1238 GFP_KERNEL | __GFP_ZERO, 1243 GFP_KERNEL | __GFP_ZERO,
1239 get_order(MAX_DOMAIN_ID/8)); 1244 get_order(MAX_DOMAIN_ID/8));
@@ -1255,6 +1260,8 @@ int __init amd_iommu_init(void)
1255 */ 1260 */
1256 amd_iommu_pd_alloc_bitmap[0] = 1; 1261 amd_iommu_pd_alloc_bitmap[0] = 1;
1257 1262
1263 spin_lock_init(&amd_iommu_pd_lock);
1264
1258 /* 1265 /*
1259 * now the data structures are allocated and basically initialized 1266 * now the data structures are allocated and basically initialized
1260 * start the real acpi table scan 1267 * start the real acpi table scan
@@ -1263,6 +1270,9 @@ int __init amd_iommu_init(void)
1263 if (acpi_table_parse("IVRS", init_iommu_all) != 0) 1270 if (acpi_table_parse("IVRS", init_iommu_all) != 0)
1264 goto free; 1271 goto free;
1265 1272
1273 if (!amd_iommu_initialized)
1274 goto free;
1275
1266 if (acpi_table_parse("IVRS", init_memory_definitions) != 0) 1276 if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
1267 goto free; 1277 goto free;
1268 1278
@@ -1274,39 +1284,43 @@ int __init amd_iommu_init(void)
1274 if (ret) 1284 if (ret)
1275 goto free; 1285 goto free;
1276 1286
1287 ret = amd_iommu_init_devices();
1288 if (ret)
1289 goto free;
1290
1277 if (iommu_pass_through) 1291 if (iommu_pass_through)
1278 ret = amd_iommu_init_passthrough(); 1292 ret = amd_iommu_init_passthrough();
1279 else 1293 else
1280 ret = amd_iommu_init_dma_ops(); 1294 ret = amd_iommu_init_dma_ops();
1295
1281 if (ret) 1296 if (ret)
1282 goto free; 1297 goto free;
1283 1298
1299 amd_iommu_init_api();
1300
1301 amd_iommu_init_notifier();
1302
1284 enable_iommus(); 1303 enable_iommus();
1285 1304
1286 if (iommu_pass_through) 1305 if (iommu_pass_through)
1287 goto out; 1306 goto out;
1288 1307
1289 printk(KERN_INFO "AMD-Vi: device isolation ");
1290 if (amd_iommu_isolate)
1291 printk("enabled\n");
1292 else
1293 printk("disabled\n");
1294
1295 if (amd_iommu_unmap_flush) 1308 if (amd_iommu_unmap_flush)
1296 printk(KERN_INFO "AMD-Vi: IO/TLB flush on unmap enabled\n"); 1309 printk(KERN_INFO "AMD-Vi: IO/TLB flush on unmap enabled\n");
1297 else 1310 else
1298 printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n"); 1311 printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n");
1299 1312
1313 x86_platform.iommu_shutdown = disable_iommus;
1300out: 1314out:
1301 return ret; 1315 return ret;
1302 1316
1303free: 1317free:
1318
1319 amd_iommu_uninit_devices();
1320
1304 free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, 1321 free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
1305 get_order(MAX_DOMAIN_ID/8)); 1322 get_order(MAX_DOMAIN_ID/8));
1306 1323
1307 free_pages((unsigned long)amd_iommu_pd_table,
1308 get_order(rlookup_table_size));
1309
1310 free_pages((unsigned long)amd_iommu_rlookup_table, 1324 free_pages((unsigned long)amd_iommu_rlookup_table,
1311 get_order(rlookup_table_size)); 1325 get_order(rlookup_table_size));
1312 1326
@@ -1323,11 +1337,6 @@ free:
1323 goto out; 1337 goto out;
1324} 1338}
1325 1339
1326void amd_iommu_shutdown(void)
1327{
1328 disable_iommus();
1329}
1330
1331/**************************************************************************** 1340/****************************************************************************
1332 * 1341 *
1333 * Early detect code. This code runs at IOMMU detection time in the DMA 1342 * Early detect code. This code runs at IOMMU detection time in the DMA
@@ -1342,16 +1351,16 @@ static int __init early_amd_iommu_detect(struct acpi_table_header *table)
1342 1351
1343void __init amd_iommu_detect(void) 1352void __init amd_iommu_detect(void)
1344{ 1353{
1345 if (swiotlb || no_iommu || (iommu_detected && !gart_iommu_aperture)) 1354 if (no_iommu || (iommu_detected && !gart_iommu_aperture))
1346 return; 1355 return;
1347 1356
1348 if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) { 1357 if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
1349 iommu_detected = 1; 1358 iommu_detected = 1;
1350 amd_iommu_detected = 1; 1359 amd_iommu_detected = 1;
1351#ifdef CONFIG_GART_IOMMU 1360 x86_init.iommu.iommu_init = amd_iommu_init;
1352 gart_iommu_aperture_disabled = 1; 1361
1353 gart_iommu_aperture = 0; 1362 /* Make sure ACS will be enabled */
1354#endif 1363 pci_request_acs();
1355 } 1364 }
1356} 1365}
1357 1366
@@ -1372,10 +1381,6 @@ static int __init parse_amd_iommu_dump(char *str)
1372static int __init parse_amd_iommu_options(char *str) 1381static int __init parse_amd_iommu_options(char *str)
1373{ 1382{
1374 for (; *str; ++str) { 1383 for (; *str; ++str) {
1375 if (strncmp(str, "isolate", 7) == 0)
1376 amd_iommu_isolate = true;
1377 if (strncmp(str, "share", 5) == 0)
1378 amd_iommu_isolate = false;
1379 if (strncmp(str, "fullflush", 9) == 0) 1384 if (strncmp(str, "fullflush", 9) == 0)
1380 amd_iommu_unmap_flush = true; 1385 amd_iommu_unmap_flush = true;
1381 } 1386 }