diff options
author | Patrick Daly <pdaly@codeaurora.org> | 2016-03-11 17:31:20 -0800 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:25:40 -0700 |
commit | 23daa77f249b158b6877a880365de81c5d98ef89 (patch) | |
tree | 18e6e3cc03a480124595637ae09758ffcb9f2ea8 /drivers/iommu/arm-smmu.c | |
parent | 2d6a28e2e3a2c97f36060da27c6b09bdae0d6da1 (diff) |
iommu/arm-smmu: Fix a Null pointer dereference
Introduced by 99afd0531465fdaa95aaf5d0a9b73f7669d0f9c7.
"iommu/arm-smmu: Be explicit about security mechanism"
Internal error: Oops: 96000006 [#1] PREEMPT SMP
[<ffffffc0009f37d0>] arm_smmu_is_master_side_secure+0x14/0x28
[<ffffffc0009f029c>] io_pgtable_free_pages_exact+0x30/0x94
[<ffffffc0009f0388>] __arm_lpae_free_pgtable+0x88/0xf0
[<ffffffc0009f03e4>] __arm_lpae_free_pgtable+0xe4/0xf0
[<ffffffc0009f0410>] arm_lpae_free_pgtable+0x20/0x38
[<ffffffc0009f01cc>] free_io_pgtable_ops+0x24/0x30
[<ffffffc0009f4ce8>] arm_smmu_domain_destroy+0x1c/0xa8
[<ffffffc0009ed0cc>] iommu_domain_free+0x1c/0x34
[<ffffffc0009f35c4>] iommu_debug_device_profiling+0x660/0x6a4
[<ffffffc0009f361c>] iommu_debug_secure_profiling_show+0x14/0x24
[<ffffffc0001c4a2c>] seq_read+0x180/0x3b0
Found when running:
cat /sys/kernel/debug/iommu/tests/client_name/secure_profiling
Add a new smmu_domain variable to track whether the domain belongs to a
master-side or slave-side secure context.
Change-Id: Ib32cc6fb03f863522de10e416007114c6e91776f
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
Diffstat (limited to 'drivers/iommu/arm-smmu.c')
-rw-r--r-- | drivers/iommu/arm-smmu.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 761381389907..9be51cdfa717 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -455,6 +455,7 @@ struct arm_smmu_domain { enum arm_smmu_domain_stage stage; struct mutex init_mutex; /* Protects smmu pointer */ u32 attributes; + bool slave_side_secure; u32 secure_vmid; struct list_head pte_info_list; struct list_head unassign_list; @@ -1477,14 +1478,14 @@ static bool arm_smmu_has_secure_vmid(struct arm_smmu_domain *smmu_domain) static bool arm_smmu_is_slave_side_secure(struct arm_smmu_domain *smmu_domain) { - return arm_smmu_has_secure_vmid(smmu_domain) && - arm_smmu_is_static_cb(smmu_domain->smmu); + return arm_smmu_has_secure_vmid(smmu_domain) + && smmu_domain->slave_side_secure; } static bool arm_smmu_is_master_side_secure(struct arm_smmu_domain *smmu_domain) { return arm_smmu_has_secure_vmid(smmu_domain) - && !arm_smmu_is_static_cb(smmu_domain->smmu); + && !smmu_domain->slave_side_secure; } static void arm_smmu_secure_domain_lock(struct arm_smmu_domain *smmu_domain) @@ -2101,6 +2102,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) dev_err(dev, "Failed to get valid context bank\n"); goto err_disable_clocks; } + smmu_domain->slave_side_secure = true; } /* Ensure that the domain is finalised */ |