diff options
Diffstat (limited to 'arch/x86/kernel/amd_iommu.c')
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 261 |
1 files changed, 217 insertions, 44 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 45be9499c973..98f230f6a28d 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -41,9 +41,13 @@ static DEFINE_RWLOCK(amd_iommu_devtable_lock); | |||
41 | static LIST_HEAD(iommu_pd_list); | 41 | static LIST_HEAD(iommu_pd_list); |
42 | static DEFINE_SPINLOCK(iommu_pd_list_lock); | 42 | static DEFINE_SPINLOCK(iommu_pd_list_lock); |
43 | 43 | ||
44 | #ifdef CONFIG_IOMMU_API | 44 | /* |
45 | * Domain for untranslated devices - only allocated | ||
46 | * if iommu=pt passed on kernel cmd line. | ||
47 | */ | ||
48 | static struct protection_domain *pt_domain; | ||
49 | |||
45 | static struct iommu_ops amd_iommu_ops; | 50 | static struct iommu_ops amd_iommu_ops; |
46 | #endif | ||
47 | 51 | ||
48 | /* | 52 | /* |
49 | * general struct to manage commands send to an IOMMU | 53 | * general struct to manage commands send to an IOMMU |
@@ -61,14 +65,11 @@ static u64 *alloc_pte(struct protection_domain *domain, | |||
61 | static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, | 65 | static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, |
62 | unsigned long start_page, | 66 | unsigned long start_page, |
63 | unsigned int pages); | 67 | unsigned int pages); |
68 | static void reset_iommu_command_buffer(struct amd_iommu *iommu); | ||
64 | static u64 *fetch_pte(struct protection_domain *domain, | 69 | static u64 *fetch_pte(struct protection_domain *domain, |
65 | unsigned long address, int map_size); | 70 | unsigned long address, int map_size); |
66 | static void update_domain(struct protection_domain *domain); | 71 | static void update_domain(struct protection_domain *domain); |
67 | 72 | ||
68 | #ifndef BUS_NOTIFY_UNBOUND_DRIVER | ||
69 | #define BUS_NOTIFY_UNBOUND_DRIVER 0x0005 | ||
70 | #endif | ||
71 | |||
72 | #ifdef CONFIG_AMD_IOMMU_STATS | 73 | #ifdef CONFIG_AMD_IOMMU_STATS |
73 | 74 | ||
74 | /* | 75 | /* |
@@ -141,7 +142,25 @@ static int iommu_has_npcache(struct amd_iommu *iommu) | |||
141 | * | 142 | * |
142 | ****************************************************************************/ | 143 | ****************************************************************************/ |
143 | 144 | ||
144 | static void iommu_print_event(void *__evt) | 145 | static void dump_dte_entry(u16 devid) |
146 | { | ||
147 | int i; | ||
148 | |||
149 | for (i = 0; i < 8; ++i) | ||
150 | pr_err("AMD-Vi: DTE[%d]: %08x\n", i, | ||
151 | amd_iommu_dev_table[devid].data[i]); | ||
152 | } | ||
153 | |||
154 | static void dump_command(unsigned long phys_addr) | ||
155 | { | ||
156 | struct iommu_cmd *cmd = phys_to_virt(phys_addr); | ||
157 | int i; | ||
158 | |||
159 | for (i = 0; i < 4; ++i) | ||
160 | pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]); | ||
161 | } | ||
162 | |||
163 | static void iommu_print_event(struct amd_iommu *iommu, void *__evt) | ||
145 | { | 164 | { |
146 | u32 *event = __evt; | 165 | u32 *event = __evt; |
147 | int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; | 166 | int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; |
@@ -150,7 +169,7 @@ static void iommu_print_event(void *__evt) | |||
150 | int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; | 169 | int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; |
151 | u64 address = (u64)(((u64)event[3]) << 32) | event[2]; | 170 | u64 address = (u64)(((u64)event[3]) << 32) | event[2]; |
152 | 171 | ||
153 | printk(KERN_ERR "AMD IOMMU: Event logged ["); | 172 | printk(KERN_ERR "AMD-Vi: Event logged ["); |
154 | 173 | ||
155 | switch (type) { | 174 | switch (type) { |
156 | case EVENT_TYPE_ILL_DEV: | 175 | case EVENT_TYPE_ILL_DEV: |
@@ -158,6 +177,7 @@ static void iommu_print_event(void *__evt) | |||
158 | "address=0x%016llx flags=0x%04x]\n", | 177 | "address=0x%016llx flags=0x%04x]\n", |
159 | PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), | 178 | PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), |
160 | address, flags); | 179 | address, flags); |
180 | dump_dte_entry(devid); | ||
161 | break; | 181 | break; |
162 | case EVENT_TYPE_IO_FAULT: | 182 | case EVENT_TYPE_IO_FAULT: |
163 | printk("IO_PAGE_FAULT device=%02x:%02x.%x " | 183 | printk("IO_PAGE_FAULT device=%02x:%02x.%x " |
@@ -179,6 +199,8 @@ static void iommu_print_event(void *__evt) | |||
179 | break; | 199 | break; |
180 | case EVENT_TYPE_ILL_CMD: | 200 | case EVENT_TYPE_ILL_CMD: |
181 | printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address); | 201 | printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address); |
202 | reset_iommu_command_buffer(iommu); | ||
203 | dump_command(address); | ||
182 | break; | 204 | break; |
183 | case EVENT_TYPE_CMD_HARD_ERR: | 205 | case EVENT_TYPE_CMD_HARD_ERR: |
184 | printk("COMMAND_HARDWARE_ERROR address=0x%016llx " | 206 | printk("COMMAND_HARDWARE_ERROR address=0x%016llx " |
@@ -212,7 +234,7 @@ static void iommu_poll_events(struct amd_iommu *iommu) | |||
212 | tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); | 234 | tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); |
213 | 235 | ||
214 | while (head != tail) { | 236 | while (head != tail) { |
215 | iommu_print_event(iommu->evt_buf + head); | 237 | iommu_print_event(iommu, iommu->evt_buf + head); |
216 | head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size; | 238 | head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size; |
217 | } | 239 | } |
218 | 240 | ||
@@ -299,8 +321,11 @@ static void __iommu_wait_for_completion(struct amd_iommu *iommu) | |||
299 | status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; | 321 | status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; |
300 | writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); | 322 | writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); |
301 | 323 | ||
302 | if (unlikely(i == EXIT_LOOP_COUNT)) | 324 | if (unlikely(i == EXIT_LOOP_COUNT)) { |
303 | panic("AMD IOMMU: Completion wait loop failed\n"); | 325 | spin_unlock(&iommu->lock); |
326 | reset_iommu_command_buffer(iommu); | ||
327 | spin_lock(&iommu->lock); | ||
328 | } | ||
304 | } | 329 | } |
305 | 330 | ||
306 | /* | 331 | /* |
@@ -448,37 +473,67 @@ static void iommu_flush_tlb_pde(struct amd_iommu *iommu, u16 domid) | |||
448 | } | 473 | } |
449 | 474 | ||
450 | /* | 475 | /* |
476 | * This function flushes one domain on one IOMMU | ||
477 | */ | ||
478 | static void flush_domain_on_iommu(struct amd_iommu *iommu, u16 domid) | ||
479 | { | ||
480 | struct iommu_cmd cmd; | ||
481 | unsigned long flags; | ||
482 | |||
483 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, | ||
484 | domid, 1, 1); | ||
485 | |||
486 | spin_lock_irqsave(&iommu->lock, flags); | ||
487 | __iommu_queue_command(iommu, &cmd); | ||
488 | __iommu_completion_wait(iommu); | ||
489 | __iommu_wait_for_completion(iommu); | ||
490 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
491 | } | ||
492 | |||
493 | static void flush_all_domains_on_iommu(struct amd_iommu *iommu) | ||
494 | { | ||
495 | int i; | ||
496 | |||
497 | for (i = 1; i < MAX_DOMAIN_ID; ++i) { | ||
498 | if (!test_bit(i, amd_iommu_pd_alloc_bitmap)) | ||
499 | continue; | ||
500 | flush_domain_on_iommu(iommu, i); | ||
501 | } | ||
502 | |||
503 | } | ||
504 | |||
505 | /* | ||
451 | * This function is used to flush the IO/TLB for a given protection domain | 506 | * This function is used to flush the IO/TLB for a given protection domain |
452 | * on every IOMMU in the system | 507 | * on every IOMMU in the system |
453 | */ | 508 | */ |
454 | static void iommu_flush_domain(u16 domid) | 509 | static void iommu_flush_domain(u16 domid) |
455 | { | 510 | { |
456 | unsigned long flags; | ||
457 | struct amd_iommu *iommu; | 511 | struct amd_iommu *iommu; |
458 | struct iommu_cmd cmd; | ||
459 | 512 | ||
460 | INC_STATS_COUNTER(domain_flush_all); | 513 | INC_STATS_COUNTER(domain_flush_all); |
461 | 514 | ||
462 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, | 515 | for_each_iommu(iommu) |
463 | domid, 1, 1); | 516 | flush_domain_on_iommu(iommu, domid); |
464 | |||
465 | for_each_iommu(iommu) { | ||
466 | spin_lock_irqsave(&iommu->lock, flags); | ||
467 | __iommu_queue_command(iommu, &cmd); | ||
468 | __iommu_completion_wait(iommu); | ||
469 | __iommu_wait_for_completion(iommu); | ||
470 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
471 | } | ||
472 | } | 517 | } |
473 | 518 | ||
474 | void amd_iommu_flush_all_domains(void) | 519 | void amd_iommu_flush_all_domains(void) |
475 | { | 520 | { |
521 | struct amd_iommu *iommu; | ||
522 | |||
523 | for_each_iommu(iommu) | ||
524 | flush_all_domains_on_iommu(iommu); | ||
525 | } | ||
526 | |||
527 | static void flush_all_devices_for_iommu(struct amd_iommu *iommu) | ||
528 | { | ||
476 | int i; | 529 | int i; |
477 | 530 | ||
478 | for (i = 1; i < MAX_DOMAIN_ID; ++i) { | 531 | for (i = 0; i <= amd_iommu_last_bdf; ++i) { |
479 | if (!test_bit(i, amd_iommu_pd_alloc_bitmap)) | 532 | if (iommu != amd_iommu_rlookup_table[i]) |
480 | continue; | 533 | continue; |
481 | iommu_flush_domain(i); | 534 | |
535 | iommu_queue_inv_dev_entry(iommu, i); | ||
536 | iommu_completion_wait(iommu); | ||
482 | } | 537 | } |
483 | } | 538 | } |
484 | 539 | ||
@@ -501,6 +556,22 @@ static void flush_devices_by_domain(struct protection_domain *domain) | |||
501 | } | 556 | } |
502 | } | 557 | } |
503 | 558 | ||
559 | static void reset_iommu_command_buffer(struct amd_iommu *iommu) | ||
560 | { | ||
561 | pr_err("AMD-Vi: Resetting IOMMU command buffer\n"); | ||
562 | |||
563 | if (iommu->reset_in_progress) | ||
564 | panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n"); | ||
565 | |||
566 | iommu->reset_in_progress = true; | ||
567 | |||
568 | amd_iommu_reset_cmd_buffer(iommu); | ||
569 | flush_all_devices_for_iommu(iommu); | ||
570 | flush_all_domains_on_iommu(iommu); | ||
571 | |||
572 | iommu->reset_in_progress = false; | ||
573 | } | ||
574 | |||
504 | void amd_iommu_flush_all_devices(void) | 575 | void amd_iommu_flush_all_devices(void) |
505 | { | 576 | { |
506 | flush_devices_by_domain(NULL); | 577 | flush_devices_by_domain(NULL); |
@@ -1077,19 +1148,36 @@ static struct protection_domain *domain_for_device(u16 devid) | |||
1077 | static void set_dte_entry(u16 devid, struct protection_domain *domain) | 1148 | static void set_dte_entry(u16 devid, struct protection_domain *domain) |
1078 | { | 1149 | { |
1079 | u64 pte_root = virt_to_phys(domain->pt_root); | 1150 | u64 pte_root = virt_to_phys(domain->pt_root); |
1080 | unsigned long flags; | ||
1081 | 1151 | ||
1082 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) | 1152 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) |
1083 | << DEV_ENTRY_MODE_SHIFT; | 1153 | << DEV_ENTRY_MODE_SHIFT; |
1084 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; | 1154 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; |
1085 | 1155 | ||
1086 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | ||
1087 | amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root); | ||
1088 | amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root); | ||
1089 | amd_iommu_dev_table[devid].data[2] = domain->id; | 1156 | amd_iommu_dev_table[devid].data[2] = domain->id; |
1157 | amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root); | ||
1158 | amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root); | ||
1090 | 1159 | ||
1091 | amd_iommu_pd_table[devid] = domain; | 1160 | amd_iommu_pd_table[devid] = domain; |
1092 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 1161 | } |
1162 | |||
1163 | /* | ||
1164 | * If a device is not yet associated with a domain, this function does | ||
1165 | * assigns it visible for the hardware | ||
1166 | */ | ||
1167 | static void __attach_device(struct amd_iommu *iommu, | ||
1168 | struct protection_domain *domain, | ||
1169 | u16 devid) | ||
1170 | { | ||
1171 | /* lock domain */ | ||
1172 | spin_lock(&domain->lock); | ||
1173 | |||
1174 | /* update DTE entry */ | ||
1175 | set_dte_entry(devid, domain); | ||
1176 | |||
1177 | domain->dev_cnt += 1; | ||
1178 | |||
1179 | /* ready */ | ||
1180 | spin_unlock(&domain->lock); | ||
1093 | } | 1181 | } |
1094 | 1182 | ||
1095 | /* | 1183 | /* |
@@ -1100,17 +1188,17 @@ static void attach_device(struct amd_iommu *iommu, | |||
1100 | struct protection_domain *domain, | 1188 | struct protection_domain *domain, |
1101 | u16 devid) | 1189 | u16 devid) |
1102 | { | 1190 | { |
1103 | /* set the DTE entry */ | 1191 | unsigned long flags; |
1104 | set_dte_entry(devid, domain); | ||
1105 | 1192 | ||
1106 | /* increase reference counter */ | 1193 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); |
1107 | domain->dev_cnt += 1; | 1194 | __attach_device(iommu, domain, devid); |
1195 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | ||
1108 | 1196 | ||
1109 | /* | 1197 | /* |
1110 | * We might boot into a crash-kernel here. The crashed kernel | 1198 | * We might boot into a crash-kernel here. The crashed kernel |
1111 | * left the caches in the IOMMU dirty. So we have to flush | 1199 | * left the caches in the IOMMU dirty. So we have to flush |
1112 | * here to evict all dirty stuff. | 1200 | * here to evict all dirty stuff. |
1113 | */ | 1201 | */ |
1114 | iommu_queue_inv_dev_entry(iommu, devid); | 1202 | iommu_queue_inv_dev_entry(iommu, devid); |
1115 | iommu_flush_tlb_pde(iommu, domain->id); | 1203 | iommu_flush_tlb_pde(iommu, domain->id); |
1116 | } | 1204 | } |
@@ -1137,6 +1225,15 @@ static void __detach_device(struct protection_domain *domain, u16 devid) | |||
1137 | 1225 | ||
1138 | /* ready */ | 1226 | /* ready */ |
1139 | spin_unlock(&domain->lock); | 1227 | spin_unlock(&domain->lock); |
1228 | |||
1229 | /* | ||
1230 | * If we run in passthrough mode the device must be assigned to the | ||
1231 | * passthrough domain if it is detached from any other domain | ||
1232 | */ | ||
1233 | if (iommu_pass_through) { | ||
1234 | struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; | ||
1235 | __attach_device(iommu, pt_domain, devid); | ||
1236 | } | ||
1140 | } | 1237 | } |
1141 | 1238 | ||
1142 | /* | 1239 | /* |
@@ -1182,6 +1279,8 @@ static int device_change_notifier(struct notifier_block *nb, | |||
1182 | case BUS_NOTIFY_UNBOUND_DRIVER: | 1279 | case BUS_NOTIFY_UNBOUND_DRIVER: |
1183 | if (!domain) | 1280 | if (!domain) |
1184 | goto out; | 1281 | goto out; |
1282 | if (iommu_pass_through) | ||
1283 | break; | ||
1185 | detach_device(domain, devid); | 1284 | detach_device(domain, devid); |
1186 | break; | 1285 | break; |
1187 | case BUS_NOTIFY_ADD_DEVICE: | 1286 | case BUS_NOTIFY_ADD_DEVICE: |
@@ -1312,12 +1411,15 @@ static int get_device_resources(struct device *dev, | |||
1312 | 1411 | ||
1313 | static void update_device_table(struct protection_domain *domain) | 1412 | static void update_device_table(struct protection_domain *domain) |
1314 | { | 1413 | { |
1414 | unsigned long flags; | ||
1315 | int i; | 1415 | int i; |
1316 | 1416 | ||
1317 | for (i = 0; i <= amd_iommu_last_bdf; ++i) { | 1417 | for (i = 0; i <= amd_iommu_last_bdf; ++i) { |
1318 | if (amd_iommu_pd_table[i] != domain) | 1418 | if (amd_iommu_pd_table[i] != domain) |
1319 | continue; | 1419 | continue; |
1420 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | ||
1320 | set_dte_entry(i, domain); | 1421 | set_dte_entry(i, domain); |
1422 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | ||
1321 | } | 1423 | } |
1322 | } | 1424 | } |
1323 | 1425 | ||
@@ -2058,19 +2160,47 @@ static void cleanup_domain(struct protection_domain *domain) | |||
2058 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 2160 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); |
2059 | } | 2161 | } |
2060 | 2162 | ||
2061 | static int amd_iommu_domain_init(struct iommu_domain *dom) | 2163 | static void protection_domain_free(struct protection_domain *domain) |
2164 | { | ||
2165 | if (!domain) | ||
2166 | return; | ||
2167 | |||
2168 | if (domain->id) | ||
2169 | domain_id_free(domain->id); | ||
2170 | |||
2171 | kfree(domain); | ||
2172 | } | ||
2173 | |||
2174 | static struct protection_domain *protection_domain_alloc(void) | ||
2062 | { | 2175 | { |
2063 | struct protection_domain *domain; | 2176 | struct protection_domain *domain; |
2064 | 2177 | ||
2065 | domain = kzalloc(sizeof(*domain), GFP_KERNEL); | 2178 | domain = kzalloc(sizeof(*domain), GFP_KERNEL); |
2066 | if (!domain) | 2179 | if (!domain) |
2067 | return -ENOMEM; | 2180 | return NULL; |
2068 | 2181 | ||
2069 | spin_lock_init(&domain->lock); | 2182 | spin_lock_init(&domain->lock); |
2070 | domain->mode = PAGE_MODE_3_LEVEL; | ||
2071 | domain->id = domain_id_alloc(); | 2183 | domain->id = domain_id_alloc(); |
2072 | if (!domain->id) | 2184 | if (!domain->id) |
2185 | goto out_err; | ||
2186 | |||
2187 | return domain; | ||
2188 | |||
2189 | out_err: | ||
2190 | kfree(domain); | ||
2191 | |||
2192 | return NULL; | ||
2193 | } | ||
2194 | |||
2195 | static int amd_iommu_domain_init(struct iommu_domain *dom) | ||
2196 | { | ||
2197 | struct protection_domain *domain; | ||
2198 | |||
2199 | domain = protection_domain_alloc(); | ||
2200 | if (!domain) | ||
2073 | goto out_free; | 2201 | goto out_free; |
2202 | |||
2203 | domain->mode = PAGE_MODE_3_LEVEL; | ||
2074 | domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL); | 2204 | domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL); |
2075 | if (!domain->pt_root) | 2205 | if (!domain->pt_root) |
2076 | goto out_free; | 2206 | goto out_free; |
@@ -2080,7 +2210,7 @@ static int amd_iommu_domain_init(struct iommu_domain *dom) | |||
2080 | return 0; | 2210 | return 0; |
2081 | 2211 | ||
2082 | out_free: | 2212 | out_free: |
2083 | kfree(domain); | 2213 | protection_domain_free(domain); |
2084 | 2214 | ||
2085 | return -ENOMEM; | 2215 | return -ENOMEM; |
2086 | } | 2216 | } |
@@ -2249,3 +2379,46 @@ static struct iommu_ops amd_iommu_ops = { | |||
2249 | .domain_has_cap = amd_iommu_domain_has_cap, | 2379 | .domain_has_cap = amd_iommu_domain_has_cap, |
2250 | }; | 2380 | }; |
2251 | 2381 | ||
2382 | /***************************************************************************** | ||
2383 | * | ||
2384 | * The next functions do a basic initialization of IOMMU for pass through | ||
2385 | * mode | ||
2386 | * | ||
2387 | * In passthrough mode the IOMMU is initialized and enabled but not used for | ||
2388 | * DMA-API translation. | ||
2389 | * | ||
2390 | *****************************************************************************/ | ||
2391 | |||
2392 | int __init amd_iommu_init_passthrough(void) | ||
2393 | { | ||
2394 | struct pci_dev *dev = NULL; | ||
2395 | u16 devid, devid2; | ||
2396 | |||
2397 | /* allocate passthroug domain */ | ||
2398 | pt_domain = protection_domain_alloc(); | ||
2399 | if (!pt_domain) | ||
2400 | return -ENOMEM; | ||
2401 | |||
2402 | pt_domain->mode |= PAGE_MODE_NONE; | ||
2403 | |||
2404 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | ||
2405 | struct amd_iommu *iommu; | ||
2406 | |||
2407 | devid = calc_devid(dev->bus->number, dev->devfn); | ||
2408 | if (devid > amd_iommu_last_bdf) | ||
2409 | continue; | ||
2410 | |||
2411 | devid2 = amd_iommu_alias_table[devid]; | ||
2412 | |||
2413 | iommu = amd_iommu_rlookup_table[devid2]; | ||
2414 | if (!iommu) | ||
2415 | continue; | ||
2416 | |||
2417 | __attach_device(iommu, pt_domain, devid); | ||
2418 | __attach_device(iommu, pt_domain, devid2); | ||
2419 | } | ||
2420 | |||
2421 | pr_info("AMD-Vi: Initialized for Passthrough Mode\n"); | ||
2422 | |||
2423 | return 0; | ||
2424 | } | ||