linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rijo Thomas <Rijo-john.Thomas@amd.com>
To: Jens Wiklander <jens.wiklander@linaro.org>,
	Dan Carpenter <dan.carpenter@oracle.com>
Cc: Devaraj Rangasamy <Devaraj.Rangasamy@amd.com>,
	Mythri Pandeshwara krishna <mythri.pandeshwarakrishna@amd.com>,
	op-tee@lists.trustedfirmware.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3] tee: amdtee: unload TA only when its refcount becomes 0
Date: Mon, 3 May 2021 09:04:35 +0530	[thread overview]
Message-ID: <5072c20c-7912-4307-6e04-caa1fe54bf1a@amd.com> (raw)
In-Reply-To: <5057c53afb568fa70234de2f23b0ffeff75af426.1618421014.git.Rijo-john.Thomas@amd.com>



On 14/04/21 11:08 pm, Rijo Thomas wrote:
> Same Trusted Application (TA) can be loaded in multiple TEE contexts.
> 
> If it is a single instance TA, the TA should not get unloaded from AMD
> Secure Processor, while it is still in use in another TEE context.
> 
> Therefore reference count TA and unload it when the count becomes zero.
> 
> Fixes: 757cc3e9ff1d ("tee: add AMD-TEE driver")
> Reviewed-by: Devaraj Rangasamy <Devaraj.Rangasamy@amd.com>
> Signed-off-by: Rijo Thomas <Rijo-john.Thomas@amd.com>

Hi Dan,

Can you please give an Ack if you are okay with this patch.
I have incorporated your review comments for v2.

Thanks,
Rijo

> ---
> v3:
>  * Updated structure initialization list from {0} to preferred
>    style {}
> 
> v2:
>  * Unload TA if get_ta_refcount() fails
> 
>  drivers/tee/amdtee/amdtee_private.h | 13 ++++
>  drivers/tee/amdtee/call.c           | 94 ++++++++++++++++++++++++++---
>  drivers/tee/amdtee/core.c           | 15 +++--
>  3 files changed, 106 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/tee/amdtee/amdtee_private.h b/drivers/tee/amdtee/amdtee_private.h
> index 337c8d82f74e..6d0f7062bb87 100644
> --- a/drivers/tee/amdtee/amdtee_private.h
> +++ b/drivers/tee/amdtee/amdtee_private.h
> @@ -21,6 +21,7 @@
>  #define TEEC_SUCCESS			0x00000000
>  #define TEEC_ERROR_GENERIC		0xFFFF0000
>  #define TEEC_ERROR_BAD_PARAMETERS	0xFFFF0006
> +#define TEEC_ERROR_OUT_OF_MEMORY	0xFFFF000C
>  #define TEEC_ERROR_COMMUNICATION	0xFFFF000E
> 
>  #define TEEC_ORIGIN_COMMS		0x00000002
> @@ -93,6 +94,18 @@ struct amdtee_shm_data {
>  	u32     buf_id;
>  };
> 
> +/**
> + * struct amdtee_ta_data - Keeps track of all TAs loaded in AMD Secure
> + *			   Processor
> + * @ta_handle:	Handle to TA loaded in TEE
> + * @refcount:	Reference count for the loaded TA
> + */
> +struct amdtee_ta_data {
> +	struct list_head list_node;
> +	u32 ta_handle;
> +	u32 refcount;
> +};
> +
>  #define LOWER_TWO_BYTE_MASK	0x0000FFFF
> 
>  /**
> diff --git a/drivers/tee/amdtee/call.c b/drivers/tee/amdtee/call.c
> index 096dd4d92d39..07f36ac834c8 100644
> --- a/drivers/tee/amdtee/call.c
> +++ b/drivers/tee/amdtee/call.c
> @@ -121,15 +121,69 @@ static int amd_params_to_tee_params(struct tee_param *tee, u32 count,
>  	return ret;
>  }
> 
> +static DEFINE_MUTEX(ta_refcount_mutex);
> +static struct list_head ta_list = LIST_HEAD_INIT(ta_list);
> +
> +static u32 get_ta_refcount(u32 ta_handle)
> +{
> +	struct amdtee_ta_data *ta_data;
> +	u32 count = 0;
> +
> +	/* Caller must hold a mutex */
> +	list_for_each_entry(ta_data, &ta_list, list_node)
> +		if (ta_data->ta_handle == ta_handle)
> +			return ++ta_data->refcount;
> +
> +	ta_data = kzalloc(sizeof(*ta_data), GFP_KERNEL);
> +	if (ta_data) {
> +		ta_data->ta_handle = ta_handle;
> +		ta_data->refcount = 1;
> +		count = ta_data->refcount;
> +		list_add(&ta_data->list_node, &ta_list);
> +	}
> +
> +	return count;
> +}
> +
> +static u32 put_ta_refcount(u32 ta_handle)
> +{
> +	struct amdtee_ta_data *ta_data;
> +	u32 count = 0;
> +
> +	/* Caller must hold a mutex */
> +	list_for_each_entry(ta_data, &ta_list, list_node)
> +		if (ta_data->ta_handle == ta_handle) {
> +			count = --ta_data->refcount;
> +			if (count == 0) {
> +				list_del(&ta_data->list_node);
> +				kfree(ta_data);
> +				break;
> +			}
> +		}
> +
> +	return count;
> +}
> +
>  int handle_unload_ta(u32 ta_handle)
>  {
>  	struct tee_cmd_unload_ta cmd = {0};
> -	u32 status;
> +	u32 status, count;
>  	int ret;
> 
>  	if (!ta_handle)
>  		return -EINVAL;
> 
> +	mutex_lock(&ta_refcount_mutex);
> +
> +	count = put_ta_refcount(ta_handle);
> +
> +	if (count) {
> +		pr_debug("unload ta: not unloading %u count %u\n",
> +			 ta_handle, count);
> +		ret = -EBUSY;
> +		goto unlock;
> +	}
> +
>  	cmd.ta_handle = ta_handle;
> 
>  	ret = psp_tee_process_cmd(TEE_CMD_ID_UNLOAD_TA, (void *)&cmd,
> @@ -137,8 +191,12 @@ int handle_unload_ta(u32 ta_handle)
>  	if (!ret && status != 0) {
>  		pr_err("unload ta: status = 0x%x\n", status);
>  		ret = -EBUSY;
> +	} else {
> +		pr_debug("unloaded ta handle %u\n", ta_handle);
>  	}
> 
> +unlock:
> +	mutex_unlock(&ta_refcount_mutex);
>  	return ret;
>  }
> 
> @@ -340,7 +398,8 @@ int handle_open_session(struct tee_ioctl_open_session_arg *arg, u32 *info,
> 
>  int handle_load_ta(void *data, u32 size, struct tee_ioctl_open_session_arg *arg)
>  {
> -	struct tee_cmd_load_ta cmd = {0};
> +	struct tee_cmd_unload_ta unload_cmd = {};
> +	struct tee_cmd_load_ta load_cmd = {};
>  	phys_addr_t blob;
>  	int ret;
> 
> @@ -353,21 +412,36 @@ int handle_load_ta(void *data, u32 size, struct tee_ioctl_open_session_arg *arg)
>  		return -EINVAL;
>  	}
> 
> -	cmd.hi_addr = upper_32_bits(blob);
> -	cmd.low_addr = lower_32_bits(blob);
> -	cmd.size = size;
> +	load_cmd.hi_addr = upper_32_bits(blob);
> +	load_cmd.low_addr = lower_32_bits(blob);
> +	load_cmd.size = size;
> 
> -	ret = psp_tee_process_cmd(TEE_CMD_ID_LOAD_TA, (void *)&cmd,
> -				  sizeof(cmd), &arg->ret);
> +	mutex_lock(&ta_refcount_mutex);
> +
> +	ret = psp_tee_process_cmd(TEE_CMD_ID_LOAD_TA, (void *)&load_cmd,
> +				  sizeof(load_cmd), &arg->ret);
>  	if (ret) {
>  		arg->ret_origin = TEEC_ORIGIN_COMMS;
>  		arg->ret = TEEC_ERROR_COMMUNICATION;
> -	} else {
> -		set_session_id(cmd.ta_handle, 0, &arg->session);
> +	} else if (arg->ret == TEEC_SUCCESS) {
> +		ret = get_ta_refcount(load_cmd.ta_handle);
> +		if (!ret) {
> +			arg->ret_origin = TEEC_ORIGIN_COMMS;
> +			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
> +
> +			/* Unload the TA on error */
> +			unload_cmd.ta_handle = load_cmd.ta_handle;
> +			psp_tee_process_cmd(TEE_CMD_ID_UNLOAD_TA,
> +					    (void *)&unload_cmd,
> +					    sizeof(unload_cmd), &ret);
> +		} else {
> +			set_session_id(load_cmd.ta_handle, 0, &arg->session);
> +		}
>  	}
> +	mutex_unlock(&ta_refcount_mutex);
> 
>  	pr_debug("load TA: TA handle = 0x%x, RO = 0x%x, ret = 0x%x\n",
> -		 cmd.ta_handle, arg->ret_origin, arg->ret);
> +		 load_cmd.ta_handle, arg->ret_origin, arg->ret);
> 
>  	return 0;
>  }
> diff --git a/drivers/tee/amdtee/core.c b/drivers/tee/amdtee/core.c
> index 8a6a8f30bb42..da6b88e80dc0 100644
> --- a/drivers/tee/amdtee/core.c
> +++ b/drivers/tee/amdtee/core.c
> @@ -59,10 +59,9 @@ static void release_session(struct amdtee_session *sess)
>  			continue;
> 
>  		handle_close_session(sess->ta_handle, sess->session_info[i]);
> +		handle_unload_ta(sess->ta_handle);
>  	}
> 
> -	/* Unload Trusted Application once all sessions are closed */
> -	handle_unload_ta(sess->ta_handle);
>  	kfree(sess);
>  }
> 
> @@ -224,8 +223,6 @@ static void destroy_session(struct kref *ref)
>  	struct amdtee_session *sess = container_of(ref, struct amdtee_session,
>  						   refcount);
> 
> -	/* Unload the TA from TEE */
> -	handle_unload_ta(sess->ta_handle);
>  	mutex_lock(&session_list_mutex);
>  	list_del(&sess->list_node);
>  	mutex_unlock(&session_list_mutex);
> @@ -238,7 +235,7 @@ int amdtee_open_session(struct tee_context *ctx,
>  {
>  	struct amdtee_context_data *ctxdata = ctx->data;
>  	struct amdtee_session *sess = NULL;
> -	u32 session_info;
> +	u32 session_info, ta_handle;
>  	size_t ta_size;
>  	int rc, i;
>  	void *ta;
> @@ -259,11 +256,14 @@ int amdtee_open_session(struct tee_context *ctx,
>  	if (arg->ret != TEEC_SUCCESS)
>  		goto out;
> 
> +	ta_handle = get_ta_handle(arg->session);
> +
>  	mutex_lock(&session_list_mutex);
>  	sess = alloc_session(ctxdata, arg->session);
>  	mutex_unlock(&session_list_mutex);
> 
>  	if (!sess) {
> +		handle_unload_ta(ta_handle);
>  		rc = -ENOMEM;
>  		goto out;
>  	}
> @@ -277,6 +277,7 @@ int amdtee_open_session(struct tee_context *ctx,
> 
>  	if (i >= TEE_NUM_SESSIONS) {
>  		pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
> +		handle_unload_ta(ta_handle);
>  		kref_put(&sess->refcount, destroy_session);
>  		rc = -ENOMEM;
>  		goto out;
> @@ -289,12 +290,13 @@ int amdtee_open_session(struct tee_context *ctx,
>  		spin_lock(&sess->lock);
>  		clear_bit(i, sess->sess_mask);
>  		spin_unlock(&sess->lock);
> +		handle_unload_ta(ta_handle);
>  		kref_put(&sess->refcount, destroy_session);
>  		goto out;
>  	}
> 
>  	sess->session_info[i] = session_info;
> -	set_session_id(sess->ta_handle, i, &arg->session);
> +	set_session_id(ta_handle, i, &arg->session);
>  out:
>  	free_pages((u64)ta, get_order(ta_size));
>  	return rc;
> @@ -329,6 +331,7 @@ int amdtee_close_session(struct tee_context *ctx, u32 session)
> 
>  	/* Close the session */
>  	handle_close_session(ta_handle, session_info);
> +	handle_unload_ta(ta_handle);
> 
>  	kref_put(&sess->refcount, destroy_session);
> 
> --
> 2.17.1
> 

  reply	other threads:[~2021-05-03  3:36 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-14 17:38 [PATCH v3] tee: amdtee: unload TA only when its refcount becomes 0 Rijo Thomas
2021-05-03  3:34 ` Rijo Thomas [this message]
2021-05-03 11:47   ` Dan Carpenter
2021-05-04  4:26     ` Rijo Thomas
2021-05-05 11:09       ` Jens Wiklander

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=5072c20c-7912-4307-6e04-caa1fe54bf1a@amd.com \
    --to=rijo-john.thomas@amd.com \
    --cc=Devaraj.Rangasamy@amd.com \
    --cc=dan.carpenter@oracle.com \
    --cc=jens.wiklander@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mythri.pandeshwarakrishna@amd.com \
    --cc=op-tee@lists.trustedfirmware.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).