diff options
author | Joerg Roedel <jroedel@suse.de> | 2015-10-20 11:33:38 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2015-10-21 05:30:32 -0400 |
commit | e25bfb56ea7f046b71414e02f80f620deb5c6362 (patch) | |
tree | aefaf08609948368c4d256c292e877cd0e63cb39 /drivers/iommu/amd_iommu.c | |
parent | 272e4f99e966989394b167b695ab489c60fe1243 (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.c | 17 |
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, | |||
1114 | static int device_flush_dte(struct iommu_dev_data *dev_data) | 1114 | static 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 | ||
2005 | static void do_detach(struct iommu_dev_data *dev_data) | 2014 | static 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); |