Skip to content

Commit

Permalink
iommu/arm-smmu-qcom: Avoid disabling secured context banks
Browse files Browse the repository at this point in the history
Some Qualcomm SoCs' TZ/hypervisor configuration is disallowing the
disablement of some context banks, being them used for tzapps and/or
remote processors; any attempt to disable such CBs will result in
triggering a fault and the system will freeze and/or reset.

For this reason, get a list of context banks that should never get
disabled during smmu initialization through a DT array property
`qcom,reset-nodisable-cbs`.
It was chosen to not hardcode the CBs as this is dependant on the
SoC's firmware, which may vary on different boards.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
(JAMI: fixup for v6.0-rc1)
  • Loading branch information
kholk authored and minlexx committed Jun 3, 2023
1 parent 7d3ac89 commit 2ea4f6a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
44 changes: 44 additions & 0 deletions drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,10 +397,32 @@ static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
return ret;
}

static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
{
const struct device_node *np = smmu->dev->of_node;

arm_mmu500_reset(smmu);

if (of_device_is_compatible(np, "qcom,sdm845-smmu-500"))
return qcom_sdm845_smmu500_reset(smmu);

return 0;
}

static bool qcom_smmu500_reset_cb_nodisable(struct arm_smmu_device *smmu,
int cbndx)
{
struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);

return test_bit(cbndx, qsmmu->reset_cb_nodisable_mask);
}

static const struct arm_smmu_impl qcom_smmu_v2_impl = {
.init_context = qcom_smmu_init_context,
.cfg_probe = qcom_smmu_cfg_probe,
.def_domain_type = qcom_smmu_def_domain_type,
.reset = qcom_smmu500_reset,
.reset_cb_nodisable = qcom_smmu500_reset_cb_nodisable,
.write_s2cr = qcom_smmu_write_s2cr,
.tlb_sync = qcom_smmu_tlb_sync,
};
Expand All @@ -426,6 +448,8 @@ static const struct arm_smmu_impl sdm845_smmu_500_impl = {
static const struct arm_smmu_impl qcom_adreno_smmu_v2_impl = {
.init_context = qcom_adreno_smmu_init_context,
.def_domain_type = qcom_smmu_def_domain_type,
.reset = qcom_smmu500_reset,
.reset_cb_nodisable = qcom_smmu500_reset_cb_nodisable,
.alloc_context_bank = qcom_adreno_smmu_alloc_context_bank,
.write_sctlr = qcom_adreno_smmu_write_sctlr,
.tlb_sync = qcom_smmu_tlb_sync,
Expand All @@ -446,6 +470,8 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
const struct device_node *np = smmu->dev->of_node;
const struct arm_smmu_impl *impl;
struct qcom_smmu *qsmmu;
u8 reset_nodisable_cbs[ARM_SMMU_MAX_CBS];
int i, sz;

if (!data)
return ERR_PTR(-EINVAL);
Expand All @@ -469,6 +495,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
qsmmu->smmu.impl = impl;
qsmmu->cfg = data->cfg;
qsmmu->bypass_cbndx = 0xff;
bitmap_zero(qsmmu->reset_cb_nodisable_mask, ARM_SMMU_MAX_CBS);

if (np != NULL) {
/*
Expand All @@ -477,6 +504,23 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
* - We are booting on ACPI
*/
of_property_read_u8(np, "qcom,bypass-cbndx", &qsmmu->bypass_cbndx);

/*
* Some context banks may not be disabled because they are
* secured: read from DT a list of secured contexts that cannot
* be disabled without crashing the system.
* This list is optional, as not all firmware configurations do
* require us skipping disablement of context banks.
*/
sz = of_property_read_variable_u8_array(np, "qcom,reset-nodisable-cbs",
reset_nodisable_cbs,
1, ARM_SMMU_MAX_CBS);
if (sz > 0) {
for (i = 0; i < sz; i++) {
__set_bit(reset_nodisable_cbs[i],
qsmmu->reset_cb_nodisable_mask);
}
}
}

return &qsmmu->smmu;
Expand Down
1 change: 1 addition & 0 deletions drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
struct qcom_smmu {
struct arm_smmu_device smmu;
const struct qcom_smmu_config *cfg;
DECLARE_BITMAP(reset_cb_nodisable_mask, ARM_SMMU_MAX_CBS);
bool bypass_quirk;
u8 bypass_cbndx;
u32 stall_enabled;
Expand Down

0 comments on commit 2ea4f6a

Please sign in to comment.