aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Roedel <jroedel@suse.de>2017-05-15 10:25:03 -0400
committerJoerg Roedel <jroedel@suse.de>2017-05-30 05:44:19 -0400
commit30bf2df65b0d18f53ee9c92131239f66c8f55d63 (patch)
tree4200b608021216be069a1800f3eef9f14410bc64
parent2ea659a9ef488125eb46da6eb571de5eae5c43f6 (diff)
iommu/amd: Ratelimit io-page-faults per device
Misbehaving devices can cause an endless chain of io-page-faults, flooding dmesg and making the system-log unusable or even prevent the system from booting. So ratelimit the error messages about io-page-faults on a per-device basis. Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/amd_iommu.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 63cacf5d6cf2..d3ff766a8ca6 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -138,6 +138,8 @@ struct iommu_dev_data {
138 PPR completions */ 138 PPR completions */
139 u32 errata; /* Bitmap for errata to apply */ 139 u32 errata; /* Bitmap for errata to apply */
140 bool use_vapic; /* Enable device to use vapic mode */ 140 bool use_vapic; /* Enable device to use vapic mode */
141
142 struct ratelimit_state rs; /* Ratelimit IOPF messages */
141}; 143};
142 144
143/* 145/*
@@ -253,6 +255,8 @@ static struct iommu_dev_data *alloc_dev_data(u16 devid)
253 list_add_tail(&dev_data->dev_data_list, &dev_data_list); 255 list_add_tail(&dev_data->dev_data_list, &dev_data_list);
254 spin_unlock_irqrestore(&dev_data_list_lock, flags); 256 spin_unlock_irqrestore(&dev_data_list_lock, flags);
255 257
258 ratelimit_default_init(&dev_data->rs);
259
256 return dev_data; 260 return dev_data;
257} 261}
258 262
@@ -551,6 +555,29 @@ static void dump_command(unsigned long phys_addr)
551 pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]); 555 pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]);
552} 556}
553 557
558static void amd_iommu_report_page_fault(u16 devid, u16 domain_id,
559 u64 address, int flags)
560{
561 struct iommu_dev_data *dev_data = NULL;
562 struct pci_dev *pdev;
563
564 pdev = pci_get_bus_and_slot(PCI_BUS_NUM(devid), devid & 0xff);
565 if (pdev)
566 dev_data = get_dev_data(&pdev->dev);
567
568 if (dev_data && __ratelimit(&dev_data->rs)) {
569 dev_err(&pdev->dev, "AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x%04x address=0x%016llx flags=0x%04x]\n",
570 domain_id, address, flags);
571 } else if (printk_ratelimit()) {
572 pr_err("AMD-Vi: Event logged [IO_PAGE_FAULT device=%02x:%02x.%x domain=0x%04x address=0x%016llx flags=0x%04x]\n",
573 PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
574 domain_id, address, flags);
575 }
576
577 if (pdev)
578 pci_dev_put(pdev);
579}
580
554static void iommu_print_event(struct amd_iommu *iommu, void *__evt) 581static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
555{ 582{
556 int type, devid, domid, flags; 583 int type, devid, domid, flags;
@@ -575,7 +602,12 @@ retry:
575 goto retry; 602 goto retry;
576 } 603 }
577 604
578 printk(KERN_ERR "AMD-Vi: Event logged ["); 605 if (type == EVENT_TYPE_IO_FAULT) {
606 amd_iommu_report_page_fault(devid, domid, address, flags);
607 return;
608 } else {
609 printk(KERN_ERR "AMD-Vi: Event logged [");
610 }
579 611
580 switch (type) { 612 switch (type) {
581 case EVENT_TYPE_ILL_DEV: 613 case EVENT_TYPE_ILL_DEV:
@@ -585,12 +617,6 @@ retry:
585 address, flags); 617 address, flags);
586 dump_dte_entry(devid); 618 dump_dte_entry(devid);
587 break; 619 break;
588 case EVENT_TYPE_IO_FAULT:
589 printk("IO_PAGE_FAULT device=%02x:%02x.%x "
590 "domain=0x%04x address=0x%016llx flags=0x%04x]\n",
591 PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
592 domid, address, flags);
593 break;
594 case EVENT_TYPE_DEV_TAB_ERR: 620 case EVENT_TYPE_DEV_TAB_ERR:
595 printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x " 621 printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
596 "address=0x%016llx flags=0x%04x]\n", 622 "address=0x%016llx flags=0x%04x]\n",