All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Boyd <swboyd@chromium.org>
To: Vivek Gautam <vivek.gautam@codeaurora.org>,
	agross@kernel.org, iommu@lists.linux-foundation.org,
	joro@8bytes.org, robin.murphy@arm.com, will.deacon@arm.com
Cc: bjorn.andersson@linaro.org, linux-arm-msm@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Vivek Gautam <vivek.gautam@codeaurora.org>
Subject: Re: [PATCH v4 1/3] firmware: qcom_scm-64: Add atomic version of qcom_scm_call
Date: Fri, 06 Sep 2019 08:12:47 -0700	[thread overview]
Message-ID: <5d727770.1c69fb81.c9062.ce60@mx.google.com> (raw)
In-Reply-To: <20190823063248.13295-2-vivek.gautam@codeaurora.org>

Quoting Vivek Gautam (2019-08-22 23:32:46)
> 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>
> ---
>  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 91d5ad7cf58b..b6dca32c5ac4 100644
> --- a/drivers/firmware/qcom_scm-64.c
> +++ b/drivers/firmware/qcom_scm-64.c
> @@ -62,32 +62,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};

Nitpick: Put spaces around braces please.

> +
> +       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);
> +       }

To save on some indentation maybe you could write it like:

	if (atomic) {
		__qcom_scm_call_do(..)
		return;
	}

	do {
		mutex_lock(..)
		...
	} while (..);

> +}
> +
> +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;
> @@ -156,6 +169,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.

Add a might_sleep() then?

> + */
> +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.
 
Maybe add a cant_sleep()?

> + */
> +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);
> +}
> +

WARNING: multiple messages have this Message-ID (diff)
From: Stephen Boyd <swboyd@chromium.org>
To: Vivek Gautam <vivek.gautam@codeaurora.org>,
	agross@kernel.org, iommu@lists.linux-foundation.org,
	joro@8bytes.org, robin.murphy@arm.com, will.deacon@arm.com
Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
	bjorn.andersson@linaro.org
Subject: Re: [PATCH v4 1/3] firmware: qcom_scm-64: Add atomic version of qcom_scm_call
Date: Fri, 06 Sep 2019 08:12:47 -0700	[thread overview]
Message-ID: <5d727770.1c69fb81.c9062.ce60@mx.google.com> (raw)
In-Reply-To: <20190823063248.13295-2-vivek.gautam@codeaurora.org>

Quoting Vivek Gautam (2019-08-22 23:32:46)
> 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>
> ---
>  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 91d5ad7cf58b..b6dca32c5ac4 100644
> --- a/drivers/firmware/qcom_scm-64.c
> +++ b/drivers/firmware/qcom_scm-64.c
> @@ -62,32 +62,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};

Nitpick: Put spaces around braces please.

> +
> +       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);
> +       }

To save on some indentation maybe you could write it like:

	if (atomic) {
		__qcom_scm_call_do(..)
		return;
	}

	do {
		mutex_lock(..)
		...
	} while (..);

> +}
> +
> +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;
> @@ -156,6 +169,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.

Add a might_sleep() then?

> + */
> +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.
 
Maybe add a cant_sleep()?

> + */
> +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);
> +}
> +
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

  reply	other threads:[~2019-09-06 15:12 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-23  6:32 [PATCH v4 0/3] Qcom smmu-500 wait-for-safe handling for sdm845 Vivek Gautam
2019-08-23  6:32 ` Vivek Gautam
2019-08-23  6:32 ` [PATCH v4 1/3] firmware: qcom_scm-64: Add atomic version of qcom_scm_call Vivek Gautam
2019-08-23  6:32   ` Vivek Gautam
2019-09-06 15:12   ` Stephen Boyd [this message]
2019-09-06 15:12     ` Stephen Boyd
2019-09-16  9:48     ` Sai Prakash Ranjan
2019-09-16  9:48       ` Sai Prakash Ranjan
2019-08-23  6:32 ` [PATCH v4 2/3] firmware/qcom_scm: Add scm call to handle smmu errata Vivek Gautam
2019-08-23  6:32   ` Vivek Gautam
2019-08-23  6:32 ` [PATCH v4 3/3] iommu: arm-smmu-impl: Add sdm845 implementation hook Vivek Gautam
2019-08-23  6:32   ` Vivek Gautam
2019-09-06  6:32   ` Vivek Gautam
2019-09-06  6:32     ` Vivek Gautam
2019-09-06 15:07   ` Stephen Boyd
2019-09-06 15:07     ` Stephen Boyd
2019-09-16  9:47     ` Sai Prakash Ranjan
2019-09-16  9:47       ` Sai Prakash Ranjan
2019-09-10 13:26   ` Robin Murphy
2019-09-10 13:26     ` Robin Murphy
2019-09-16  9:46     ` Sai Prakash Ranjan
2019-09-16  9:46       ` Sai Prakash Ranjan

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=5d727770.1c69fb81.c9062.ce60@mx.google.com \
    --to=swboyd@chromium.org \
    --cc=agross@kernel.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=iommu@lists.linux-foundation.org \
    --cc=joro@8bytes.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=vivek.gautam@codeaurora.org \
    --cc=will.deacon@arm.com \
    /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.