From 008a22d3e9196ddb266f90e2ee2e856c496ca525 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Sat, 16 Nov 2019 08:42:01 -0800 Subject: [PATCH] iommu/arm-smmu: Fix atomic domain attribute check When checking if a domain is a atomic or not, the driver code will take the bitwise AND of the 64-bit domain attributes field and a bitmask with bit 32 set. This value is then implicitly cast to an int, which truncates the upper 32 bits--losing the bit that indicates if the domain is atomic or not--and based on that int, we determine if the domain is atomic, which will vacuously be false. Instead, check if the bitwise AND operation yields a non-zero value when determining if a domain is atomic or not to prevent any truncation errors. Change-Id: I96753035b47b848bc4d1e8029c8f3f46e03f8c67 Signed-off-by: Isaac J. Manjarres Signed-off-by: George Shen --- drivers/iommu/arm-smmu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 7e766374edfd..aafac8dd63e3 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -835,8 +835,8 @@ static int arm_smmu_domain_power_on(struct iommu_domain *domain, struct arm_smmu_device *smmu) { struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); - int atomic_domain = smmu_domain->attributes & - (1ULL << DOMAIN_ATTR_ATOMIC); + bool atomic_domain = !!(smmu_domain->attributes & + (1ULL << DOMAIN_ATTR_ATOMIC)); if (atomic_domain) return arm_smmu_power_on_atomic(smmu->pwr); @@ -852,8 +852,8 @@ static void arm_smmu_domain_power_off(struct iommu_domain *domain, struct arm_smmu_device *smmu) { struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); - int atomic_domain = smmu_domain->attributes & - (1ULL << DOMAIN_ATTR_ATOMIC); + bool atomic_domain = !!(smmu_domain->attributes & + (1ULL << DOMAIN_ATTR_ATOMIC)); if (atomic_domain) { arm_smmu_power_off_atomic(smmu, smmu->pwr); @@ -2432,8 +2432,8 @@ static void arm_smmu_detach_dev(struct iommu_domain *domain, struct arm_smmu_device *smmu = smmu_domain->smmu; struct iommu_fwspec *fwspec = dev->iommu_fwspec; int dynamic = smmu_domain->attributes & (1ULL << DOMAIN_ATTR_DYNAMIC); - int atomic_domain = smmu_domain->attributes & - (1ULL << DOMAIN_ATTR_ATOMIC); + bool atomic_domain = !!(smmu_domain->attributes & + (1ULL << DOMAIN_ATTR_ATOMIC)); if (dynamic) return; @@ -2739,8 +2739,8 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) struct iommu_fwspec *fwspec = dev->iommu_fwspec; struct arm_smmu_device *smmu; struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); - int atomic_domain = smmu_domain->attributes & - (1ULL << DOMAIN_ATTR_ATOMIC); + bool atomic_domain = !!(smmu_domain->attributes & + (1ULL << DOMAIN_ATTR_ATOMIC)); int s1_bypass = 0; if (!fwspec || fwspec->ops != &arm_smmu_ops.iommu_ops) {