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 <isaacm@codeaurora.org>
Signed-off-by: George Shen <sqiao@codeaurora.org>
This commit is contained in:
Isaac J. Manjarres 2019-11-16 08:42:01 -08:00 • committed by George Shen
commit 008a22d3e9

View file

@ -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) {