Received: by 2002:a05:6a10:7420:0:0:0:0 with SMTP id hk32csp3794194pxb; Mon, 21 Feb 2022 05:58:53 -0800 (PST) X-Google-Smtp-Source: ABdhPJwY3G8gdR688skI7GhwaFZO+ieU4nrMPxQHKn5vN0zuTZsRatut1V6ENH/N27jwdO58Dhzg X-Received: by 2002:a17:903:230e:b0:14d:a8c5:90c2 with SMTP id d14-20020a170903230e00b0014da8c590c2mr19487899plh.5.1645451933272; Mon, 21 Feb 2022 05:58:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1645451933; cv=none; d=google.com; s=arc-20160816; b=olIFvypD/xGpoxooJi7BseBrQpUv4nZPk2c78A39Y54OujZY+I1DKC7j3soo+1zsEk pmC5fFlsi2BAbUDQ431ATr9V39j0GFJtlK7GMcxzyRFwIq/y0jBxM7tnQPvYyBfURPP4 R1HOpURIqOnQrSJDw/XBKQTb6VqHIOTpoVjiBzWxWsE+hwAh99WA0w383ehJiBJN4AVj Jrn0axtZ4orwpyPHU/Ke15/KP9kIv5EBvgYHjT6R6/6lL/JEz2EABbE8acUvh4sK1I17 e0X+rDtbfyb8tOygTbe+spKk4K5vR/UHWf1JFwt1iibxuGlP0RI3oEplYVix4QSSWybh BT2Q== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=pFVn0QOo+Zcg+06MiM9QzzBCSyfRtxUu954RTSUNr0w=; b=aYYlRmbj8UQNDW8bpywsEU99rL99NDaQ3q64V/Rh6THAWXIn4eZiR2seGqyM4yjQEo rl+DXcv7KgweiycKjX25HIDQG0nuyYKWjdFoYrWNPBp8f5jGqIwrhPwuNcQ6TGQXif0D UI1X09kU1dtl1g6cQ7s8/vhGlpLhlHxHxAfPZu0LKfoGJIiyiNGAtZauruMxl5v4QWp2 XA6m3yzWrn2GEhPkLQghgia88Bv+mvJ58sUaJEqZW3sk7lLKzGtlvFm4ESSSTcBuZpXf NdwwdXPKwgvFiH4HMeS3Uw/lvjHbClhrbUn5w+8iHrWUyfulBis7ojXWXxt36byf2cFQ zqCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=1CUL7LPT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b17-20020a17090a489100b001b8c6dcca5dsi6475854pjh.2.2022.02.21.05.58.38; Mon, 21 Feb 2022 05:58:53 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=1CUL7LPT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353631AbiBUJ5g (ORCPT + 99 others); Mon, 21 Feb 2022 04:57:36 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:41672 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352730AbiBUJrv (ORCPT ); Mon, 21 Feb 2022 04:47:51 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 031DD43AE9; Mon, 21 Feb 2022 01:20:21 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8D6F760B1E; Mon, 21 Feb 2022 09:20:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A25D0C340E9; Mon, 21 Feb 2022 09:20:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1645435221; bh=Reg4j40feaS9usqLz7Yj0e17Lz0RrzXRqkX2eGW8+Ms=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1CUL7LPTgcoNun0aze2qSRYB73McsDg2mBcpJrRCvlMOU/RfIMCqkWbazJOPdrj1n UxLIgeyfRoSgzRrdrZ/qI0qiCEzOAkV/sxE1AoQae6gTpf+zXS7jxM2j/oy2ZlGXcI g/xk4UHKYNjJIJmQFlH76otmvH77fG2NaKFQe59c= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Lars Persson , Sumit Garg , Jens Wiklander Subject: [PATCH 5.16 088/227] optee: use driver internal tee_context for some rpc Date: Mon, 21 Feb 2022 09:48:27 +0100 Message-Id: <20220221084937.806250169@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220221084934.836145070@linuxfoundation.org> References: <20220221084934.836145070@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 [JW: backport to 5.16-stable + update commit message] Signed-off-by: Jens Wiklander Signed-off-by: Greg Kroah-Hartman --- drivers/tee/optee/core.c | 1 drivers/tee/optee/ffa_abi.c | 70 +++++++++++++++++++++----------------- drivers/tee/optee/optee_private.h | 4 +- drivers/tee/optee/smc_abi.c | 13 +++++-- 4 files changed, 54 insertions(+), 34 deletions(-) --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -157,6 +157,7 @@ void optee_remove_common(struct optee *o /* Unregister OP-TEE specific client devices on TEE bus */ optee_unregister_devices(); + teedev_close_context(optee->ctx); /* * The two devices have to be unregistered before we can free the * other resources. --- a/drivers/tee/optee/ffa_abi.c +++ b/drivers/tee/optee/ffa_abi.c @@ -424,6 +424,7 @@ static struct tee_shm_pool_mgr *optee_ff */ static void handle_ffa_rpc_func_cmd_shm_alloc(struct tee_context *ctx, + struct optee *optee, struct optee_msg_arg *arg) { struct tee_shm *shm; @@ -439,7 +440,7 @@ static void handle_ffa_rpc_func_cmd_shm_ 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, + shm = tee_shm_alloc(optee->ctx, arg->params[0].u.value.b, TEE_SHM_MAPPED | TEE_SHM_PRIV); break; default: @@ -493,14 +494,13 @@ err_bad_param: } static void handle_ffa_rpc_func_cmd(struct tee_context *ctx, + struct optee *optee, struct optee_msg_arg *arg) { - struct optee *optee = tee_get_drvdata(ctx->teedev); - arg->ret_origin = TEEC_ORIGIN_COMMS; switch (arg->cmd) { case OPTEE_RPC_CMD_SHM_ALLOC: - handle_ffa_rpc_func_cmd_shm_alloc(ctx, arg); + handle_ffa_rpc_func_cmd_shm_alloc(ctx, optee, arg); break; case OPTEE_RPC_CMD_SHM_FREE: handle_ffa_rpc_func_cmd_shm_free(ctx, optee, arg); @@ -510,12 +510,12 @@ static void handle_ffa_rpc_func_cmd(stru } } -static void optee_handle_ffa_rpc(struct tee_context *ctx, u32 cmd, - struct optee_msg_arg *arg) +static void optee_handle_ffa_rpc(struct tee_context *ctx, struct optee *optee, + u32 cmd, struct optee_msg_arg *arg) { switch (cmd) { case OPTEE_FFA_YIELDING_CALL_RETURN_RPC_CMD: - handle_ffa_rpc_func_cmd(ctx, arg); + handle_ffa_rpc_func_cmd(ctx, optee, arg); break; case OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT: /* Interrupt delivered by now */ @@ -582,7 +582,7 @@ static int optee_ffa_yielding_call(struc * above. */ cond_resched(); - optee_handle_ffa_rpc(ctx, data->data1, rpc_arg); + optee_handle_ffa_rpc(ctx, optee, data->data1, rpc_arg); cmd = OPTEE_FFA_YIELDING_CALL_RESUME; data->data0 = cmd; data->data1 = 0; @@ -802,7 +802,9 @@ static int optee_ffa_probe(struct ffa_de { const struct ffa_dev_ops *ffa_ops; unsigned int rpc_arg_count; + struct tee_shm_pool *pool; struct tee_device *teedev; + struct tee_context *ctx; struct optee *optee; int rc; @@ -822,12 +824,12 @@ static int optee_ffa_probe(struct ffa_de if (!optee) return -ENOMEM; - optee->pool = optee_ffa_config_dyn_shm(); - if (IS_ERR(optee->pool)) { - rc = PTR_ERR(optee->pool); - optee->pool = NULL; - goto err; + pool = optee_ffa_config_dyn_shm(); + if (IS_ERR(pool)) { + rc = PTR_ERR(pool); + goto err_free_optee; } + optee->pool = pool; optee->ops = &optee_ffa_ops; optee->ffa.ffa_dev = ffa_dev; @@ -838,7 +840,7 @@ static int optee_ffa_probe(struct ffa_de optee); if (IS_ERR(teedev)) { rc = PTR_ERR(teedev); - goto err; + goto err_free_pool; } optee->teedev = teedev; @@ -846,46 +848,54 @@ static int optee_ffa_probe(struct ffa_de optee); if (IS_ERR(teedev)) { rc = PTR_ERR(teedev); - goto err; + goto err_unreg_teedev; } optee->supp_teedev = teedev; rc = tee_device_register(optee->teedev); if (rc) - goto err; + goto err_unreg_supp_teedev; rc = tee_device_register(optee->supp_teedev); if (rc) - goto err; + goto err_unreg_supp_teedev; rc = rhashtable_init(&optee->ffa.global_ids, &shm_rhash_params); if (rc) - goto err; + goto err_unreg_supp_teedev; mutex_init(&optee->ffa.mutex); mutex_init(&optee->call_queue.mutex); INIT_LIST_HEAD(&optee->call_queue.waiters); optee_wait_queue_init(&optee->wait_queue); optee_supp_init(&optee->supp); ffa_dev_set_drvdata(ffa_dev, optee); + ctx = teedev_open(optee->teedev); + if (IS_ERR(ctx)) + goto err_rhashtable_free; + optee->ctx = ctx; + rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES); - if (rc) { - optee_ffa_remove(ffa_dev); - return rc; - } + if (rc) + goto err_unregister_devices; pr_info("initialized driver\n"); return 0; -err: - /* - * tee_device_unregister() is safe to call even if the - * devices hasn't been registered with - * tee_device_register() yet. - */ + +err_unregister_devices: + optee_unregister_devices(); + teedev_close_context(ctx); +err_rhashtable_free: + rhashtable_free_and_destroy(&optee->ffa.global_ids, rh_free_fn, NULL); + optee_supp_uninit(&optee->supp); + mutex_destroy(&optee->call_queue.mutex); +err_unreg_supp_teedev: tee_device_unregister(optee->supp_teedev); +err_unreg_teedev: tee_device_unregister(optee->teedev); - if (optee->pool) - tee_shm_pool_free(optee->pool); +err_free_pool: + tee_shm_pool_free(pool); +err_free_optee: kfree(optee); return rc; } --- a/drivers/tee/optee/optee_private.h +++ b/drivers/tee/optee/optee_private.h @@ -123,9 +123,10 @@ struct optee_ops { /** * struct optee - main service struct * @supp_teedev: supplicant device + * @teedev: client device * @ops: internal callbacks for different ways to reach secure * world - * @teedev: client device + * @ctx: driver internal TEE context * @smc: specific to SMC ABI * @ffa: specific to FF-A ABI * @call_queue: queue of threads waiting to call @invoke_fn @@ -142,6 +143,7 @@ struct optee { struct tee_device *supp_teedev; struct tee_device *teedev; const struct optee_ops *ops; + struct tee_context *ctx; union { struct optee_smc smc; struct optee_ffa ffa; --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -608,6 +608,7 @@ static void handle_rpc_func_cmd_shm_free } 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) { @@ -637,7 +638,8 @@ static void handle_rpc_func_cmd_shm_allo 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(optee->ctx, sz, + TEE_SHM_MAPPED | TEE_SHM_PRIV); break; default: arg->ret = TEEC_ERROR_BAD_PARAMETERS; @@ -733,7 +735,7 @@ static void handle_rpc_func_cmd(struct t switch (arg->cmd) { 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); @@ -762,7 +764,7 @@ static void optee_handle_rpc(struct tee_ 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); @@ -1207,6 +1209,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; @@ -1284,6 +1287,10 @@ static int optee_probe(struct platform_d optee_supp_init(&optee->supp); optee->smc.memremaped_shm = memremaped_shm; optee->pool = pool; + ctx = teedev_open(optee->teedev); + if (IS_ERR(ctx)) + goto err; + optee->ctx = ctx; /* * Ensure that there are no pre-existing shm objects before enabling