From: Greg Kroah-Hartman Date: Fri, 25 Feb 2022 12:35:59 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v4.9.304~53 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=825acd074e7f65686a0c2a19833a2b524b6d3102;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: optee-use-driver-internal-tee_context-for-some-rpc.patch tee-export-teedev_open-and-teedev_close_context.patch --- diff --git a/queue-5.15/optee-use-driver-internal-tee_context-for-some-rpc.patch b/queue-5.15/optee-use-driver-internal-tee_context-for-some-rpc.patch new file mode 100644 index 00000000000..b595fce5cb1 --- /dev/null +++ b/queue-5.15/optee-use-driver-internal-tee_context-for-some-rpc.patch @@ -0,0 +1,131 @@ +From aceeafefff736057e8f93f19bbfbef26abd94604 Mon Sep 17 00:00:00 2001 +From: Jens Wiklander +Date: Thu, 27 Jan 2022 15:29:39 +0100 +Subject: optee: use driver internal tee_context for some rpc + +From: Jens Wiklander + +commit aceeafefff736057e8f93f19bbfbef26abd94604 upstream. + +Adds a driver private tee_context by moving the tee_context in struct +optee_notif to struct optee. This tee_context was previously used when +doing internal calls to secure world to deliver notification. + +The new driver internal tee_context is now also when allocating driver +private shared memory. This decouples the shared memory object from its +original tee_context. This is needed when the life time of such a memory +allocation outlives the client tee_context. + +This patch fixes the problem described below: + +The addition of a shutdown hook by commit f25889f93184 ("optee: fix tee out +of memory failure seen during kexec reboot") introduced a kernel shutdown +regression that can be triggered after running the OP-TEE xtest suites. + +Once the shutdown hook is called it is not possible to communicate any more +with the supplicant process because the system is not scheduling task any +longer. Thus if the optee driver shutdown path receives a supplicant RPC +request from the OP-TEE we will deadlock the kernel's shutdown. + +Fixes: f25889f93184 ("optee: fix tee out of memory failure seen during kexec reboot") +Fixes: 217e0250cccb ("tee: use reference counting for tee_context") +Reported-by: Lars Persson +Cc: stable@vger.kernel.org +Reviewed-by: Sumit Garg +Signed-off-by: Jens Wiklander +[JW: backport to 5.15-stable + update commit message] +Signed-off-by: Jens Wiklander +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tee/optee/core.c | 8 ++++++++ + drivers/tee/optee/optee_private.h | 2 ++ + drivers/tee/optee/rpc.c | 8 +++++--- + 3 files changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/tee/optee/core.c ++++ b/drivers/tee/optee/core.c +@@ -588,6 +588,7 @@ static int optee_remove(struct platform_ + /* Unregister OP-TEE specific client devices on TEE bus */ + optee_unregister_devices(); + ++ teedev_close_context(optee->ctx); + /* + * Ask OP-TEE to free all cached shared memory objects to decrease + * reference counters and also avoid wild pointers in secure world +@@ -633,6 +634,7 @@ static int optee_probe(struct platform_d + struct optee *optee = NULL; + void *memremaped_shm = NULL; + struct tee_device *teedev; ++ struct tee_context *ctx; + u32 sec_caps; + int rc; + +@@ -719,6 +721,12 @@ static int optee_probe(struct platform_d + optee_supp_init(&optee->supp); + optee->memremaped_shm = memremaped_shm; + optee->pool = pool; ++ ctx = teedev_open(optee->teedev); ++ if (IS_ERR(ctx)) { ++ rc = PTR_ERR(ctx); ++ goto err; ++ } ++ optee->ctx = ctx; + + /* + * Ensure that there are no pre-existing shm objects before enabling +--- a/drivers/tee/optee/optee_private.h ++++ b/drivers/tee/optee/optee_private.h +@@ -70,6 +70,7 @@ struct optee_supp { + * struct optee - main service struct + * @supp_teedev: supplicant device + * @teedev: client device ++ * @ctx: driver internal TEE context + * @invoke_fn: function to issue smc or hvc + * @call_queue: queue of threads waiting to call @invoke_fn + * @wait_queue: queue of threads from secure world waiting for a +@@ -87,6 +88,7 @@ struct optee { + struct tee_device *supp_teedev; + struct tee_device *teedev; + optee_invoke_fn *invoke_fn; ++ struct tee_context *ctx; + struct optee_call_queue call_queue; + struct optee_wait_queue wait_queue; + struct optee_supp supp; +--- a/drivers/tee/optee/rpc.c ++++ b/drivers/tee/optee/rpc.c +@@ -285,6 +285,7 @@ static struct tee_shm *cmd_alloc_suppl(s + } + + static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, ++ struct optee *optee, + struct optee_msg_arg *arg, + struct optee_call_ctx *call_ctx) + { +@@ -314,7 +315,8 @@ static void handle_rpc_func_cmd_shm_allo + shm = 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(optee->ctx, sz, ++ TEE_SHM_MAPPED | TEE_SHM_PRIV); + break; + default: + arg->ret = TEEC_ERROR_BAD_PARAMETERS; +@@ -471,7 +473,7 @@ static void handle_rpc_func_cmd(struct t + break; + case OPTEE_RPC_CMD_SHM_ALLOC: + free_pages_list(call_ctx); +- handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx); ++ handle_rpc_func_cmd_shm_alloc(ctx, optee, arg, call_ctx); + break; + case OPTEE_RPC_CMD_SHM_FREE: + handle_rpc_func_cmd_shm_free(ctx, arg); +@@ -502,7 +504,7 @@ void optee_handle_rpc(struct tee_context + + switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) { + case OPTEE_SMC_RPC_FUNC_ALLOC: +- shm = tee_shm_alloc(ctx, param->a1, ++ shm = tee_shm_alloc(optee->ctx, param->a1, + TEE_SHM_MAPPED | TEE_SHM_PRIV); + if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) { + reg_pair_from_64(¶m->a1, ¶m->a2, pa); diff --git a/queue-5.15/series b/queue-5.15/series index fa89538113b..8f3d11ac273 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -27,3 +27,5 @@ cdc-ncm-avoid-overflow-in-sanity-checking.patch netfilter-xt_socket-fix-a-typo-in-socket_mt_destroy.patch netfilter-xt_socket-missing-ifdef-config_ip6_nf_iptables-dependency.patch netfilter-nf_tables_offload-incorrect-flow-offload-action-array-size.patch +tee-export-teedev_open-and-teedev_close_context.patch +optee-use-driver-internal-tee_context-for-some-rpc.patch diff --git a/queue-5.15/tee-export-teedev_open-and-teedev_close_context.patch b/queue-5.15/tee-export-teedev_open-and-teedev_close_context.patch new file mode 100644 index 00000000000..6c8401ed1b3 --- /dev/null +++ b/queue-5.15/tee-export-teedev_open-and-teedev_close_context.patch @@ -0,0 +1,76 @@ +From 1e2c3ef0496e72ba9001da5fd1b7ed56ccb30597 Mon Sep 17 00:00:00 2001 +From: Jens Wiklander +Date: Mon, 4 Oct 2021 16:11:52 +0200 +Subject: tee: export teedev_open() and teedev_close_context() + +From: Jens Wiklander + +commit 1e2c3ef0496e72ba9001da5fd1b7ed56ccb30597 upstream. + +Exports the two functions teedev_open() and teedev_close_context() in +order to make it easier to create a driver internal struct tee_context. + +Reviewed-by: Sumit Garg +Signed-off-by: Jens Wiklander +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tee/tee_core.c | 6 ++++-- + include/linux/tee_drv.h | 14 ++++++++++++++ + 2 files changed, 18 insertions(+), 2 deletions(-) + +--- a/drivers/tee/tee_core.c ++++ b/drivers/tee/tee_core.c +@@ -43,7 +43,7 @@ static DEFINE_SPINLOCK(driver_lock); + static struct class *tee_class; + static dev_t tee_devt; + +-static struct tee_context *teedev_open(struct tee_device *teedev) ++struct tee_context *teedev_open(struct tee_device *teedev) + { + int rc; + struct tee_context *ctx; +@@ -70,6 +70,7 @@ err: + return ERR_PTR(rc); + + } ++EXPORT_SYMBOL_GPL(teedev_open); + + void teedev_ctx_get(struct tee_context *ctx) + { +@@ -96,13 +97,14 @@ void teedev_ctx_put(struct tee_context * + kref_put(&ctx->refcount, teedev_ctx_release); + } + +-static void teedev_close_context(struct tee_context *ctx) ++void teedev_close_context(struct tee_context *ctx) + { + struct tee_device *teedev = ctx->teedev; + + teedev_ctx_put(ctx); + tee_device_put(teedev); + } ++EXPORT_SYMBOL_GPL(teedev_close_context); + + static int tee_open(struct inode *inode, struct file *filp) + { +--- a/include/linux/tee_drv.h ++++ b/include/linux/tee_drv.h +@@ -582,4 +582,18 @@ struct tee_client_driver { + #define to_tee_client_driver(d) \ + container_of(d, struct tee_client_driver, driver) + ++/** ++ * teedev_open() - Open a struct tee_device ++ * @teedev: Device to open ++ * ++ * @return a pointer to struct tee_context on success or an ERR_PTR on failure. ++ */ ++struct tee_context *teedev_open(struct tee_device *teedev); ++ ++/** ++ * teedev_close_context() - closes a struct tee_context ++ * @ctx: The struct tee_context to close ++ */ ++void teedev_close_context(struct tee_context *ctx); ++ + #endif /*__TEE_DRV_H*/