iommu/arm-smmu-qcom: Avoid disabling secured context banks
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>
This commit is contained in:
parent
67c90625b8
commit
0af29df528
1 changed files with 32 additions and 0 deletions
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/adreno-smmu-priv.h>
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
|
||||
|
|
@ -12,6 +13,7 @@
|
|||
|
||||
struct qcom_smmu {
|
||||
struct arm_smmu_device smmu;
|
||||
DECLARE_BITMAP(reset_cb_nodisable_mask, ARM_SMMU_MAX_CBS);
|
||||
bool bypass_quirk;
|
||||
u8 bypass_cbndx;
|
||||
u32 stall_enabled;
|
||||
|
|
@ -369,11 +371,20 @@ static int qcom_smmu500_reset(struct arm_smmu_device *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_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,
|
||||
};
|
||||
|
||||
|
|
@ -381,6 +392,7 @@ static const struct arm_smmu_impl qcom_adreno_smmu_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,
|
||||
};
|
||||
|
|
@ -390,6 +402,8 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
|
|||
{
|
||||
const struct device_node *np = smmu->dev->of_node;
|
||||
struct qcom_smmu *qsmmu;
|
||||
u8 reset_nodisable_cbs[ARM_SMMU_MAX_CBS];
|
||||
int i, sz;
|
||||
|
||||
/* Check to make sure qcom_scm has finished probing */
|
||||
if (!qcom_scm_is_available())
|
||||
|
|
@ -401,6 +415,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
|
|||
|
||||
qsmmu->smmu.impl = impl;
|
||||
qsmmu->bypass_cbndx = 0xff;
|
||||
bitmap_zero(qsmmu->reset_cb_nodisable_mask, ARM_SMMU_MAX_CBS);
|
||||
|
||||
if (np != NULL) {
|
||||
/*
|
||||
|
|
@ -409,6 +424,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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue