| From: Anna-Maria Gleixner <anna-maria@linutronix.de> |
| Date: Mon, 16 Apr 2018 16:15:25 +0200 |
| Subject: [PATCH] iommu/amd: Do not flush when device is busy |
| |
| When device is already attached to a domain, there is no need to execute |
| the domain_flush_tlb_pde(). Therefore move the check if the domain is set |
| into attach_device(). |
| |
| Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de> |
| Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| --- |
| drivers/iommu/amd_iommu.c | 32 ++++++++++---------------------- |
| 1 file changed, 10 insertions(+), 22 deletions(-) |
| |
| --- a/drivers/iommu/amd_iommu.c |
| +++ b/drivers/iommu/amd_iommu.c |
| @@ -1876,8 +1876,11 @@ static void clear_dte_entry(u16 devid) |
| amd_iommu_apply_erratum_63(devid); |
| } |
| |
| -static void do_attach(struct iommu_dev_data *dev_data, |
| - struct protection_domain *domain) |
| +/* |
| + * This function does assigns the device visible for the hardware |
| + */ |
| +static void __attach_device(struct iommu_dev_data *dev_data, |
| + struct protection_domain *domain) |
| { |
| struct amd_iommu *iommu; |
| u16 alias; |
| @@ -1930,23 +1933,6 @@ static void __detach_device(struct iommu |
| device_flush_dte(dev_data); |
| } |
| |
| -/* |
| - * If a device is not yet associated with a domain, this function does |
| - * assigns it visible for the hardware |
| - */ |
| -static int __attach_device(struct iommu_dev_data *dev_data, |
| - struct protection_domain *domain) |
| -{ |
| - if (dev_data->domain != NULL) |
| - return -EBUSY; |
| - |
| - /* Attach alias group root */ |
| - do_attach(dev_data, domain); |
| - |
| - return 0; |
| -} |
| - |
| - |
| static void pdev_iommuv2_disable(struct pci_dev *pdev) |
| { |
| pci_disable_ats(pdev); |
| @@ -2043,7 +2029,6 @@ static int attach_device(struct device * |
| struct pci_dev *pdev; |
| struct iommu_dev_data *dev_data; |
| unsigned long flags; |
| - int ret; |
| |
| dev_data = get_dev_data(dev); |
| |
| @@ -2071,8 +2056,11 @@ static int attach_device(struct device * |
| |
| skip_ats_check: |
| |
| + if (dev_data->domain != NULL) |
| + return -EBUSY; |
| + |
| spin_lock_irqsave(&domain->lock, flags); |
| - ret = __attach_device(dev_data, domain); |
| + __attach_device(dev_data, domain); |
| spin_unlock_irqrestore(&domain->lock, flags); |
| |
| /* |
| @@ -2082,7 +2070,7 @@ static int attach_device(struct device * |
| */ |
| domain_flush_tlb_pde(domain); |
| |
| - return ret; |
| + return 0; |
| } |
| |
| /* |