From: Bjorn Andersson <bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
To: Vivek Gautam <vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Cc: will.deacon-5wv7dgnIgG8@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
david.brown-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
andy.gross-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
swboyd-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org,
robin.murphy-5wv7dgnIgG8@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Subject: Re: [PATCH v2 1/4] firmware: qcom_scm-64: Add atomic version of qcom_scm_call
Date: Mon, 25 Mar 2019 14:09:25 -0700 [thread overview]
Message-ID: <20190325210925.GA2899@builder> (raw)
In-Reply-To: <20180910062551.28175-2-vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
On Sun 09 Sep 23:25 PDT 2018, Vivek Gautam wrote:
> There are scnenarios where drivers are required to make a
> scm call in atomic context, such as in one of the qcom's
> arm-smmu-500 errata [1].
>
> [1] ("https://source.codeaurora.org/quic/la/kernel/msm-4.9/
> tree/drivers/iommu/arm-smmu.c?h=msm-4.9#n4842")
>
> Signed-off-by: Vivek Gautam <vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Regards,
Bjorn
> ---
> drivers/firmware/qcom_scm-64.c | 136 ++++++++++++++++++++++++++++-------------
> 1 file changed, 92 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
> index 688525dd4aee..3a8c867cdf51 100644
> --- a/drivers/firmware/qcom_scm-64.c
> +++ b/drivers/firmware/qcom_scm-64.c
> @@ -70,32 +70,71 @@ static DEFINE_MUTEX(qcom_scm_lock);
> #define FIRST_EXT_ARG_IDX 3
> #define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1)
>
> -/**
> - * qcom_scm_call() - Invoke a syscall in the secure world
> - * @dev: device
> - * @svc_id: service identifier
> - * @cmd_id: command identifier
> - * @desc: Descriptor structure containing arguments and return values
> - *
> - * Sends a command to the SCM and waits for the command to finish processing.
> - * This should *only* be called in pre-emptible context.
> -*/
> -static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> - const struct qcom_scm_desc *desc,
> - struct arm_smccc_res *res)
> +static void __qcom_scm_call_do(const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res, u32 fn_id,
> + u64 x5, u32 type)
> +{
> + u64 cmd;
> + struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6};
> +
> + cmd = ARM_SMCCC_CALL_VAL(type, qcom_smccc_convention,
> + ARM_SMCCC_OWNER_SIP, fn_id);
> +
> + quirk.state.a6 = 0;
> +
> + do {
> + arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0],
> + desc->args[1], desc->args[2], x5,
> + quirk.state.a6, 0, res, &quirk);
> +
> + if (res->a0 == QCOM_SCM_INTERRUPTED)
> + cmd = res->a0;
> +
> + } while (res->a0 == QCOM_SCM_INTERRUPTED);
> +}
> +
> +static void qcom_scm_call_do(const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res, u32 fn_id,
> + u64 x5, bool atomic)
> +{
> + int retry_count = 0;
> +
> + if (!atomic) {
> + do {
> + mutex_lock(&qcom_scm_lock);
> +
> + __qcom_scm_call_do(desc, res, fn_id, x5,
> + ARM_SMCCC_STD_CALL);
> +
> + mutex_unlock(&qcom_scm_lock);
> +
> + if (res->a0 == QCOM_SCM_V2_EBUSY) {
> + if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
> + break;
> + msleep(QCOM_SCM_EBUSY_WAIT_MS);
> + }
> + } while (res->a0 == QCOM_SCM_V2_EBUSY);
> + } else {
> + __qcom_scm_call_do(desc, res, fn_id, x5, ARM_SMCCC_FAST_CALL);
> + }
> +}
> +
> +static int ___qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> + const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res, bool atomic)
> {
> int arglen = desc->arginfo & 0xf;
> - int retry_count = 0, i;
> + int i;
> u32 fn_id = QCOM_SCM_FNID(svc_id, cmd_id);
> - u64 cmd, x5 = desc->args[FIRST_EXT_ARG_IDX];
> + u64 x5 = desc->args[FIRST_EXT_ARG_IDX];
> dma_addr_t args_phys = 0;
> void *args_virt = NULL;
> size_t alloc_len;
> - struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6};
> + gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
>
> if (unlikely(arglen > N_REGISTER_ARGS)) {
> alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64);
> - args_virt = kzalloc(PAGE_ALIGN(alloc_len), GFP_KERNEL);
> + args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
>
> if (!args_virt)
> return -ENOMEM;
> @@ -125,33 +164,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> x5 = args_phys;
> }
>
> - do {
> - mutex_lock(&qcom_scm_lock);
> -
> - cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL,
> - qcom_smccc_convention,
> - ARM_SMCCC_OWNER_SIP, fn_id);
> -
> - quirk.state.a6 = 0;
> -
> - do {
> - arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0],
> - desc->args[1], desc->args[2], x5,
> - quirk.state.a6, 0, res, &quirk);
> -
> - if (res->a0 == QCOM_SCM_INTERRUPTED)
> - cmd = res->a0;
> -
> - } while (res->a0 == QCOM_SCM_INTERRUPTED);
> -
> - mutex_unlock(&qcom_scm_lock);
> -
> - if (res->a0 == QCOM_SCM_V2_EBUSY) {
> - if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
> - break;
> - msleep(QCOM_SCM_EBUSY_WAIT_MS);
> - }
> - } while (res->a0 == QCOM_SCM_V2_EBUSY);
> + qcom_scm_call_do(desc, res, fn_id, x5, atomic);
>
> if (args_virt) {
> dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
> @@ -164,6 +177,41 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> return 0;
> }
>
> +/**
> + * qcom_scm_call() - Invoke a syscall in the secure world
> + * @dev: device
> + * @svc_id: service identifier
> + * @cmd_id: command identifier
> + * @desc: Descriptor structure containing arguments and return values
> + *
> + * Sends a command to the SCM and waits for the command to finish processing.
> + * This should *only* be called in pre-emptible context.
> + */
> +static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> + const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res)
> +{
> + return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, false);
> +}
> +
> +/**
> + * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
> + * @dev: device
> + * @svc_id: service identifier
> + * @cmd_id: command identifier
> + * @desc: Descriptor structure containing arguments and return values
> + * @res: Structure containing results from SMC/HVC call
> + *
> + * Sends a command to the SCM and waits for the command to finish processing.
> + * This should be called in atomic context only.
> + */
> +static int qcom_scm_call_atomic(struct device *dev, u32 svc_id, u32 cmd_id,
> + const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res)
> +{
> + return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, true);
> +}
> +
> /**
> * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
> * @entry: Entry point function for the cpus
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>
WARNING: multiple messages have this Message-ID (diff)
From: Bjorn Andersson <bjorn.andersson@linaro.org>
To: Vivek Gautam <vivek.gautam@codeaurora.org>
Cc: robdclark@gmail.com, joro@8bytes.org, will.deacon@arm.com,
linux-kernel@vger.kernel.org, tfiga@chromium.org,
david.brown@linaro.org, iommu@lists.linux-foundation.org,
andy.gross@linaro.org, swboyd@chromium.org, robin.murphy@arm.com,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v2 1/4] firmware: qcom_scm-64: Add atomic version of qcom_scm_call
Date: Mon, 25 Mar 2019 14:09:25 -0700 [thread overview]
Message-ID: <20190325210925.GA2899@builder> (raw)
In-Reply-To: <20180910062551.28175-2-vivek.gautam@codeaurora.org>
On Sun 09 Sep 23:25 PDT 2018, Vivek Gautam wrote:
> There are scnenarios where drivers are required to make a
> scm call in atomic context, such as in one of the qcom's
> arm-smmu-500 errata [1].
>
> [1] ("https://source.codeaurora.org/quic/la/kernel/msm-4.9/
> tree/drivers/iommu/arm-smmu.c?h=msm-4.9#n4842")
>
> Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> ---
> drivers/firmware/qcom_scm-64.c | 136 ++++++++++++++++++++++++++++-------------
> 1 file changed, 92 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
> index 688525dd4aee..3a8c867cdf51 100644
> --- a/drivers/firmware/qcom_scm-64.c
> +++ b/drivers/firmware/qcom_scm-64.c
> @@ -70,32 +70,71 @@ static DEFINE_MUTEX(qcom_scm_lock);
> #define FIRST_EXT_ARG_IDX 3
> #define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1)
>
> -/**
> - * qcom_scm_call() - Invoke a syscall in the secure world
> - * @dev: device
> - * @svc_id: service identifier
> - * @cmd_id: command identifier
> - * @desc: Descriptor structure containing arguments and return values
> - *
> - * Sends a command to the SCM and waits for the command to finish processing.
> - * This should *only* be called in pre-emptible context.
> -*/
> -static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> - const struct qcom_scm_desc *desc,
> - struct arm_smccc_res *res)
> +static void __qcom_scm_call_do(const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res, u32 fn_id,
> + u64 x5, u32 type)
> +{
> + u64 cmd;
> + struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6};
> +
> + cmd = ARM_SMCCC_CALL_VAL(type, qcom_smccc_convention,
> + ARM_SMCCC_OWNER_SIP, fn_id);
> +
> + quirk.state.a6 = 0;
> +
> + do {
> + arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0],
> + desc->args[1], desc->args[2], x5,
> + quirk.state.a6, 0, res, &quirk);
> +
> + if (res->a0 == QCOM_SCM_INTERRUPTED)
> + cmd = res->a0;
> +
> + } while (res->a0 == QCOM_SCM_INTERRUPTED);
> +}
> +
> +static void qcom_scm_call_do(const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res, u32 fn_id,
> + u64 x5, bool atomic)
> +{
> + int retry_count = 0;
> +
> + if (!atomic) {
> + do {
> + mutex_lock(&qcom_scm_lock);
> +
> + __qcom_scm_call_do(desc, res, fn_id, x5,
> + ARM_SMCCC_STD_CALL);
> +
> + mutex_unlock(&qcom_scm_lock);
> +
> + if (res->a0 == QCOM_SCM_V2_EBUSY) {
> + if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
> + break;
> + msleep(QCOM_SCM_EBUSY_WAIT_MS);
> + }
> + } while (res->a0 == QCOM_SCM_V2_EBUSY);
> + } else {
> + __qcom_scm_call_do(desc, res, fn_id, x5, ARM_SMCCC_FAST_CALL);
> + }
> +}
> +
> +static int ___qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> + const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res, bool atomic)
> {
> int arglen = desc->arginfo & 0xf;
> - int retry_count = 0, i;
> + int i;
> u32 fn_id = QCOM_SCM_FNID(svc_id, cmd_id);
> - u64 cmd, x5 = desc->args[FIRST_EXT_ARG_IDX];
> + u64 x5 = desc->args[FIRST_EXT_ARG_IDX];
> dma_addr_t args_phys = 0;
> void *args_virt = NULL;
> size_t alloc_len;
> - struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6};
> + gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
>
> if (unlikely(arglen > N_REGISTER_ARGS)) {
> alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64);
> - args_virt = kzalloc(PAGE_ALIGN(alloc_len), GFP_KERNEL);
> + args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
>
> if (!args_virt)
> return -ENOMEM;
> @@ -125,33 +164,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> x5 = args_phys;
> }
>
> - do {
> - mutex_lock(&qcom_scm_lock);
> -
> - cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL,
> - qcom_smccc_convention,
> - ARM_SMCCC_OWNER_SIP, fn_id);
> -
> - quirk.state.a6 = 0;
> -
> - do {
> - arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0],
> - desc->args[1], desc->args[2], x5,
> - quirk.state.a6, 0, res, &quirk);
> -
> - if (res->a0 == QCOM_SCM_INTERRUPTED)
> - cmd = res->a0;
> -
> - } while (res->a0 == QCOM_SCM_INTERRUPTED);
> -
> - mutex_unlock(&qcom_scm_lock);
> -
> - if (res->a0 == QCOM_SCM_V2_EBUSY) {
> - if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
> - break;
> - msleep(QCOM_SCM_EBUSY_WAIT_MS);
> - }
> - } while (res->a0 == QCOM_SCM_V2_EBUSY);
> + qcom_scm_call_do(desc, res, fn_id, x5, atomic);
>
> if (args_virt) {
> dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
> @@ -164,6 +177,41 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> return 0;
> }
>
> +/**
> + * qcom_scm_call() - Invoke a syscall in the secure world
> + * @dev: device
> + * @svc_id: service identifier
> + * @cmd_id: command identifier
> + * @desc: Descriptor structure containing arguments and return values
> + *
> + * Sends a command to the SCM and waits for the command to finish processing.
> + * This should *only* be called in pre-emptible context.
> + */
> +static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> + const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res)
> +{
> + return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, false);
> +}
> +
> +/**
> + * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
> + * @dev: device
> + * @svc_id: service identifier
> + * @cmd_id: command identifier
> + * @desc: Descriptor structure containing arguments and return values
> + * @res: Structure containing results from SMC/HVC call
> + *
> + * Sends a command to the SCM and waits for the command to finish processing.
> + * This should be called in atomic context only.
> + */
> +static int qcom_scm_call_atomic(struct device *dev, u32 svc_id, u32 cmd_id,
> + const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res)
> +{
> + return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, true);
> +}
> +
> /**
> * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
> * @entry: Entry point function for the cpus
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: Bjorn Andersson <bjorn.andersson@linaro.org>
To: Vivek Gautam <vivek.gautam@codeaurora.org>
Cc: joro@8bytes.org, andy.gross@linaro.org, will.deacon@arm.com,
robin.murphy@arm.com, iommu@lists.linux-foundation.org,
linux-arm-kernel@lists.infradead.org, david.brown@linaro.org,
tfiga@chromium.org, swboyd@chromium.org,
linux-kernel@vger.kernel.org, robdclark@gmail.com
Subject: Re: [PATCH v2 1/4] firmware: qcom_scm-64: Add atomic version of qcom_scm_call
Date: Mon, 25 Mar 2019 14:09:25 -0700 [thread overview]
Message-ID: <20190325210925.GA2899@builder> (raw)
In-Reply-To: <20180910062551.28175-2-vivek.gautam@codeaurora.org>
On Sun 09 Sep 23:25 PDT 2018, Vivek Gautam wrote:
> There are scnenarios where drivers are required to make a
> scm call in atomic context, such as in one of the qcom's
> arm-smmu-500 errata [1].
>
> [1] ("https://source.codeaurora.org/quic/la/kernel/msm-4.9/
> tree/drivers/iommu/arm-smmu.c?h=msm-4.9#n4842")
>
> Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> ---
> drivers/firmware/qcom_scm-64.c | 136 ++++++++++++++++++++++++++++-------------
> 1 file changed, 92 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
> index 688525dd4aee..3a8c867cdf51 100644
> --- a/drivers/firmware/qcom_scm-64.c
> +++ b/drivers/firmware/qcom_scm-64.c
> @@ -70,32 +70,71 @@ static DEFINE_MUTEX(qcom_scm_lock);
> #define FIRST_EXT_ARG_IDX 3
> #define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1)
>
> -/**
> - * qcom_scm_call() - Invoke a syscall in the secure world
> - * @dev: device
> - * @svc_id: service identifier
> - * @cmd_id: command identifier
> - * @desc: Descriptor structure containing arguments and return values
> - *
> - * Sends a command to the SCM and waits for the command to finish processing.
> - * This should *only* be called in pre-emptible context.
> -*/
> -static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> - const struct qcom_scm_desc *desc,
> - struct arm_smccc_res *res)
> +static void __qcom_scm_call_do(const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res, u32 fn_id,
> + u64 x5, u32 type)
> +{
> + u64 cmd;
> + struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6};
> +
> + cmd = ARM_SMCCC_CALL_VAL(type, qcom_smccc_convention,
> + ARM_SMCCC_OWNER_SIP, fn_id);
> +
> + quirk.state.a6 = 0;
> +
> + do {
> + arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0],
> + desc->args[1], desc->args[2], x5,
> + quirk.state.a6, 0, res, &quirk);
> +
> + if (res->a0 == QCOM_SCM_INTERRUPTED)
> + cmd = res->a0;
> +
> + } while (res->a0 == QCOM_SCM_INTERRUPTED);
> +}
> +
> +static void qcom_scm_call_do(const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res, u32 fn_id,
> + u64 x5, bool atomic)
> +{
> + int retry_count = 0;
> +
> + if (!atomic) {
> + do {
> + mutex_lock(&qcom_scm_lock);
> +
> + __qcom_scm_call_do(desc, res, fn_id, x5,
> + ARM_SMCCC_STD_CALL);
> +
> + mutex_unlock(&qcom_scm_lock);
> +
> + if (res->a0 == QCOM_SCM_V2_EBUSY) {
> + if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
> + break;
> + msleep(QCOM_SCM_EBUSY_WAIT_MS);
> + }
> + } while (res->a0 == QCOM_SCM_V2_EBUSY);
> + } else {
> + __qcom_scm_call_do(desc, res, fn_id, x5, ARM_SMCCC_FAST_CALL);
> + }
> +}
> +
> +static int ___qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> + const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res, bool atomic)
> {
> int arglen = desc->arginfo & 0xf;
> - int retry_count = 0, i;
> + int i;
> u32 fn_id = QCOM_SCM_FNID(svc_id, cmd_id);
> - u64 cmd, x5 = desc->args[FIRST_EXT_ARG_IDX];
> + u64 x5 = desc->args[FIRST_EXT_ARG_IDX];
> dma_addr_t args_phys = 0;
> void *args_virt = NULL;
> size_t alloc_len;
> - struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6};
> + gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
>
> if (unlikely(arglen > N_REGISTER_ARGS)) {
> alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64);
> - args_virt = kzalloc(PAGE_ALIGN(alloc_len), GFP_KERNEL);
> + args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
>
> if (!args_virt)
> return -ENOMEM;
> @@ -125,33 +164,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> x5 = args_phys;
> }
>
> - do {
> - mutex_lock(&qcom_scm_lock);
> -
> - cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL,
> - qcom_smccc_convention,
> - ARM_SMCCC_OWNER_SIP, fn_id);
> -
> - quirk.state.a6 = 0;
> -
> - do {
> - arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0],
> - desc->args[1], desc->args[2], x5,
> - quirk.state.a6, 0, res, &quirk);
> -
> - if (res->a0 == QCOM_SCM_INTERRUPTED)
> - cmd = res->a0;
> -
> - } while (res->a0 == QCOM_SCM_INTERRUPTED);
> -
> - mutex_unlock(&qcom_scm_lock);
> -
> - if (res->a0 == QCOM_SCM_V2_EBUSY) {
> - if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
> - break;
> - msleep(QCOM_SCM_EBUSY_WAIT_MS);
> - }
> - } while (res->a0 == QCOM_SCM_V2_EBUSY);
> + qcom_scm_call_do(desc, res, fn_id, x5, atomic);
>
> if (args_virt) {
> dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
> @@ -164,6 +177,41 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> return 0;
> }
>
> +/**
> + * qcom_scm_call() - Invoke a syscall in the secure world
> + * @dev: device
> + * @svc_id: service identifier
> + * @cmd_id: command identifier
> + * @desc: Descriptor structure containing arguments and return values
> + *
> + * Sends a command to the SCM and waits for the command to finish processing.
> + * This should *only* be called in pre-emptible context.
> + */
> +static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> + const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res)
> +{
> + return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, false);
> +}
> +
> +/**
> + * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
> + * @dev: device
> + * @svc_id: service identifier
> + * @cmd_id: command identifier
> + * @desc: Descriptor structure containing arguments and return values
> + * @res: Structure containing results from SMC/HVC call
> + *
> + * Sends a command to the SCM and waits for the command to finish processing.
> + * This should be called in atomic context only.
> + */
> +static int qcom_scm_call_atomic(struct device *dev, u32 svc_id, u32 cmd_id,
> + const struct qcom_scm_desc *desc,
> + struct arm_smccc_res *res)
> +{
> + return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, true);
> +}
> +
> /**
> * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
> * @entry: Entry point function for the cpus
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>
next prev parent reply other threads:[~2019-03-25 21:09 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-10 6:25 [PATCH v2 0/4] Qcom smmu-500 TLB invalidation errata for sdm845 Vivek Gautam
2018-09-10 6:25 ` Vivek Gautam
[not found] ` <20180910062551.28175-1-vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-09-10 6:25 ` [PATCH v2 1/4] firmware: qcom_scm-64: Add atomic version of qcom_scm_call Vivek Gautam
2018-09-10 6:25 ` Vivek Gautam
2018-09-10 6:25 ` Vivek Gautam
[not found] ` <20180910062551.28175-2-vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2019-03-25 21:09 ` Bjorn Andersson [this message]
2019-03-25 21:09 ` Bjorn Andersson
2019-03-25 21:09 ` Bjorn Andersson
2019-03-26 8:02 ` Vivek Gautam
2019-03-26 8:02 ` Vivek Gautam
2019-03-26 8:02 ` Vivek Gautam
2018-09-10 6:25 ` [PATCH v2 2/4] firmware/qcom_scm: Add atomic version of io read/write APIs Vivek Gautam
2018-09-10 6:25 ` Vivek Gautam
2018-09-10 6:25 ` Vivek Gautam
2019-03-25 21:09 ` Bjorn Andersson
2019-03-25 21:09 ` Bjorn Andersson
2018-09-10 6:25 ` [PATCH v2 4/4] iommu/arm-smmu: Add support to handle Qcom's TLBI serialization errata Vivek Gautam
2018-09-10 6:25 ` Vivek Gautam
2018-09-10 6:25 ` Vivek Gautam
2018-09-25 12:31 ` Robin Murphy
2018-09-25 12:31 ` Robin Murphy
[not found] ` <29fd7e9e-708b-b884-4de1-ecc141f41692-5wv7dgnIgG8@public.gmane.org>
2018-10-23 7:45 ` Vivek Gautam
2018-10-23 7:45 ` Vivek Gautam
2018-10-23 7:45 ` Vivek Gautam
2019-03-25 21:16 ` Bjorn Andersson
2019-03-25 21:16 ` Bjorn Andersson
2018-09-10 10:38 ` [PATCH v2 0/4] Qcom smmu-500 TLB invalidation errata for sdm845 Vivek Gautam
2018-09-10 10:38 ` Vivek Gautam
2018-09-10 10:38 ` Vivek Gautam
2018-09-25 5:58 ` Vivek Gautam
2018-09-25 5:58 ` Vivek Gautam
2018-09-25 5:58 ` Vivek Gautam
2018-09-10 6:25 ` [PATCH v2 3/4] firmware/qcom_scm: Add scm call to handle smmu errata Vivek Gautam
2018-09-10 6:25 ` Vivek Gautam
[not found] ` <20180910062551.28175-4-vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2019-03-25 21:10 ` Bjorn Andersson
2019-03-25 21:10 ` Bjorn Andersson
2019-03-25 21:10 ` Bjorn Andersson
2018-09-25 12:09 ` [PATCH v2 0/4] Qcom smmu-500 TLB invalidation errata for sdm845 Joerg Roedel
2018-09-25 12:09 ` Joerg Roedel
2018-09-25 16:39 ` Will Deacon
2018-09-25 16:39 ` Will Deacon
2018-09-26 6:23 ` Vivek Gautam
2018-09-26 6:23 ` Vivek Gautam
2018-09-26 6:23 ` Vivek Gautam
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190325210925.GA2899@builder \
--to=bjorn.andersson-qsej5fyqhm4dnm+yrofe0a@public.gmane.org \
--cc=andy.gross-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=david.brown-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=robin.murphy-5wv7dgnIgG8@public.gmane.org \
--cc=swboyd-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
--cc=vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=will.deacon-5wv7dgnIgG8@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.