From 535b44cab1e998d045a5d4ee1d1efc4aa4a5a02c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 6 Sep 2022 18:13:46 +0200 Subject: [PATCH] iommu: Workaround for AMD HD-audio regressions Patch-mainline: Never, testing References: bsc#1202492 Signed-off-by: Takashi Iwai --- drivers/iommu/amd/iommu_v2.c | 2 ++ drivers/iommu/iommu.c | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/amd/iommu_v2.c b/drivers/iommu/amd/iommu_v2.c index 696d5555be57..6a1f02c62dff 100644 --- a/drivers/iommu/amd/iommu_v2.c +++ b/drivers/iommu/amd/iommu_v2.c @@ -777,6 +777,8 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids) if (dev_state->domain == NULL) goto out_free_states; + /* See iommu_is_default_domain() */ + dev_state->domain->type = IOMMU_DOMAIN_IDENTITY; amd_iommu_domain_direct_map(dev_state->domain); ret = amd_iommu_domain_enable_v2(dev_state->domain, pasids); diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 780fb7071577..fe8bd17f5231 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -3076,6 +3076,24 @@ static ssize_t iommu_group_store_type(struct iommu_group *group, return ret; } +static bool iommu_is_default_domain(struct iommu_group *group) +{ + if (group->domain == group->default_domain) + return true; + + /* + * If the default domain was set to identity and it is still an identity + * domain then we consider this a pass. This happens because of + * amd_iommu_init_device() replacing the default idenity domain with an + * identity domain that has a different configuration for AMDGPU. + */ + if (group->default_domain && + group->default_domain->type == IOMMU_DOMAIN_IDENTITY && + group->domain && group->domain->type == IOMMU_DOMAIN_IDENTITY) + return true; + return false; +} + /** * iommu_device_use_default_domain() - Device driver wants to handle device * DMA through the kernel DMA API. @@ -3094,8 +3112,7 @@ int iommu_device_use_default_domain(struct device *dev) mutex_lock(&group->mutex); if (group->owner_cnt) { - if (group->domain != group->default_domain || - group->owner) { + if (group->owner || !iommu_is_default_domain(group)) { ret = -EBUSY; goto unlock_out; } -- 2.35.3