diff options
| -rw-r--r-- | arch/x86/kernel/amd_iommu.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 2dc093370d2d..2333d615f5ee 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
| @@ -61,6 +61,7 @@ static u64* alloc_pte(struct protection_domain *dom, | |||
| 61 | static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, | 61 | static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, |
| 62 | unsigned long start_page, | 62 | unsigned long start_page, |
| 63 | unsigned int pages); | 63 | unsigned int pages); |
| 64 | static void reset_iommu_command_buffer(struct amd_iommu *iommu); | ||
| 64 | 65 | ||
| 65 | #ifndef BUS_NOTIFY_UNBOUND_DRIVER | 66 | #ifndef BUS_NOTIFY_UNBOUND_DRIVER |
| 66 | #define BUS_NOTIFY_UNBOUND_DRIVER 0x0005 | 67 | #define BUS_NOTIFY_UNBOUND_DRIVER 0x0005 |
| @@ -156,7 +157,7 @@ static void dump_command(unsigned long phys_addr) | |||
| 156 | pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]); | 157 | pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]); |
| 157 | } | 158 | } |
| 158 | 159 | ||
| 159 | static void iommu_print_event(void *__evt) | 160 | static void iommu_print_event(struct amd_iommu *iommu, void *__evt) |
| 160 | { | 161 | { |
| 161 | u32 *event = __evt; | 162 | u32 *event = __evt; |
| 162 | int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; | 163 | int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; |
| @@ -195,6 +196,7 @@ static void iommu_print_event(void *__evt) | |||
| 195 | break; | 196 | break; |
| 196 | case EVENT_TYPE_ILL_CMD: | 197 | case EVENT_TYPE_ILL_CMD: |
| 197 | printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address); | 198 | printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address); |
| 199 | reset_iommu_command_buffer(iommu); | ||
| 198 | dump_command(address); | 200 | dump_command(address); |
| 199 | break; | 201 | break; |
| 200 | case EVENT_TYPE_CMD_HARD_ERR: | 202 | case EVENT_TYPE_CMD_HARD_ERR: |
| @@ -229,7 +231,7 @@ static void iommu_poll_events(struct amd_iommu *iommu) | |||
| 229 | tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); | 231 | tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); |
| 230 | 232 | ||
| 231 | while (head != tail) { | 233 | while (head != tail) { |
| 232 | iommu_print_event(iommu->evt_buf + head); | 234 | iommu_print_event(iommu, iommu->evt_buf + head); |
| 233 | head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size; | 235 | head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size; |
| 234 | } | 236 | } |
| 235 | 237 | ||
| @@ -547,6 +549,15 @@ void amd_iommu_flush_all_devices(void) | |||
| 547 | } | 549 | } |
| 548 | } | 550 | } |
| 549 | 551 | ||
| 552 | static void reset_iommu_command_buffer(struct amd_iommu *iommu) | ||
| 553 | { | ||
| 554 | pr_err("AMD-Vi: Resetting IOMMU command buffer\n"); | ||
| 555 | |||
| 556 | amd_iommu_reset_cmd_buffer(iommu); | ||
| 557 | flush_all_devices_for_iommu(iommu); | ||
| 558 | flush_all_domains_on_iommu(iommu); | ||
| 559 | } | ||
| 560 | |||
| 550 | /**************************************************************************** | 561 | /**************************************************************************** |
| 551 | * | 562 | * |
| 552 | * The functions below are used the create the page table mappings for | 563 | * The functions below are used the create the page table mappings for |
