mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
2ea659a9ef
commit
30bf2df65b
|
@ -138,6 +138,8 @@ struct iommu_dev_data {
|
|||
PPR completions */
|
||||
u32 errata; /* Bitmap for errata to apply */
|
||||
bool use_vapic; /* Enable device to use vapic mode */
|
||||
|
||||
struct ratelimit_state rs; /* Ratelimit IOPF messages */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -253,6 +255,8 @@ static struct iommu_dev_data *alloc_dev_data(u16 devid)
|
|||
list_add_tail(&dev_data->dev_data_list, &dev_data_list);
|
||||
spin_unlock_irqrestore(&dev_data_list_lock, flags);
|
||||
|
||||
ratelimit_default_init(&dev_data->rs);
|
||||
|
||||
return dev_data;
|
||||
}
|
||||
|
||||
|
@ -551,6 +555,29 @@ static void dump_command(unsigned long phys_addr)
|
|||
pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]);
|
||||
}
|
||||
|
||||
static void amd_iommu_report_page_fault(u16 devid, u16 domain_id,
|
||||
u64 address, int flags)
|
||||
{
|
||||
struct iommu_dev_data *dev_data = NULL;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
pdev = pci_get_bus_and_slot(PCI_BUS_NUM(devid), devid & 0xff);
|
||||
if (pdev)
|
||||
dev_data = get_dev_data(&pdev->dev);
|
||||
|
||||
if (dev_data && __ratelimit(&dev_data->rs)) {
|
||||
dev_err(&pdev->dev, "AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x%04x address=0x%016llx flags=0x%04x]\n",
|
||||
domain_id, address, flags);
|
||||
} else if (printk_ratelimit()) {
|
||||
pr_err("AMD-Vi: Event logged [IO_PAGE_FAULT device=%02x:%02x.%x domain=0x%04x address=0x%016llx flags=0x%04x]\n",
|
||||
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
|
||||
domain_id, address, flags);
|
||||
}
|
||||
|
||||
if (pdev)
|
||||
pci_dev_put(pdev);
|
||||
}
|
||||
|
||||
static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
|
||||
{
|
||||
int type, devid, domid, flags;
|
||||
|
@ -575,7 +602,12 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
|
|||
goto retry;
|
||||
}
|
||||
|
||||
printk(KERN_ERR "AMD-Vi: Event logged [");
|
||||
if (type == EVENT_TYPE_IO_FAULT) {
|
||||
amd_iommu_report_page_fault(devid, domid, address, flags);
|
||||
return;
|
||||
} else {
|
||||
printk(KERN_ERR "AMD-Vi: Event logged [");
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case EVENT_TYPE_ILL_DEV:
|
||||
|
@ -585,12 +617,6 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
|
|||
address, flags);
|
||||
dump_dte_entry(devid);
|
||||
break;
|
||||
case EVENT_TYPE_IO_FAULT:
|
||||
printk("IO_PAGE_FAULT device=%02x:%02x.%x "
|
||||
"domain=0x%04x address=0x%016llx flags=0x%04x]\n",
|
||||
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
|
||||
domid, address, flags);
|
||||
break;
|
||||
case EVENT_TYPE_DEV_TAB_ERR:
|
||||
printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
|
||||
"address=0x%016llx flags=0x%04x]\n",
|
||||
|
|
Loading…
Reference in New Issue