Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp668485pxb; Fri, 14 Jan 2022 13:36:35 -0800 (PST) X-Google-Smtp-Source: ABdhPJyaUzRFHVTBc+LxwrhGwR0ARhlRp48weHQXDIOf9QEXBwnK+xtYATHeFIWxdiScyr+Vl3aY X-Received: by 2002:a63:7c03:: with SMTP id x3mr9485942pgc.433.1642196195689; Fri, 14 Jan 2022 13:36:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642196195; cv=none; d=google.com; s=arc-20160816; b=CKFm9XxP4Xyjo5I/X/yg6DA8e3qo64Adjvxr8vQI4OCCGZbXnJjqZ/Cp4Rc7G3o8el k8/HRA1CwOow4NywRjZ/1AV/BNe9lt370c62nuAUbA+PeOsASGnBm2me4tDC+oYH6Y2d so1LwRG7ZbBDHN7It/rkCqj7YxuQub3UlKOk1okMDEYEiRzq3VQWyiC633D12pKVtTGv hoX+kZY8NCAevjBvpIFA3wsTrd/vEJYDF6iBnnzh1mRHQdHypiA03C5pSHkYQqQkSp2W askxNJZd0hWubn+pXQOhw/9/lLNY4L3HPHCYmZaBkMu3GB4t/elw51rNfAMtKAkxdRZ2 wSHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=95djvJwQmGN4QP2pKlfIXqtuuD+v4MbXGaa6QJVPkOg=; b=IB5NBdeTxHQ5uzGWk0qOO7WMIsOMKtmzROtrg4ePfUkXQ8+GynD/yC3UWSCPyj5tAV Afm8n1qm0eYTM/I/URyOvCHvfRrxNco+DvwwH3pmNk9asomHpt5BFRyEKh5VeX7Sotja f7ndFZxc8cULj6S6y4dFQJf+ADPqD+z1Hn4RQTK9+0lOY17JkxCLJOQUqoHbpLDsf9aP uve3hWXZzrxaK4MR2O8EX0fLKqcq+W+1ubfpZf0/z8M4AymfqntRHreJSrayni17EcE6 /6abaWQdf0ggXylGDPhy/PYMEd0QC+ec0pRyT+bZDmyByxmaDNQGPrwNt8A7P46F8K+Q K+RA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=PwfcN+GB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f19si7270132pgb.657.2022.01.14.13.36.23; Fri, 14 Jan 2022 13:36:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=PwfcN+GB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242326AbiANPIz (ORCPT + 99 others); Fri, 14 Jan 2022 10:08:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59722 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242233AbiANPIp (ORCPT ); Fri, 14 Jan 2022 10:08:45 -0500 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 43C9EC061574 for ; Fri, 14 Jan 2022 07:08:45 -0800 (PST) Received: by mail-lf1-x12a.google.com with SMTP id br17so31190855lfb.6 for ; Fri, 14 Jan 2022 07:08:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=95djvJwQmGN4QP2pKlfIXqtuuD+v4MbXGaa6QJVPkOg=; b=PwfcN+GB6v/mufTrOZZHi9IDIgA29oDnM3ZvRe6LV0DQCroGsD4pdVj2JcF2Kyj/PN gberymRqwa8ROmxpqPp25y8l5lLne85HQLIm1L1cDSXRerdvOZLTkTmmHpsEDo8EXIVm 3fckkFsznm/dBM/mjpC8WrynHqD7/DzM1Y3GWFDCc2aF0rEiTsTnRvCdUYvLxbWepzRi ae2U33+EszRfpcWstp8q1wudDeor7slb51dT0P/MwQH+yxN2ZLOXLykkdPMJw3YTro10 0ouf/BeK6vUXm0y9GQ8KbSGHeFUwixfYfat3ywqFNHt/7r9aR/XvNyPO01WLiu482q8Y +cuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=95djvJwQmGN4QP2pKlfIXqtuuD+v4MbXGaa6QJVPkOg=; b=WNriKC3VvPfECAxpa7c3uHdL9Y1dBp6nAtWuAyM8aX5njb6SQ+8hGhYwFfc8zHvX5N wUhydB6ABomOFbqz+sDHjZ+7xmjn/7yATAApsRKx/K5bfBJXyBdePZww4Q5MiNaUfRcv T6CppmInYkXP0V9IYS1nIDx1NA8I2SA4r4oF+sUcdWOk493n+/SeD0OkSiFPT2tPy2C8 UUgnQOhhcs2m1JKJPnOPFoF18EIfHs8/I0SsXbUEzKmLxLQBlnXhpzUQ1P2+OcbWYEyy 8j9JPi6rFA+nf/LoczoYE0Po68KcKBT3CFrlkqFkdYmjVqxdvRJAUZmp6rb1NZ3cUL7q xd5A== X-Gm-Message-State: AOAM531WTXdlQZqcrgL/CI+RXGQ2OaGt+lV9n/ADWSsygn7ADjcY9CnF 4TfUsi6qwykkwureB+Weiq3gPHXQXNBx1g== X-Received: by 2002:a2e:a782:: with SMTP id c2mr6513423ljf.143.1642172923374; Fri, 14 Jan 2022 07:08:43 -0800 (PST) Received: from jade.urgonet (h-94-254-48-165.A175.priv.bahnhof.se. [94.254.48.165]) by smtp.gmail.com with ESMTPSA id i31sm40517lfv.67.2022.01.14.07.08.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 07:08:42 -0800 (PST) From: Jens Wiklander To: linux-kernel@vger.kernel.org, op-tee@lists.trustedfirmware.org Cc: Sumit Garg , Herbert Xu , Devaraj Rangasamy , Rijo Thomas , David Howells , Tyler Hicks , Jens Wiklander Subject: [PATCH v2 05/12] tee: replace tee_shm_alloc() Date: Fri, 14 Jan 2022 16:08:17 +0100 Message-Id: <20220114150824.3578829-6-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220114150824.3578829-1-jens.wiklander@linaro.org> References: <20220114150824.3578829-1-jens.wiklander@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org tee_shm_alloc() is replaced by three new functions, tee_shm_alloc_user_buf() - for user mode allocations, replacing passing the flags TEE_SHM_MAPPED | TEE_SHM_DMA_BUF tee_shm_alloc_kernel_buf() - for kernel mode allocations, slightly optimized compared to using the flags TEE_SHM_MAPPED | TEE_SHM_DMA_BUF. tee_shm_alloc_priv_kernel_buf() - primarily for TEE driver internal use. This also makes the interface easier to use as we can get rid of the somewhat hard to use flags parameter. The TEE subsystem and the TEE drivers are updated to use the new functions instead. Signed-off-by: Jens Wiklander --- drivers/tee/optee/call.c | 2 +- drivers/tee/optee/device.c | 5 +- drivers/tee/optee/ffa_abi.c | 4 +- drivers/tee/optee/smc_abi.c | 5 +- drivers/tee/tee_shm.c | 109 +++++++++++++++++++++++------------- include/linux/tee_drv.h | 17 +----- 6 files changed, 78 insertions(+), 64 deletions(-) diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c index b25cc1fac945..fd6ad7d6fbee 100644 --- a/drivers/tee/optee/call.c +++ b/drivers/tee/optee/call.c @@ -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_kernel_buf(ctx, sz); if (IS_ERR(shm)) return shm; diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c index 128a2d2a50a1..f3947be13e2e 100644 --- a/drivers/tee/optee/device.c +++ b/drivers/tee/optee/device.c @@ -121,10 +121,9 @@ static int __optee_enumerate_devices(u32 func) if (rc < 0 || !shm_size) goto out_sess; - device_shm = tee_shm_alloc(ctx, shm_size, - TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); + device_shm = tee_shm_alloc_kernel_buf(ctx, shm_size); if (IS_ERR(device_shm)) { - pr_err("tee_shm_alloc failed\n"); + pr_err("tee_shm_alloc_kernel_buf failed\n"); rc = PTR_ERR(device_shm); goto out_sess; } diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c index e690d9420966..18963f7e4d48 100644 --- a/drivers/tee/optee/ffa_abi.c +++ b/drivers/tee/optee/ffa_abi.c @@ -439,8 +439,8 @@ static void handle_ffa_rpc_func_cmd_shm_alloc(struct tee_context *ctx, shm = optee_rpc_cmd_alloc_suppl(ctx, arg->params[0].u.value.b); break; case OPTEE_RPC_SHM_TYPE_KERNEL: - shm = tee_shm_alloc(ctx, arg->params[0].u.value.b, - TEE_SHM_MAPPED | TEE_SHM_PRIV); + shm = tee_shm_alloc_priv_kernel_buf(ctx, + arg->params[0].u.value.b); break; default: arg->ret = TEEC_ERROR_BAD_PARAMETERS; diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index b679037ea794..196cd4316d7d 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -650,7 +650,7 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, shm = optee_rpc_cmd_alloc_suppl(ctx, sz); break; case OPTEE_RPC_SHM_TYPE_KERNEL: - shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV); + shm = tee_shm_alloc_priv_kernel_buf(ctx, sz); break; default: arg->ret = TEEC_ERROR_BAD_PARAMETERS; @@ -775,8 +775,7 @@ static void optee_handle_rpc(struct tee_context *ctx, switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) { case OPTEE_SMC_RPC_FUNC_ALLOC: - shm = tee_shm_alloc(ctx, param->a1, - TEE_SHM_MAPPED | TEE_SHM_PRIV); + shm = tee_shm_alloc_priv_kernel_buf(ctx, param->a1); if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) { reg_pair_from_64(¶m->a1, ¶m->a2, pa); reg_pair_from_64(¶m->a4, ¶m->a5, diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 2c8ce0c6801a..d51bf97ce7e5 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -49,25 +49,14 @@ static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) tee_device_put(teedev); } -struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) +static struct tee_shm *shm_alloc_helper(struct tee_context *ctx, size_t size, + size_t align, u32 flags, int id) { struct tee_device *teedev = ctx->teedev; struct tee_shm *shm; - size_t align; void *ret; int rc; - if (!(flags & TEE_SHM_MAPPED)) { - dev_err(teedev->dev.parent, - "only mapped allocations supported\n"); - return ERR_PTR(-EINVAL); - } - - if ((flags & ~(TEE_SHM_MAPPED | TEE_SHM_DMA_BUF | TEE_SHM_PRIV))) { - dev_err(teedev->dev.parent, "invalid shm flags 0x%x", flags); - return ERR_PTR(-EINVAL); - } - if (!tee_device_get(teedev)) return ERR_PTR(-EINVAL); @@ -84,18 +73,16 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) } refcount_set(&shm->refcount, 1); - shm->flags = flags | TEE_SHM_POOL; + shm->flags = flags; + shm->id = id; + + /* + * We're assigning this as it is needed if the shm is to be + * registered. If this function returns OK then the caller expected + * to call teedev_ctx_get() or clear shm->ctx in case it's not + * needed any longer. + */ shm->ctx = ctx; - if (flags & TEE_SHM_DMA_BUF) { - align = PAGE_SIZE; - /* - * Request to register the shm in the pool allocator below - * if supported. - */ - shm->flags |= TEE_SHM_REGISTER; - } else { - align = 2 * sizeof(long); - } rc = teedev->pool->ops->alloc(teedev->pool, shm, size, align); if (rc) { @@ -103,28 +90,14 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) goto err_kfree; } - if (flags & TEE_SHM_DMA_BUF) { - mutex_lock(&teedev->mutex); - shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL); - mutex_unlock(&teedev->mutex); - if (shm->id < 0) { - ret = ERR_PTR(shm->id); - goto err_pool_free; - } - } - teedev_ctx_get(ctx); - return shm; -err_pool_free: - teedev->pool->ops->free(teedev->pool, shm); err_kfree: kfree(shm); err_dev_put: tee_device_put(teedev); return ret; } -EXPORT_SYMBOL_GPL(tee_shm_alloc); /** * tee_shm_alloc_user_buf() - Allocate shared memory for user space @@ -140,7 +113,36 @@ EXPORT_SYMBOL_GPL(tee_shm_alloc); */ struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size) { - return tee_shm_alloc(ctx, size, TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); + u32 flags = TEE_SHM_MAPPED | TEE_SHM_DMA_BUF | TEE_SHM_REGISTER | + TEE_SHM_POOL; + struct tee_device *teedev = ctx->teedev; + struct tee_shm *shm; + void *ret; + int id; + + mutex_lock(&teedev->mutex); + id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL); + mutex_unlock(&teedev->mutex); + if (id < 0) + return ERR_PTR(id); + + shm = shm_alloc_helper(ctx, size, PAGE_SIZE, flags, id); + if (IS_ERR(shm)) { + mutex_lock(&teedev->mutex); + idr_remove(&teedev->idr, id); + mutex_unlock(&teedev->mutex); + return shm; + } + + mutex_lock(&teedev->mutex); + ret = idr_replace(&teedev->idr, shm, id); + mutex_unlock(&teedev->mutex); + if (IS_ERR(ret)) { + tee_shm_free(shm); + return ret; + } + + return shm; } EXPORT_SYMBOL_GPL(tee_shm_alloc_user_buf); @@ -158,10 +160,37 @@ EXPORT_SYMBOL_GPL(tee_shm_alloc_user_buf); */ struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size) { - return tee_shm_alloc(ctx, size, TEE_SHM_MAPPED); + u32 flags = TEE_SHM_MAPPED | TEE_SHM_REGISTER | TEE_SHM_POOL; + + return shm_alloc_helper(ctx, size, PAGE_SIZE, flags, -1); } EXPORT_SYMBOL_GPL(tee_shm_alloc_kernel_buf); +/** + * tee_shm_alloc_priv_kernel_buf() - Allocate shared memory for a privatly + * shared kernel buffer + * @ctx: Context that allocates the shared memory + * @size: Requested size of shared memory + * + * This function returns similar shared memory as + * tee_shm_alloc_kernel_buf(), but with the difference that the memory + * might not be registered in secure world in case the driver supports + * passing memory not registered in advance. + * + * This function should normally only be used internally in the TEE + * drivers. + * + * @returns a pointer to 'struct tee_shm' + */ +struct tee_shm *tee_shm_alloc_priv_kernel_buf(struct tee_context *ctx, + size_t size) +{ + u32 flags = TEE_SHM_MAPPED | TEE_SHM_PRIV | TEE_SHM_POOL; + + return shm_alloc_helper(ctx, size, sizeof(long) * 2, flags, -1); +} +EXPORT_SYMBOL_GPL(tee_shm_alloc_priv_kernel_buf); + struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, size_t length, u32 flags) { diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index 808aa23308c2..e71cb0411e9c 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -273,22 +273,9 @@ static inline void tee_shm_pool_free(struct tee_shm_pool *pool) */ void *tee_get_drvdata(struct tee_device *teedev); -/** - * tee_shm_alloc() - Allocate shared memory - * @ctx: Context that allocates the shared memory - * @size: Requested size of shared memory - * @flags: Flags setting properties for the requested shared memory. - * - * Memory allocated as global shared memory is automatically freed when the - * TEE file pointer is closed. The @flags field uses the bits defined by - * TEE_SHM_* above. TEE_SHM_MAPPED must currently always be set. If - * TEE_SHM_DMA_BUF global shared memory will be allocated and associated - * with a dma-buf handle, else driver private memory. - * - * @returns a pointer to 'struct tee_shm' - */ -struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags); struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size); +struct tee_shm *tee_shm_alloc_priv_kernel_buf(struct tee_context *ctx, + size_t size); struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size); /** -- 2.31.1