Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e25bfb56 authored by Joerg Roedel's avatar Joerg Roedel
Browse files

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: default avatarJoerg Roedel <jroedel@suse.de>
parent 272e4f99
Loading
Loading
Loading
Loading
+15 −2
Original line number Original line Diff line number Diff line
@@ -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)
static int device_flush_dte(struct iommu_dev_data *dev_data)
{
{
	struct amd_iommu *iommu;
	struct amd_iommu *iommu;
	u16 alias;
	int ret;
	int ret;


	iommu = amd_iommu_rlookup_table[dev_data->devid];
	iommu = amd_iommu_rlookup_table[dev_data->devid];
	alias = amd_iommu_alias_table[dev_data->devid];


	ret = iommu_flush_dte(iommu, 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)
	if (ret)
		return ret;
		return ret;


@@ -1984,29 +1988,36 @@ static void do_attach(struct iommu_dev_data *dev_data,
		      struct protection_domain *domain)
		      struct protection_domain *domain)
{
{
	struct amd_iommu *iommu;
	struct amd_iommu *iommu;
	u16 alias;
	bool ats;
	bool ats;


	iommu = amd_iommu_rlookup_table[dev_data->devid];
	iommu = amd_iommu_rlookup_table[dev_data->devid];
	alias = amd_iommu_alias_table[dev_data->devid];
	ats   = dev_data->ats.enabled;
	ats   = dev_data->ats.enabled;


	/* Update data structures */
	/* Update data structures */
	dev_data->domain = domain;
	dev_data->domain = domain;
	list_add(&dev_data->list, &domain->dev_list);
	list_add(&dev_data->list, &domain->dev_list);
	set_dte_entry(dev_data->devid, domain, ats);


	/* Do reference counting */
	/* Do reference counting */
	domain->dev_iommu[iommu->index] += 1;
	domain->dev_iommu[iommu->index] += 1;
	domain->dev_cnt                 += 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);
	device_flush_dte(dev_data);
}
}


static void do_detach(struct iommu_dev_data *dev_data)
static void do_detach(struct iommu_dev_data *dev_data)
{
{
	struct amd_iommu *iommu;
	struct amd_iommu *iommu;
	u16 alias;


	iommu = amd_iommu_rlookup_table[dev_data->devid];
	iommu = amd_iommu_rlookup_table[dev_data->devid];
	alias = amd_iommu_alias_table[dev_data->devid];


	/* decrease reference counters */
	/* decrease reference counters */
	dev_data->domain->dev_iommu[iommu->index] -= 1;
	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;
	dev_data->domain = NULL;
	list_del(&dev_data->list);
	list_del(&dev_data->list);
	clear_dte_entry(dev_data->devid);
	clear_dte_entry(dev_data->devid);
	if (alias != dev_data->devid)
		clear_dte_entry(alias);


	/* Flush the DTE entry */
	/* Flush the DTE entry */
	device_flush_dte(dev_data);
	device_flush_dte(dev_data);