| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Will Deacon <will@kernel.org> |
| Date: Mon, 11 Nov 2019 11:34:37 +0000 |
| Subject: FROMLIST: iommu/arm-smmu: Prevent forced unbinding of Arm SMMU |
| drivers |
| |
| Forcefully unbinding the Arm SMMU drivers is a pretty dangerous operation, |
| since it will likely lead to catastrophic failure for any DMA devices |
| mastering through the SMMU being unbound. When the driver then attempts |
| to "handle" the fatal faults, it's very easy to trip over dead data |
| structures, leading to use-after-free. |
| |
| On John's machine, he reports that the machine was "unusable" due to |
| loss of the storage controller following a forced unbind of the SMMUv3 |
| driver: |
| |
| | # cd ./bus/platform/drivers/arm-smmu-v3 |
| | # echo arm-smmu-v3.0.auto > unbind |
| | hisi_sas_v2_hw HISI0162:01: CQE_AXI_W_ERR (0x800) found! |
| | platform arm-smmu-v3.0.auto: CMD_SYNC timeout at 0x00000146 |
| | [hwprod 0x00000146, hwcons 0x00000000] |
| |
| Prevent this forced unbinding of the drivers by setting "suppress_bind_attrs" |
| to true. |
| |
| Link: https://lore.kernel.org/lkml/06dfd385-1af0-3106-4cc5-6a5b8e864759@huawei.com |
| Reported-by: John Garry <john.garry@huawei.com> |
| Signed-off-by: Will Deacon <will@kernel.org> |
| Bug: 140290589 |
| Link: https://lore.kernel.org/lkml/20191121114918.2293-10-will@kernel.org/ |
| Signed-off-by: Will Deacon <willdeacon@google.com> |
| Change-Id: I8b1c439f7ba11d6fc38cdf686948ef5909871dfb |
| --- |
| drivers/iommu/arm-smmu-v3.c | 5 +++-- |
| drivers/iommu/arm-smmu.c | 7 ++++--- |
| 2 files changed, 7 insertions(+), 5 deletions(-) |
| |
| diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c |
| index 9cdb8f322d89..e6c97bf0104c 100644 |
| --- a/drivers/iommu/arm-smmu-v3.c |
| +++ b/drivers/iommu/arm-smmu-v3.c |
| @@ -3700,8 +3700,9 @@ MODULE_DEVICE_TABLE(of, arm_smmu_of_match); |
| |
| static struct platform_driver arm_smmu_driver = { |
| .driver = { |
| - .name = "arm-smmu-v3", |
| - .of_match_table = of_match_ptr(arm_smmu_of_match), |
| + .name = "arm-smmu-v3", |
| + .of_match_table = of_match_ptr(arm_smmu_of_match), |
| + .suppress_bind_attrs = true, |
| }, |
| .probe = arm_smmu_device_probe, |
| .remove = arm_smmu_device_remove, |
| diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c |
| index 53bbe0663b9e..d6c83bd69555 100644 |
| --- a/drivers/iommu/arm-smmu.c |
| +++ b/drivers/iommu/arm-smmu.c |
| @@ -2237,9 +2237,10 @@ static const struct dev_pm_ops arm_smmu_pm_ops = { |
| |
| static struct platform_driver arm_smmu_driver = { |
| .driver = { |
| - .name = "arm-smmu", |
| - .of_match_table = of_match_ptr(arm_smmu_of_match), |
| - .pm = &arm_smmu_pm_ops, |
| + .name = "arm-smmu", |
| + .of_match_table = of_match_ptr(arm_smmu_of_match), |
| + .pm = &arm_smmu_pm_ops, |
| + .suppress_bind_attrs = true, |
| }, |
| .probe = arm_smmu_device_probe, |
| .remove = arm_smmu_device_remove, |