aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/amd_iommu_types.h8
-rw-r--r--arch/x86/kernel/amd_iommu.c119
-rw-r--r--arch/x86/kernel/amd_iommu_init.c34
3 files changed, 120 insertions, 41 deletions
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h
index 0c878caaa0a..3a6a3259e1e 100644
--- a/arch/x86/include/asm/amd_iommu_types.h
+++ b/arch/x86/include/asm/amd_iommu_types.h
@@ -198,7 +198,7 @@ extern bool amd_iommu_dump;
198#define DUMP_printk(format, arg...) \ 198#define DUMP_printk(format, arg...) \
199 do { \ 199 do { \
200 if (amd_iommu_dump) \ 200 if (amd_iommu_dump) \
201 printk(KERN_INFO "AMD IOMMU: " format, ## arg); \ 201 printk(KERN_INFO "AMD-Vi: " format, ## arg); \
202 } while(0); 202 } while(0);
203 203
204/* 204/*
@@ -337,6 +337,9 @@ struct amd_iommu {
337 /* if one, we need to send a completion wait command */ 337 /* if one, we need to send a completion wait command */
338 bool need_sync; 338 bool need_sync;
339 339
340 /* becomes true if a command buffer reset is running */
341 bool reset_in_progress;
342
340 /* default dma_ops domain for that IOMMU */ 343 /* default dma_ops domain for that IOMMU */
341 struct dma_ops_domain *default_dom; 344 struct dma_ops_domain *default_dom;
342}; 345};
@@ -457,4 +460,7 @@ static inline void amd_iommu_stats_init(void) { }
457 460
458#endif /* CONFIG_AMD_IOMMU_STATS */ 461#endif /* CONFIG_AMD_IOMMU_STATS */
459 462
463/* some function prototypes */
464extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
465
460#endif /* _ASM_X86_AMD_IOMMU_TYPES_H */ 466#endif /* _ASM_X86_AMD_IOMMU_TYPES_H */
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 6c99f503780..8c93b7c7735 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -41,9 +41,7 @@ static DEFINE_RWLOCK(amd_iommu_devtable_lock);
41static LIST_HEAD(iommu_pd_list); 41static LIST_HEAD(iommu_pd_list);
42static DEFINE_SPINLOCK(iommu_pd_list_lock); 42static DEFINE_SPINLOCK(iommu_pd_list_lock);
43 43
44#ifdef CONFIG_IOMMU_API
45static struct iommu_ops amd_iommu_ops; 44static struct iommu_ops amd_iommu_ops;
46#endif
47 45
48/* 46/*
49 * general struct to manage commands send to an IOMMU 47 * general struct to manage commands send to an IOMMU
@@ -61,10 +59,7 @@ static u64* alloc_pte(struct protection_domain *dom,
61static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, 59static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
62 unsigned long start_page, 60 unsigned long start_page,
63 unsigned int pages); 61 unsigned int pages);
64 62static void reset_iommu_command_buffer(struct amd_iommu *iommu);
65#ifndef BUS_NOTIFY_UNBOUND_DRIVER
66#define BUS_NOTIFY_UNBOUND_DRIVER 0x0005
67#endif
68 63
69#ifdef CONFIG_AMD_IOMMU_STATS 64#ifdef CONFIG_AMD_IOMMU_STATS
70 65
@@ -138,7 +133,25 @@ static int iommu_has_npcache(struct amd_iommu *iommu)
138 * 133 *
139 ****************************************************************************/ 134 ****************************************************************************/
140 135
141static void iommu_print_event(void *__evt) 136static void dump_dte_entry(u16 devid)
137{
138 int i;
139
140 for (i = 0; i < 8; ++i)
141 pr_err("AMD-Vi: DTE[%d]: %08x\n", i,
142 amd_iommu_dev_table[devid].data[i]);
143}
144
145static void dump_command(unsigned long phys_addr)
146{
147 struct iommu_cmd *cmd = phys_to_virt(phys_addr);
148 int i;
149
150 for (i = 0; i < 4; ++i)
151 pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]);
152}
153
154static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
142{ 155{
143 u32 *event = __evt; 156 u32 *event = __evt;
144 int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; 157 int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK;
@@ -147,7 +160,7 @@ static void iommu_print_event(void *__evt)
147 int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; 160 int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
148 u64 address = (u64)(((u64)event[3]) << 32) | event[2]; 161 u64 address = (u64)(((u64)event[3]) << 32) | event[2];
149 162
150 printk(KERN_ERR "AMD IOMMU: Event logged ["); 163 printk(KERN_ERR "AMD-Vi: Event logged [");
151 164
152 switch (type) { 165 switch (type) {
153 case EVENT_TYPE_ILL_DEV: 166 case EVENT_TYPE_ILL_DEV:
@@ -155,6 +168,7 @@ static void iommu_print_event(void *__evt)
155 "address=0x%016llx flags=0x%04x]\n", 168 "address=0x%016llx flags=0x%04x]\n",
156 PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), 169 PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid),
157 address, flags); 170 address, flags);
171 dump_dte_entry(devid);
158 break; 172 break;
159 case EVENT_TYPE_IO_FAULT: 173 case EVENT_TYPE_IO_FAULT:
160 printk("IO_PAGE_FAULT device=%02x:%02x.%x " 174 printk("IO_PAGE_FAULT device=%02x:%02x.%x "
@@ -176,6 +190,8 @@ static void iommu_print_event(void *__evt)
176 break; 190 break;
177 case EVENT_TYPE_ILL_CMD: 191 case EVENT_TYPE_ILL_CMD:
178 printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address); 192 printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
193 reset_iommu_command_buffer(iommu);
194 dump_command(address);
179 break; 195 break;
180 case EVENT_TYPE_CMD_HARD_ERR: 196 case EVENT_TYPE_CMD_HARD_ERR:
181 printk("COMMAND_HARDWARE_ERROR address=0x%016llx " 197 printk("COMMAND_HARDWARE_ERROR address=0x%016llx "
@@ -209,7 +225,7 @@ static void iommu_poll_events(struct amd_iommu *iommu)
209 tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); 225 tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET);
210 226
211 while (head != tail) { 227 while (head != tail) {
212 iommu_print_event(iommu->evt_buf + head); 228 iommu_print_event(iommu, iommu->evt_buf + head);
213 head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size; 229 head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size;
214 } 230 }
215 231
@@ -296,8 +312,11 @@ static void __iommu_wait_for_completion(struct amd_iommu *iommu)
296 status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; 312 status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
297 writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); 313 writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
298 314
299 if (unlikely(i == EXIT_LOOP_COUNT)) 315 if (unlikely(i == EXIT_LOOP_COUNT)) {
300 panic("AMD IOMMU: Completion wait loop failed\n"); 316 spin_unlock(&iommu->lock);
317 reset_iommu_command_buffer(iommu);
318 spin_lock(&iommu->lock);
319 }
301} 320}
302 321
303/* 322/*
@@ -445,37 +464,67 @@ static void iommu_flush_tlb_pde(struct amd_iommu *iommu, u16 domid)
445} 464}
446 465
447/* 466/*
467 * This function flushes one domain on one IOMMU
468 */
469static void flush_domain_on_iommu(struct amd_iommu *iommu, u16 domid)
470{
471 struct iommu_cmd cmd;
472 unsigned long flags;
473
474 __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
475 domid, 1, 1);
476
477 spin_lock_irqsave(&iommu->lock, flags);
478 __iommu_queue_command(iommu, &cmd);
479 __iommu_completion_wait(iommu);
480 __iommu_wait_for_completion(iommu);
481 spin_unlock_irqrestore(&iommu->lock, flags);
482}
483
484static void flush_all_domains_on_iommu(struct amd_iommu *iommu)
485{
486 int i;
487
488 for (i = 1; i < MAX_DOMAIN_ID; ++i) {
489 if (!test_bit(i, amd_iommu_pd_alloc_bitmap))
490 continue;
491 flush_domain_on_iommu(iommu, i);
492 }
493
494}
495
496/*
448 * This function is used to flush the IO/TLB for a given protection domain 497 * This function is used to flush the IO/TLB for a given protection domain
449 * on every IOMMU in the system 498 * on every IOMMU in the system
450 */ 499 */
451static void iommu_flush_domain(u16 domid) 500static void iommu_flush_domain(u16 domid)
452{ 501{
453 unsigned long flags;
454 struct amd_iommu *iommu; 502 struct amd_iommu *iommu;
455 struct iommu_cmd cmd;
456 503
457 INC_STATS_COUNTER(domain_flush_all); 504 INC_STATS_COUNTER(domain_flush_all);
458 505
459 __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 506 for_each_iommu(iommu)
460 domid, 1, 1); 507 flush_domain_on_iommu(iommu, domid);
461
462 for_each_iommu(iommu) {
463 spin_lock_irqsave(&iommu->lock, flags);
464 __iommu_queue_command(iommu, &cmd);
465 __iommu_completion_wait(iommu);
466 __iommu_wait_for_completion(iommu);
467 spin_unlock_irqrestore(&iommu->lock, flags);
468 }
469} 508}
470 509
471void amd_iommu_flush_all_domains(void) 510void amd_iommu_flush_all_domains(void)
472{ 511{
512 struct amd_iommu *iommu;
513
514 for_each_iommu(iommu)
515 flush_all_domains_on_iommu(iommu);
516}
517
518static void flush_all_devices_for_iommu(struct amd_iommu *iommu)
519{
473 int i; 520 int i;
474 521
475 for (i = 1; i < MAX_DOMAIN_ID; ++i) { 522 for (i = 0; i <= amd_iommu_last_bdf; ++i) {
476 if (!test_bit(i, amd_iommu_pd_alloc_bitmap)) 523 if (iommu != amd_iommu_rlookup_table[i])
477 continue; 524 continue;
478 iommu_flush_domain(i); 525
526 iommu_queue_inv_dev_entry(iommu, i);
527 iommu_completion_wait(iommu);
479 } 528 }
480} 529}
481 530
@@ -485,8 +534,6 @@ void amd_iommu_flush_all_devices(void)
485 int i; 534 int i;
486 535
487 for (i = 0; i <= amd_iommu_last_bdf; ++i) { 536 for (i = 0; i <= amd_iommu_last_bdf; ++i) {
488 if (amd_iommu_pd_table[i] == NULL)
489 continue;
490 537
491 iommu = amd_iommu_rlookup_table[i]; 538 iommu = amd_iommu_rlookup_table[i];
492 if (!iommu) 539 if (!iommu)
@@ -497,6 +544,22 @@ void amd_iommu_flush_all_devices(void)
497 } 544 }
498} 545}
499 546
547static void reset_iommu_command_buffer(struct amd_iommu *iommu)
548{
549 pr_err("AMD-Vi: Resetting IOMMU command buffer\n");
550
551 if (iommu->reset_in_progress)
552 panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n");
553
554 iommu->reset_in_progress = true;
555
556 amd_iommu_reset_cmd_buffer(iommu);
557 flush_all_devices_for_iommu(iommu);
558 flush_all_domains_on_iommu(iommu);
559
560 iommu->reset_in_progress = false;
561}
562
500/**************************************************************************** 563/****************************************************************************
501 * 564 *
502 * The functions below are used the create the page table mappings for 565 * The functions below are used the create the page table mappings for
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index c1b17e97252..779ace29247 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -252,7 +252,7 @@ static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
252/* Function to enable the hardware */ 252/* Function to enable the hardware */
253static void iommu_enable(struct amd_iommu *iommu) 253static void iommu_enable(struct amd_iommu *iommu)
254{ 254{
255 printk(KERN_INFO "AMD IOMMU: Enabling IOMMU at %s cap 0x%hx\n", 255 printk(KERN_INFO "AMD-Vi: Enabling IOMMU at %s cap 0x%hx\n",
256 dev_name(&iommu->dev->dev), iommu->cap_ptr); 256 dev_name(&iommu->dev->dev), iommu->cap_ptr);
257 257
258 iommu_feature_enable(iommu, CONTROL_IOMMU_EN); 258 iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
@@ -435,6 +435,20 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
435} 435}
436 436
437/* 437/*
438 * This function resets the command buffer if the IOMMU stopped fetching
439 * commands from it.
440 */
441void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu)
442{
443 iommu_feature_disable(iommu, CONTROL_CMDBUF_EN);
444
445 writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
446 writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
447
448 iommu_feature_enable(iommu, CONTROL_CMDBUF_EN);
449}
450
451/*
438 * This function writes the command buffer address to the hardware and 452 * This function writes the command buffer address to the hardware and
439 * enables it. 453 * enables it.
440 */ 454 */
@@ -450,11 +464,7 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu)
450 memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET, 464 memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET,
451 &entry, sizeof(entry)); 465 &entry, sizeof(entry));
452 466
453 /* set head and tail to zero manually */ 467 amd_iommu_reset_cmd_buffer(iommu);
454 writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
455 writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
456
457 iommu_feature_enable(iommu, CONTROL_CMDBUF_EN);
458} 468}
459 469
460static void __init free_command_buffer(struct amd_iommu *iommu) 470static void __init free_command_buffer(struct amd_iommu *iommu)
@@ -858,7 +868,7 @@ static int __init init_iommu_all(struct acpi_table_header *table)
858 switch (*p) { 868 switch (*p) {
859 case ACPI_IVHD_TYPE: 869 case ACPI_IVHD_TYPE:
860 870
861 DUMP_printk("IOMMU: device: %02x:%02x.%01x cap: %04x " 871 DUMP_printk("device: %02x:%02x.%01x cap: %04x "
862 "seg: %d flags: %01x info %04x\n", 872 "seg: %d flags: %01x info %04x\n",
863 PCI_BUS(h->devid), PCI_SLOT(h->devid), 873 PCI_BUS(h->devid), PCI_SLOT(h->devid),
864 PCI_FUNC(h->devid), h->cap_ptr, 874 PCI_FUNC(h->devid), h->cap_ptr,
@@ -902,7 +912,7 @@ static int __init iommu_setup_msi(struct amd_iommu *iommu)
902 912
903 r = request_irq(iommu->dev->irq, amd_iommu_int_handler, 913 r = request_irq(iommu->dev->irq, amd_iommu_int_handler,
904 IRQF_SAMPLE_RANDOM, 914 IRQF_SAMPLE_RANDOM,
905 "AMD IOMMU", 915 "AMD-Vi",
906 NULL); 916 NULL);
907 917
908 if (r) { 918 if (r) {
@@ -1150,7 +1160,7 @@ int __init amd_iommu_init(void)
1150 1160
1151 1161
1152 if (no_iommu) { 1162 if (no_iommu) {
1153 printk(KERN_INFO "AMD IOMMU disabled by kernel command line\n"); 1163 printk(KERN_INFO "AMD-Vi disabled by kernel command line\n");
1154 return 0; 1164 return 0;
1155 } 1165 }
1156 1166
@@ -1248,16 +1258,16 @@ int __init amd_iommu_init(void)
1248 1258
1249 enable_iommus(); 1259 enable_iommus();
1250 1260
1251 printk(KERN_INFO "AMD IOMMU: device isolation "); 1261 printk(KERN_INFO "AMD-Vi: device isolation ");
1252 if (amd_iommu_isolate) 1262 if (amd_iommu_isolate)
1253 printk("enabled\n"); 1263 printk("enabled\n");
1254 else 1264 else
1255 printk("disabled\n"); 1265 printk("disabled\n");
1256 1266
1257 if (amd_iommu_unmap_flush) 1267 if (amd_iommu_unmap_flush)
1258 printk(KERN_INFO "AMD IOMMU: IO/TLB flush on unmap enabled\n"); 1268 printk(KERN_INFO "AMD-Vi: IO/TLB flush on unmap enabled\n");
1259 else 1269 else
1260 printk(KERN_INFO "AMD IOMMU: Lazy IO/TLB flushing enabled\n"); 1270 printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n");
1261 1271
1262out: 1272out:
1263 return ret; 1273 return ret;