iommu/amd: Set alias DTE in do_attach/do_detach
authorJoerg Roedel <jroedel@suse.de>
Tue, 20 Oct 2015 15:33:38 +0000 (17:33 +0200)
committerJoerg Roedel <jroedel@suse.de>
Wed, 21 Oct 2015 09:30:32 +0000 (11:30 +0200)
With this we don't have to create dev_data entries for
non-existent devices (which only exist as request-ids).

Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/amd_iommu.c

index f8f54a4..68b8ecf 100644 (file)
@@ -1114,11 +1114,15 @@ static int device_flush_iotlb(struct iommu_dev_data *dev_data,
 static int device_flush_dte(struct iommu_dev_data *dev_data)
 {
        struct amd_iommu *iommu;
+       u16 alias;
        int ret;
 
        iommu = amd_iommu_rlookup_table[dev_data->devid];
+       alias = amd_iommu_alias_table[dev_data->devid];
 
        ret = iommu_flush_dte(iommu, dev_data->devid);
+       if (!ret && alias != dev_data->devid)
+               ret = iommu_flush_dte(iommu, alias);
        if (ret)
                return ret;
 
@@ -1984,29 +1988,36 @@ static void do_attach(struct iommu_dev_data *dev_data,
                      struct protection_domain *domain)
 {
        struct amd_iommu *iommu;
+       u16 alias;
        bool ats;
 
        iommu = amd_iommu_rlookup_table[dev_data->devid];
+       alias = amd_iommu_alias_table[dev_data->devid];
        ats   = dev_data->ats.enabled;
 
        /* Update data structures */
        dev_data->domain = domain;
        list_add(&dev_data->list, &domain->dev_list);
-       set_dte_entry(dev_data->devid, domain, ats);
 
        /* Do reference counting */
        domain->dev_iommu[iommu->index] += 1;
        domain->dev_cnt                 += 1;
 
-       /* Flush the DTE entry */
+       /* Update device table */
+       set_dte_entry(dev_data->devid, domain, ats);
+       if (alias != dev_data->devid)
+               set_dte_entry(dev_data->devid, domain, ats);
+
        device_flush_dte(dev_data);
 }
 
 static void do_detach(struct iommu_dev_data *dev_data)
 {
        struct amd_iommu *iommu;
+       u16 alias;
 
        iommu = amd_iommu_rlookup_table[dev_data->devid];
+       alias = amd_iommu_alias_table[dev_data->devid];
 
        /* decrease reference counters */
        dev_data->domain->dev_iommu[iommu->index] -= 1;
@@ -2016,6 +2027,8 @@ static void do_detach(struct iommu_dev_data *dev_data)
        dev_data->domain = NULL;
        list_del(&dev_data->list);
        clear_dte_entry(dev_data->devid);
+       if (alias != dev_data->devid)
+               clear_dte_entry(alias);
 
        /* Flush the DTE entry */
        device_flush_dte(dev_data);