mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-09-13 11:07:46 +10:00
firmware: qcom: scm: take struct device as argument in SHM bridge enable
commit dc3f4e75c5
upstream.
qcom_scm_shm_bridge_enable() is used early in the SCM initialization
routine. It makes an SCM call and so expects the internal __scm pointer
in the SCM driver to be assigned. For this reason the tzmem memory pool
is allocated *after* this pointer is assigned. However, this can lead to
a crash if another consumer of the SCM API makes a call using the memory
pool between the assignment of the __scm pointer and the initialization
of the tzmem memory pool.
As qcom_scm_shm_bridge_enable() is a special case, not meant to be
called by ordinary users, pull it into the local SCM header. Make it
take struct device as argument. This is the device that will be used to
make the SCM call as opposed to the global __scm pointer. This will
allow us to move the tzmem initialization *before* the __scm assignment
in the core SCM driver.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20250630-qcom-scm-race-v2-2-fa3851c98611@linaro.org
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
617ad64abf
commit
6e7c7570ce
@ -1603,7 +1603,13 @@ bool qcom_scm_lmh_dcvsh_available(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available);
|
||||
|
||||
int qcom_scm_shm_bridge_enable(void)
|
||||
/*
|
||||
* This is only supposed to be called once by the TZMem module. It takes the
|
||||
* SCM struct device as argument and uses it to pass the call as at the time
|
||||
* the SHM Bridge is enabled, the SCM is not yet fully set up and doesn't
|
||||
* accept global user calls. Don't try to use the __scm pointer here.
|
||||
*/
|
||||
int qcom_scm_shm_bridge_enable(struct device *scm_dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -1615,11 +1621,11 @@ int qcom_scm_shm_bridge_enable(void)
|
||||
|
||||
struct qcom_scm_res res;
|
||||
|
||||
if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
|
||||
if (!__qcom_scm_is_call_available(scm_dev, QCOM_SCM_SVC_MP,
|
||||
QCOM_SCM_MP_SHM_BRIDGE_ENABLE))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = qcom_scm_call(__scm->dev, &desc, &res);
|
||||
ret = qcom_scm_call(scm_dev, &desc, &res);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -83,6 +83,7 @@ int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
|
||||
struct qcom_scm_res *res);
|
||||
|
||||
struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
|
||||
int qcom_scm_shm_bridge_enable(struct device *scm_dev);
|
||||
|
||||
#define QCOM_SCM_SVC_BOOT 0x01
|
||||
#define QCOM_SCM_BOOT_SET_ADDR 0x01
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "qcom_scm.h"
|
||||
#include "qcom_tzmem.h"
|
||||
|
||||
struct qcom_tzmem_area {
|
||||
@ -94,7 +95,7 @@ static int qcom_tzmem_init(void)
|
||||
goto notsupp;
|
||||
}
|
||||
|
||||
ret = qcom_scm_shm_bridge_enable();
|
||||
ret = qcom_scm_shm_bridge_enable(qcom_tzmem_dev);
|
||||
if (ret == -EOPNOTSUPP)
|
||||
goto notsupp;
|
||||
|
||||
|
@ -148,7 +148,6 @@ bool qcom_scm_lmh_dcvsh_available(void);
|
||||
|
||||
int qcom_scm_gpu_init_regs(u32 gpu_req);
|
||||
|
||||
int qcom_scm_shm_bridge_enable(void);
|
||||
int qcom_scm_shm_bridge_create(u64 pfn_and_ns_perm_flags,
|
||||
u64 ipfn_and_s_perm_flags, u64 size_and_flags,
|
||||
u64 ns_vmids, u64 *handle);
|
||||
|
Loading…
Reference in New Issue
Block a user