aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/amd_iommu.c
diff options
context:
space:
mode:
authorJoerg Roedel <jroedel@suse.de>2015-10-20 11:33:38 -0400
committerJoerg Roedel <jroedel@suse.de>2015-10-21 05:30:32 -0400
commite25bfb56ea7f046b71414e02f80f620deb5c6362 (patch)
treeaefaf08609948368c4d256c292e877cd0e63cb39 /drivers/iommu/amd_iommu.c
parent272e4f99e966989394b167b695ab489c60fe1243 (diff)
iommu/amd: Set alias DTE in do_attach/do_detach
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>
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
-rw-r--r--drivers/iommu/amd_iommu.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index f8f54a4b1d8f..68b8ecf075ca 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1114,11 +1114,15 @@ static int device_flush_iotlb(struct iommu_dev_data *dev_data,
1114static int device_flush_dte(struct iommu_dev_data *dev_data) 1114static int device_flush_dte(struct iommu_dev_data *dev_data)
1115{ 1115{
1116 struct amd_iommu *iommu; 1116 struct amd_iommu *iommu;
1117 u16 alias;
1117 int ret; 1118 int ret;
1118 1119
1119 iommu = amd_iommu_rlookup_table[dev_data->devid]; 1120 iommu = amd_iommu_rlookup_table[dev_data->devid];
1121 alias = amd_iommu_alias_table[dev_data->devid];
1120 1122
1121 ret = iommu_flush_dte(iommu, dev_data->devid); 1123 ret = iommu_flush_dte(iommu, dev_data->devid);
1124 if (!ret && alias != dev_data->devid)
1125 ret = iommu_flush_dte(iommu, alias);
1122 if (ret) 1126 if (ret)
1123 return ret; 1127 return ret;
1124 1128
@@ -1984,29 +1988,36 @@ static void do_attach(struct iommu_dev_data *dev_data,
1984 struct protection_domain *domain) 1988 struct protection_domain *domain)
1985{ 1989{
1986 struct amd_iommu *iommu; 1990 struct amd_iommu *iommu;
1991 u16 alias;
1987 bool ats; 1992 bool ats;
1988 1993
1989 iommu = amd_iommu_rlookup_table[dev_data->devid]; 1994 iommu = amd_iommu_rlookup_table[dev_data->devid];
1995 alias = amd_iommu_alias_table[dev_data->devid];
1990 ats = dev_data->ats.enabled; 1996 ats = dev_data->ats.enabled;
1991 1997
1992 /* Update data structures */ 1998 /* Update data structures */
1993 dev_data->domain = domain; 1999 dev_data->domain = domain;
1994 list_add(&dev_data->list, &domain->dev_list); 2000 list_add(&dev_data->list, &domain->dev_list);
1995 set_dte_entry(dev_data->devid, domain, ats);
1996 2001
1997 /* Do reference counting */ 2002 /* Do reference counting */
1998 domain->dev_iommu[iommu->index] += 1; 2003 domain->dev_iommu[iommu->index] += 1;
1999 domain->dev_cnt += 1; 2004 domain->dev_cnt += 1;
2000 2005
2001 /* Flush the DTE entry */ 2006 /* Update device table */
2007 set_dte_entry(dev_data->devid, domain, ats);
2008 if (alias != dev_data->devid)
2009 set_dte_entry(dev_data->devid, domain, ats);
2010
2002 device_flush_dte(dev_data); 2011 device_flush_dte(dev_data);
2003} 2012}
2004 2013
2005static void do_detach(struct iommu_dev_data *dev_data) 2014static void do_detach(struct iommu_dev_data *dev_data)
2006{ 2015{
2007 struct amd_iommu *iommu; 2016 struct amd_iommu *iommu;
2017 u16 alias;
2008 2018
2009 iommu = amd_iommu_rlookup_table[dev_data->devid]; 2019 iommu = amd_iommu_rlookup_table[dev_data->devid];
2020 alias = amd_iommu_alias_table[dev_data->devid];
2010 2021
2011 /* decrease reference counters */ 2022 /* decrease reference counters */
2012 dev_data->domain->dev_iommu[iommu->index] -= 1; 2023 dev_data->domain->dev_iommu[iommu->index] -= 1;
@@ -2016,6 +2027,8 @@ static void do_detach(struct iommu_dev_data *dev_data)
2016 dev_data->domain = NULL; 2027 dev_data->domain = NULL;
2017 list_del(&dev_data->list); 2028 list_del(&dev_data->list);
2018 clear_dte_entry(dev_data->devid); 2029 clear_dte_entry(dev_data->devid);
2030 if (alias != dev_data->devid)
2031 clear_dte_entry(alias);
2019 2032
2020 /* Flush the DTE entry */ 2033 /* Flush the DTE entry */
2021 device_flush_dte(dev_data); 2034 device_flush_dte(dev_data);