Unverified Commit 25b67f37 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'tee-shm-for-v5.18' of...

Merge tag 'tee-shm-for-v5.18' of git://git.linaro.org:/people/jens.wiklander/linux-tee into arm/drivers

TEE shared memory cleanup for v5.18

- The TEE shared memory pool based on two pools is replaced with a single
  somewhat more capable pool.
- Replaces tee_shm_alloc() and tee_shm_register() with new functions
  easier to use and maintain.  The TEE subsystem and the TEE drivers are
  updated to use the new functions instead.
- The TEE based Trusted keys routines are updated to use the new
  simplified functions above.
- The OP-TEE based rng driver is updated to use the new simplified
  functions above.
- The TEE_SHM-flags are refactored to better match their usage

* tag 'tee-shm-for-v5.18' of git://git.linaro.org:/people/jens.wiklander/linux-tee:
  tee: refactor TEE_SHM_* flags
  tee: replace tee_shm_register()
  KEYS: trusted: tee: use tee_shm_register_kernel_buf()
  tee: add tee_shm_register_{user,kernel}_buf()
  optee: add optee_pool_op_free_helper()
  tee: replace tee_shm_alloc()
  tee: simplify shm pool handling
  tee: add tee_shm_alloc_user_buf()
  tee: remove unused tee_shm_pool_alloc_res_mem()
  hwrng: optee-rng: use tee_shm_alloc_kernel_buf()
  optee: use driver internal tee_context for some rpc

Link: https://lore.kernel.org/r/20220218184802.GA968155@jade


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents bc5ede20 a45ea4ef
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -145,10 +145,10 @@ static int optee_rng_init(struct hwrng *rng)
	struct optee_rng_private *pvt_data = to_optee_rng_private(rng);
	struct tee_shm *entropy_shm_pool = NULL;

	entropy_shm_pool = tee_shm_alloc(pvt_data->ctx, MAX_ENTROPY_REQ_SZ,
					 TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
	entropy_shm_pool = tee_shm_alloc_kernel_buf(pvt_data->ctx,
						    MAX_ENTROPY_REQ_SZ);
	if (IS_ERR(entropy_shm_pool)) {
		dev_err(pvt_data->dev, "tee_shm_alloc failed\n");
		dev_err(pvt_data->dev, "tee_shm_alloc_kernel_buf failed\n");
		return PTR_ERR(entropy_shm_pool);
	}

+16 −39
Original line number Diff line number Diff line
@@ -8,13 +8,17 @@
#include <linux/psp-sev.h>
#include "amdtee_private.h"

static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm,
			 size_t size)
static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
			 size_t size, size_t align)
{
	unsigned int order = get_order(size);
	unsigned long va;
	int rc;

	/*
	 * Ignore alignment since this is already going to be page aligned
	 * and there's no need for any larger alignment.
	 */
	va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
	if (!va)
		return -ENOMEM;
@@ -34,7 +38,7 @@ static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm,
	return 0;
}

static void pool_op_free(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm)
static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm)
{
	/* Unmap the shared memory from TEE */
	amdtee_unmap_shmem(shm);
@@ -42,52 +46,25 @@ static void pool_op_free(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm)
	shm->kaddr = NULL;
}

static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
static void pool_op_destroy_pool(struct tee_shm_pool *pool)
{
	kfree(poolm);
	kfree(pool);
}

static const struct tee_shm_pool_mgr_ops pool_ops = {
static const struct tee_shm_pool_ops pool_ops = {
	.alloc = pool_op_alloc,
	.free = pool_op_free,
	.destroy_poolmgr = pool_op_destroy_poolmgr,
	.destroy_pool = pool_op_destroy_pool,
};

static struct tee_shm_pool_mgr *pool_mem_mgr_alloc(void)
{
	struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);

	if (!mgr)
		return ERR_PTR(-ENOMEM);

	mgr->ops = &pool_ops;

	return mgr;
}

struct tee_shm_pool *amdtee_config_shm(void)
{
	struct tee_shm_pool_mgr *priv_mgr;
	struct tee_shm_pool_mgr *dmabuf_mgr;
	void *rc;

	rc = pool_mem_mgr_alloc();
	if (IS_ERR(rc))
		return rc;
	priv_mgr = rc;
	struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);

	rc = pool_mem_mgr_alloc();
	if (IS_ERR(rc)) {
		tee_shm_pool_mgr_destroy(priv_mgr);
		return rc;
	}
	dmabuf_mgr = rc;
	if (!pool)
		return ERR_PTR(-ENOMEM);

	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
	if (IS_ERR(rc)) {
		tee_shm_pool_mgr_destroy(priv_mgr);
		tee_shm_pool_mgr_destroy(dmabuf_mgr);
	}
	pool->ops = &pool_ops;

	return rc;
	return pool;
}
+0 −8
Original line number Diff line number Diff line
@@ -7,11 +7,3 @@ config OPTEE
	help
	  This implements the OP-TEE Trusted Execution Environment (TEE)
	  driver.

config OPTEE_SHM_NUM_PRIV_PAGES
	int "Private Shared Memory Pages"
	default 1
	depends on OPTEE
	help
	  This sets the number of private shared memory pages to be
	  used by OP-TEE TEE driver.
+1 −1
Original line number Diff line number Diff line
@@ -120,7 +120,7 @@ struct tee_shm *optee_get_msg_arg(struct tee_context *ctx, size_t num_params,
	if (optee->rpc_arg_count)
		sz += OPTEE_MSG_GET_ARG_SIZE(optee->rpc_arg_count);

	shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);
	shm = tee_shm_alloc_priv_buf(ctx, sz);
	if (IS_ERR(shm))
		return shm;

+18 −4
Original line number Diff line number Diff line
@@ -18,8 +18,8 @@
#include <linux/workqueue.h>
#include "optee_private.h"

int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,
			       struct tee_shm *shm, size_t size,
int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
			       size_t size, size_t align,
			       int (*shm_register)(struct tee_context *ctx,
						   struct tee_shm *shm,
						   struct page **pages,
@@ -30,6 +30,10 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,
	struct page *page;
	int rc = 0;

	/*
	 * Ignore alignment since this is already going to be page aligned
	 * and there's no need for any larger alignment.
	 */
	page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
	if (!page)
		return -ENOMEM;
@@ -51,7 +55,6 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,
		for (i = 0; i < nr_pages; i++)
			pages[i] = page + i;

		shm->flags |= TEE_SHM_REGISTER;
		rc = shm_register(shm->ctx, shm, pages, nr_pages,
				  (unsigned long)shm->kaddr);
		kfree(pages);
@@ -62,10 +65,20 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,
	return 0;

err:
	__free_pages(page, order);
	free_pages((unsigned long)shm->kaddr, order);
	return rc;
}

void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
			       int (*shm_unregister)(struct tee_context *ctx,
						     struct tee_shm *shm))
{
	if (shm_unregister)
		shm_unregister(shm->ctx, shm);
	free_pages((unsigned long)shm->kaddr, get_order(shm->size));
	shm->kaddr = NULL;
}

static void optee_bus_scan(struct work_struct *work)
{
	WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP));
@@ -158,6 +171,7 @@ void optee_remove_common(struct optee *optee)
	optee_unregister_devices();

	optee_notif_uninit(optee);
	teedev_close_context(optee->ctx);
	/*
	 * The two devices have to be unregistered before we can free the
	 * other resources.
Loading