diff options
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 658ee39e6..532e2a211 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -1835,8 +1835,8 @@ static void free_gcr3_table(struct protection_domain *domain) free_gcr3_tbl_level2(domain->gcr3_tbl); else if (domain->glx == 1) free_gcr3_tbl_level1(domain->gcr3_tbl); - else if (domain->glx != 0) - BUG(); + else + BUG_ON(domain->glx != 0); free_page((unsigned long)domain->gcr3_tbl); } @@ -1974,8 +1974,8 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats) static void clear_dte_entry(u16 devid) { /* remove entry from the device table seen by the hardware */ - amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV; - amd_iommu_dev_table[devid].data[1] = 0; + amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV; + amd_iommu_dev_table[devid].data[1] &= DTE_FLAG_MASK; amd_iommu_apply_erratum_63(devid); } @@ -2006,6 +2006,15 @@ static void do_detach(struct iommu_dev_data *dev_data) { struct amd_iommu *iommu; + /* + * First check if the device is still attached. It might already + * be detached from its domain because the generic + * iommu_detach_group code detached it and we try again here in + * our alias handling. + */ + if (!dev_data->domain) + return; + iommu = amd_iommu_rlookup_table[dev_data->devid]; /* decrease reference counters */ @@ -3947,11 +3956,6 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq, if (ret < 0) return ret; - ret = -ENOMEM; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - goto out_free_parent; - if (info->type == X86_IRQ_ALLOC_TYPE_IOAPIC) { if (get_irq_table(devid, true)) index = info->ioapic_pin; @@ -3962,7 +3966,6 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq, } if (index < 0) { pr_warn("Failed to allocate IRTE\n"); - kfree(data); goto out_free_parent; } @@ -3974,17 +3977,18 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq, goto out_free_data; } - if (i > 0) { - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - goto out_free_data; - } + ret = -ENOMEM; + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + goto out_free_data; + irq_data->hwirq = (devid << 16) + i; irq_data->chip_data = data; irq_data->chip = &amd_ir_chip; irq_remapping_prepare_irte(data, cfg, info, devid, index, i); irq_set_status_flags(virq + i, IRQ_MOVE_PCNTXT); } + return 0; out_free_data: |