From patchwork Fri Jan 11 11:47:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 10757913 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E0C721515 for ; Fri, 11 Jan 2019 11:50:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D056929898 for ; Fri, 11 Jan 2019 11:50:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C3F8A298A1; Fri, 11 Jan 2019 11:50:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B862F29898 for ; Fri, 11 Jan 2019 11:50:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731703AbfAKLuG (ORCPT ); Fri, 11 Jan 2019 06:50:06 -0500 Received: from mail-pg1-f196.google.com ([209.85.215.196]:35021 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731702AbfAKLuG (ORCPT ); Fri, 11 Jan 2019 06:50:06 -0500 Received: by mail-pg1-f196.google.com with SMTP id s198so6243714pgs.2 for ; Fri, 11 Jan 2019 03:50:05 -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; bh=6abORcUabUlyQ/4AP1uyvPR1q2RgpmyN10/gdUhWenU=; b=g7gHW/jWIMatBO2ENQA5SeXRuUX/6+SBSitd2LC02rG48Qav0QUTKMPvKqhqp+PIPo B17vysB8REO2mwgTVcJS2rLsQUkjzmafkzovfO4ZR04o7Xu8yIs58dZIcLV1fQ9oIFHf KRaGg5tEbFErZjiuevko6B4g1rStpuLJoimOM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6abORcUabUlyQ/4AP1uyvPR1q2RgpmyN10/gdUhWenU=; b=jkOjcS8hs2zbFSsiQIDIFCQ1jbZOPU6cxcHYS6dfMZsouu8TYl/LCOFllv4PTK4dTO Wo+2rBYPHIes75CA6PTVC2fGijkOeWO4i53fwt5ZeMac1u1nuzw3qlBCkaOwO89YCFsu Xtls6ADrmm6/4+BBQRb5SXyDBEOatWXib1trapb8hzUbr/bsi/xpKS4yYn8uc101C2PO 3oxdReP1V6/K+bkZwI85fRUOeAWsY380/+PKsr2jxE0EH218HW8U1YTklk2resTzXaoB Xpv2wVav6QJrAVL7WwWb1YmViYXw1KEfdW/UXs96X2ObzE3CLgCxWh0LwQ5vjPXD39q1 diFw== X-Gm-Message-State: AJcUuke0r5XjoM/Y4/+/1B5XIGoBWAFzuxqqUwOdWxuWkwC4buyNHBpz LmWHD4zYHf43v08CIT9a0f33Eg== X-Google-Smtp-Source: ALg8bN7XYNUYJM7hDizvK2p4tYdBY6+A0ZJZjunM2Hc/7vNmrrdGjYmjvidWWZisWpHamDADz/6l+g== X-Received: by 2002:a62:8e19:: with SMTP id k25mr14208417pfe.185.1547207405038; Fri, 11 Jan 2019 03:50:05 -0800 (PST) Received: from localhost.localdomain ([117.196.233.251]) by smtp.gmail.com with ESMTPSA id b2sm143199988pfm.3.2019.01.11.03.49.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 11 Jan 2019 03:50:04 -0800 (PST) From: Sumit Garg To: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, jens.wiklander@linaro.org, mpm@selenic.com, herbert@gondor.apana.org.au, robh+dt@kernel.org, mark.rutland@arm.com, arnd@arndb.de, gregkh@linuxfoundation.org, daniel.thompson@linaro.org, ard.biesheuvel@linaro.org, bhsharma@redhat.com, tee-dev@lists.linaro.org, Sumit Garg Subject: [PATCH v3 1/4] tee: add bus driver framework for TEE based devices Date: Fri, 11 Jan 2019 17:17:28 +0530 Message-Id: <1547207251-9372-2-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1547207251-9372-1-git-send-email-sumit.garg@linaro.org> References: <1547207251-9372-1-git-send-email-sumit.garg@linaro.org> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Introduce a generic TEE bus driver concept for TEE based kernel drivers which would like to communicate with TEE based devices/services. In this TEE bus concept, devices/services are identified via Universally Unique Identifier (UUID) and drivers register a table of device UUIDs which they can support. So this TEE bus framework registers a match() callback function which iterates over the driver UUID table to find a corresponding match for device UUID. If a match is found, then this particular device is probed via corresponding probe api registered by the driver. This process happens whenever a device or a driver is registered with TEE bus. Also this framework allows for device enumeration to be specific to corresponding TEE implementation like OP-TEE etc. Signed-off-by: Sumit Garg --- drivers/tee/tee_core.c | 43 ++++++++++++++++++++++++++++++++++++++++--- include/linux/tee_drv.h | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 7b2bb4c..a685940 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -15,7 +15,6 @@ #define pr_fmt(fmt) "%s: " fmt, __func__ #include -#include #include #include #include @@ -1027,6 +1026,30 @@ int tee_client_invoke_func(struct tee_context *ctx, } EXPORT_SYMBOL_GPL(tee_client_invoke_func); +static int tee_client_device_match(struct device *dev, + struct device_driver *drv) +{ + struct tee_client_device *tee_device; + const struct tee_client_device_id *id_table; + + tee_device = to_tee_client_device(dev); + id_table = to_tee_client_driver(drv)->id_table; + + while (!uuid_is_null(&id_table->uuid)) { + if (uuid_equal(&tee_device->id.uuid, &id_table->uuid)) + return 1; + id_table++; + } + + return 0; +} + +struct bus_type tee_bus_type = { + .name = "tee", + .match = tee_client_device_match, +}; +EXPORT_SYMBOL_GPL(tee_bus_type); + static int __init tee_init(void) { int rc; @@ -1040,10 +1063,23 @@ static int __init tee_init(void) rc = alloc_chrdev_region(&tee_devt, 0, TEE_NUM_DEVICES, "tee"); if (rc) { pr_err("failed to allocate char dev region\n"); - class_destroy(tee_class); - tee_class = NULL; + goto chrdev_err; } + rc = bus_register(&tee_bus_type); + if (rc) { + pr_err("failed to register tee bus\n"); + goto bus_err; + } + + return 0; + +bus_err: + unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES); +chrdev_err: + class_destroy(tee_class); + tee_class = NULL; + return rc; } @@ -1052,6 +1088,7 @@ static void __exit tee_exit(void) class_destroy(tee_class); tee_class = NULL; unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES); + bus_unregister(&tee_bus_type); } subsys_initcall(tee_init); diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index 6cfe058..ed16bf1 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -20,6 +20,8 @@ #include #include #include +#include +#include /* * The file describes the API provided by the generic TEE driver to the @@ -538,4 +540,38 @@ static inline bool tee_param_is_memref(struct tee_param *param) } } +extern struct bus_type tee_bus_type; + +/** + * struct tee_client_device_id - tee based device identifier + * @uuid: For TEE based client devices we use the device uuid + * as the identifier. + */ +struct tee_client_device_id { + uuid_t uuid; +}; + +/** + * struct tee_client_device - tee based device + * @id: device identifier + * @dev: device structure + */ +struct tee_client_device { + struct tee_client_device_id id; + struct device dev; +}; +#define to_tee_client_device(d) container_of(d, struct tee_client_device, dev) + +/** + * struct tee_client_driver - tee client driver + * @id_table: device id table supported by this driver + * @driver: driver structure + */ +struct tee_client_driver { + const struct tee_client_device_id *id_table; + struct device_driver driver; +}; +#define to_tee_client_driver(d) \ + container_of(d, struct tee_client_driver, driver) + #endif /*__TEE_DRV_H*/ From patchwork Fri Jan 11 11:47:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 10757915 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2F6EB6C5 for ; Fri, 11 Jan 2019 11:50:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1FCDB29263 for ; Fri, 11 Jan 2019 11:50:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 13CFA2987A; Fri, 11 Jan 2019 11:50:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9517F29263 for ; Fri, 11 Jan 2019 11:50:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731763AbfAKLuO (ORCPT ); Fri, 11 Jan 2019 06:50:14 -0500 Received: from mail-pl1-f196.google.com ([209.85.214.196]:38218 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731749AbfAKLuO (ORCPT ); Fri, 11 Jan 2019 06:50:14 -0500 Received: by mail-pl1-f196.google.com with SMTP id e5so6669446plb.5 for ; Fri, 11 Jan 2019 03:50:13 -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; bh=Zqnv4LLkDg8wPzP1MIvwucQL3XBVPPUY8eZwPtDeR+I=; b=An9XWEfxwBQmgY60VBFH2PgnzUFECLIYcdZATyaB+XWVeq82O4UE+u0WtmzHvjtUBX SB6oboCayi2YZm9mMaCL597MrPCQOht5/suCwwVcqoo0nmtxZf3dAH0FSFPBNycC0uBE Nlc7Sd+8q7bmhlSwWL7d8ia293GvGjM7JPBDE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Zqnv4LLkDg8wPzP1MIvwucQL3XBVPPUY8eZwPtDeR+I=; b=ZfFH0Z/rB1ISoS1KgiDY3TQlSEDxiSPMlMFOAL54HSkDsEgvkIzaZZ9WrRUn+vvMW4 f+obFzc/k+oJdAST4zkAsh+9O/q0KnVg2dd8UcrbPgKKmRAgEdJ8rkrzcr/86sesrafi fIH1jc6DljszJCsPq0OenAiMgMdJKXSs77N2wM9bkxFMdETPiX+P1MaeV7Ol+Zqy4DXk ZgBXu3yUIARKocRtS1fUNOVNnV4o7ufzMUsuNFvwzGw6MPDF4SChXMg3krxu15/Yrjut jcqFzMXsJziEhA2EfmT8OcvFODJlEXS8rNAKixWnS71GuXBKbIwZ+9vUPJEW5tdSlmpn /Y/g== X-Gm-Message-State: AJcUukf/nZC266mTqNrGc97+8j4HonN18CQIXoF/fWeg53Bft+14wpVr AqZWYnxUTUqliT7yB6wiu7t57A== X-Google-Smtp-Source: ALg8bN5PbP61zIdl4XkV00TWsScqNY5ZDdMTwpftWQ31TuS0fr0CbHG3Bmso66LgBq2Ku3YubRieFQ== X-Received: by 2002:a17:902:6b49:: with SMTP id g9mr14099084plt.98.1547207412969; Fri, 11 Jan 2019 03:50:12 -0800 (PST) Received: from localhost.localdomain ([117.196.233.251]) by smtp.gmail.com with ESMTPSA id b2sm143199988pfm.3.2019.01.11.03.50.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 11 Jan 2019 03:50:12 -0800 (PST) From: Sumit Garg To: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, jens.wiklander@linaro.org, mpm@selenic.com, herbert@gondor.apana.org.au, robh+dt@kernel.org, mark.rutland@arm.com, arnd@arndb.de, gregkh@linuxfoundation.org, daniel.thompson@linaro.org, ard.biesheuvel@linaro.org, bhsharma@redhat.com, tee-dev@lists.linaro.org, Sumit Garg Subject: [PATCH v3 2/4] tee: add supp_nowait flag in tee_context struct Date: Fri, 11 Jan 2019 17:17:29 +0530 Message-Id: <1547207251-9372-3-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1547207251-9372-1-git-send-email-sumit.garg@linaro.org> References: <1547207251-9372-1-git-send-email-sumit.garg@linaro.org> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This flag indicates that requests in this context should not wait for tee-supplicant daemon to be started if not present and just return with an error code. It is needed for requests which should be non-blocking in nature like ones arising from TEE based kernel drivers or any in kernel api that uses TEE internal client interface. Signed-off-by: Sumit Garg --- drivers/tee/optee/supp.c | 10 +++++++++- drivers/tee/tee_core.c | 13 +++++++++++++ include/linux/tee_drv.h | 6 ++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c index 43626e1..92f56b8 100644 --- a/drivers/tee/optee/supp.c +++ b/drivers/tee/optee/supp.c @@ -88,10 +88,18 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, { struct optee *optee = tee_get_drvdata(ctx->teedev); struct optee_supp *supp = &optee->supp; - struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL); + struct optee_supp_req *req; bool interruptable; u32 ret; + /* + * Return in case there is no supplicant available and + * non-blocking request. + */ + if (!supp->ctx && ctx->supp_nowait) + return TEEC_ERROR_COMMUNICATION; + + req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return TEEC_ERROR_OUT_OF_MEMORY; diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index a685940..eed83bd 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -105,6 +105,11 @@ static int tee_open(struct inode *inode, struct file *filp) if (IS_ERR(ctx)) return PTR_ERR(ctx); + /* + * Default user-space behaviour is to wait for tee-supplicant + * if not present for any requests in this context. + */ + ctx->supp_nowait = false; filp->private_data = ctx; return 0; } @@ -981,6 +986,14 @@ tee_client_open_context(struct tee_context *start, } while (IS_ERR(ctx) && PTR_ERR(ctx) != -ENOMEM); put_device(put_dev); + /* + * Default behaviour for in kernel client is to not wait for + * tee-supplicant if not present for any requests in this context. + * Also this flag could be configured again before call to + * tee_client_open_session() if any in kernel client requires + * different behaviour. + */ + ctx->supp_nowait = true; return ctx; } EXPORT_SYMBOL_GPL(tee_client_open_context); diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index ed16bf1..fe1a920 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -49,6 +49,11 @@ struct tee_shm_pool; * @releasing: flag that indicates if context is being released right now. * It is needed to break circular dependency on context during * shared memory release. + * @supp_nowait: flag that indicates that requests in this context should not + * wait for tee-supplicant daemon to be started if not present + * and just return with an error code. It is needed for requests + * that arises from TEE based kernel drivers that should be + * non-blocking in nature. */ struct tee_context { struct tee_device *teedev; @@ -56,6 +61,7 @@ struct tee_context { void *data; struct kref refcount; bool releasing; + bool supp_nowait; }; struct tee_param_memref { From patchwork Fri Jan 11 11:47:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 10757919 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E40881515 for ; Fri, 11 Jan 2019 11:50:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D3B4929263 for ; Fri, 11 Jan 2019 11:50:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C7C2E2987A; Fri, 11 Jan 2019 11:50:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 34C3029263 for ; Fri, 11 Jan 2019 11:50:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731785AbfAKLuW (ORCPT ); Fri, 11 Jan 2019 06:50:22 -0500 Received: from mail-pl1-f196.google.com ([209.85.214.196]:46704 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731783AbfAKLuU (ORCPT ); Fri, 11 Jan 2019 06:50:20 -0500 Received: by mail-pl1-f196.google.com with SMTP id t13so6663425ply.13 for ; Fri, 11 Jan 2019 03:50:20 -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; bh=dnEldj1krFnyBcZ28g4diO0QN2WcNK+iA+Bx1sW0hq8=; b=fdQYo3kmCkeAaNH1504R+ZjcZ/Mjnh+9oIiMFWuuYZyF1sCzUoufwO8ibOFWopjGlu 58aiX9toAVA6qVouHFDMwwvHG2UsF53zGcuUgQWfg5GVNfd9zBNS1W8tnrfdW55hkhZa BODyTYz8kDJSrUzT7hmV51jHt44lzeNwmjSc8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dnEldj1krFnyBcZ28g4diO0QN2WcNK+iA+Bx1sW0hq8=; b=o/OrA4ohBj1S2dtP6JPd6GzCLHDvp9QKFXFKaFHJklsT+aIko2C24vVGxQf3bCdASK rpxxR0DhneNlKjkAk+qI/5KYpAlJ8j19zAsSodaAlv3NSmTi6SyTXnuIkcr+9J70UK10 gTiK0nueecFEdMAmHuZTkGDeEUnqncr18soxV09Qo2SpnX4OD4IUG6w5lZSr154lfdAp j/tTPk2V15ljYWmjz7XEWm7HlMKl5YR59kZzs6J30PfeFyzmZK4/S/azFeGtRxN4IZ6K l53S7EkmhqE9cP+h5xoWg3UVyUO8rmWKhrcNxnV5ucjDWMlE4IRtt6YhnjoZlaGM9Pmh J3Lw== X-Gm-Message-State: AJcUukdqA7UbwqaTjNPr4mtPA9s7Ke1DfWIMeVp3Qy7xiiSX5Cl3Ohlu N+FyCRa4R0EF8YYdj9TzStMaSA== X-Google-Smtp-Source: ALg8bN47uMTKJ6y7QGDpdfwmD/V75F+OT+Lp8WzfGCJF3JxhXZsWkzxD+U5auXEyisk57G70N0arkg== X-Received: by 2002:a17:902:6b83:: with SMTP id p3mr14242950plk.118.1547207419680; Fri, 11 Jan 2019 03:50:19 -0800 (PST) Received: from localhost.localdomain ([117.196.233.251]) by smtp.gmail.com with ESMTPSA id b2sm143199988pfm.3.2019.01.11.03.50.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 11 Jan 2019 03:50:19 -0800 (PST) From: Sumit Garg To: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, jens.wiklander@linaro.org, mpm@selenic.com, herbert@gondor.apana.org.au, robh+dt@kernel.org, mark.rutland@arm.com, arnd@arndb.de, gregkh@linuxfoundation.org, daniel.thompson@linaro.org, ard.biesheuvel@linaro.org, bhsharma@redhat.com, tee-dev@lists.linaro.org, Sumit Garg Subject: [PATCH v3 3/4] tee: optee: add TEE bus device enumeration support Date: Fri, 11 Jan 2019 17:17:30 +0530 Message-Id: <1547207251-9372-4-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1547207251-9372-1-git-send-email-sumit.garg@linaro.org> References: <1547207251-9372-1-git-send-email-sumit.garg@linaro.org> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP OP-TEE provides a pseudo TA to enumerate TAs which can act as devices/ services for TEE bus. So implement device enumeration using invoke function: PTA_CMD_GET_DEVICES provided by pseudo TA to fetch array of device UUIDs. Also register these enumerated devices with TEE bus as "optee-clntX" device. Signed-off-by: Sumit Garg --- drivers/tee/optee/Makefile | 1 + drivers/tee/optee/core.c | 4 + drivers/tee/optee/device.c | 153 ++++++++++++++++++++++++++++++++++++++ drivers/tee/optee/optee_private.h | 3 + 4 files changed, 161 insertions(+) create mode 100644 drivers/tee/optee/device.c diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile index 48d262a..56263ae 100644 --- a/drivers/tee/optee/Makefile +++ b/drivers/tee/optee/Makefile @@ -5,3 +5,4 @@ optee-objs += call.o optee-objs += rpc.o optee-objs += supp.o optee-objs += shm_pool.o +optee-objs += device.o diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index e5efce3..ac59c77 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -634,6 +634,10 @@ static struct optee *optee_probe(struct device_node *np) if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM) pr_info("dynamic shared memory is enabled\n"); + rc = optee_enumerate_devices(); + if (rc) + goto err; + pr_info("initialized driver\n"); return optee; err: diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c new file mode 100644 index 0000000..987e552 --- /dev/null +++ b/drivers/tee/optee/device.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 Linaro Ltd. + */ + +#include +#include +#include +#include +#include "optee_private.h" + +/* + * Get device UUIDs + * + * [out] memref[0] Array of device UUIDs + * + * Return codes: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + * TEE_ERROR_SHORT_BUFFER - Output buffer size less than required + */ +#define PTA_CMD_GET_DEVICES 0x0 + +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) +{ + if (ver->impl_id == TEE_IMPL_ID_OPTEE) + return 1; + else + return 0; +} + +static int get_devices(struct tee_context *ctx, u32 session, + struct tee_shm *device_shm, u32 *shm_size) +{ + u32 ret = 0; + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[4] = {0}; + + /* Invoke PTA_CMD_GET_DEVICES function */ + inv_arg.func = PTA_CMD_GET_DEVICES; + inv_arg.session = session; + inv_arg.num_params = 4; + + /* Fill invoke cmd params */ + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + param[0].u.memref.shm = device_shm; + param[0].u.memref.size = *shm_size; + param[0].u.memref.shm_offs = 0; + + ret = tee_client_invoke_func(ctx, &inv_arg, param); + if ((ret < 0) || ((inv_arg.ret != TEEC_SUCCESS) && + (inv_arg.ret != TEEC_ERROR_SHORT_BUFFER))) { + pr_err("PTA_CMD_GET_DEVICES invoke function err: %x\n", + inv_arg.ret); + return -EINVAL; + } + + *shm_size = param[0].u.memref.size; + + return 0; +} + +static int optee_register_device(const uuid_t *device_uuid, u32 device_id) +{ + struct tee_client_device *optee_device = NULL; + int rc; + + optee_device = kzalloc(sizeof(*optee_device), GFP_KERNEL); + if (!optee_device) + return -ENOMEM; + + optee_device->dev.bus = &tee_bus_type; + dev_set_name(&optee_device->dev, "optee-clnt%u", device_id); + uuid_copy(&optee_device->id.uuid, device_uuid); + + rc = device_register(&optee_device->dev); + if (rc) { + pr_err("device registration failed, err: %d\n", rc); + kfree(optee_device); + } + + return rc; +} + +int optee_enumerate_devices(void) +{ + const uuid_t pta_uuid = + UUID_INIT(0x7011a688, 0xddde, 0x4053, + 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8); + struct tee_ioctl_open_session_arg sess_arg = {0}; + struct tee_shm *device_shm = NULL; + const uuid_t *device_uuid = NULL; + struct tee_context *ctx = NULL; + u32 shm_size = 0, idx, num_devices = 0; + int rc; + + /* Open context with OP-TEE driver */ + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); + if (IS_ERR(ctx)) + return -ENODEV; + + /* Open session with device enumeration pseudo TA */ + memcpy(sess_arg.uuid, pta_uuid.b, TEE_IOCTL_UUID_LEN); + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; + sess_arg.num_params = 0; + + rc = tee_client_open_session(ctx, &sess_arg, NULL); + if ((rc < 0) || (sess_arg.ret != TEEC_SUCCESS)) { + /* Device enumeration pseudo TA not found */ + rc = 0; + goto out_ctx; + } + + rc = get_devices(ctx, sess_arg.session, NULL, &shm_size); + if (rc < 0) + goto out_sess; + + device_shm = tee_shm_alloc(ctx, shm_size, + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); + if (IS_ERR(device_shm)) { + pr_err("tee_shm_alloc failed\n"); + rc = PTR_ERR(device_shm); + goto out_sess; + } + + rc = get_devices(ctx, sess_arg.session, device_shm, &shm_size); + if (rc < 0) + goto out_shm; + + device_uuid = tee_shm_get_va(device_shm, 0); + if (IS_ERR(device_uuid)) { + pr_err("tee_shm_get_va failed\n"); + rc = PTR_ERR(device_uuid); + goto out_shm; + } + + num_devices = shm_size / sizeof(uuid_t); + + for (idx = 0; idx < num_devices; idx++) { + rc = optee_register_device(&device_uuid[idx], idx); + if (rc) + goto out_shm; + } + +out_shm: + tee_shm_free(device_shm); +out_sess: + tee_client_close_session(ctx, sess_arg.session); +out_ctx: + tee_client_close_context(ctx); + + return rc; +} diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h index 35e7938..a5e84af 100644 --- a/drivers/tee/optee/optee_private.h +++ b/drivers/tee/optee/optee_private.h @@ -28,6 +28,7 @@ #define TEEC_ERROR_BAD_PARAMETERS 0xFFFF0006 #define TEEC_ERROR_COMMUNICATION 0xFFFF000E #define TEEC_ERROR_OUT_OF_MEMORY 0xFFFF000C +#define TEEC_ERROR_SHORT_BUFFER 0xFFFF0010 #define TEEC_ORIGIN_COMMS 0x00000002 @@ -181,6 +182,8 @@ void optee_free_pages_list(void *array, size_t num_entries); void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages, size_t page_offset); +int optee_enumerate_devices(void); + /* * Small helpers */ From patchwork Fri Jan 11 11:47:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Garg X-Patchwork-Id: 10757925 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 17BDE91E for ; Fri, 11 Jan 2019 11:50:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0799429263 for ; Fri, 11 Jan 2019 11:50:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EF8792987A; Fri, 11 Jan 2019 11:50:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2B5D129263 for ; Fri, 11 Jan 2019 11:50:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731819AbfAKLu3 (ORCPT ); Fri, 11 Jan 2019 06:50:29 -0500 Received: from mail-pl1-f195.google.com ([209.85.214.195]:35069 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731816AbfAKLu1 (ORCPT ); Fri, 11 Jan 2019 06:50:27 -0500 Received: by mail-pl1-f195.google.com with SMTP id p8so6682240plo.2 for ; Fri, 11 Jan 2019 03:50:26 -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; bh=+tINcixN6J6ihFsCpuV3WXH4VOjaj3uv+FEBw2ND7Y8=; b=dVwgbg6IUF2B5po1W3grzLihb3uvLuaCwxl5+YxaAFO4asPcOBEZl2Vwx8YZHLP8vT n3pgEXd6axeCANm6+JUmEeCiOOsScP5A4kUzWfki3IehNzaqCoYiRKgTwU3cr77S1tvd /hVjZ8gb2Z6JreCyk8as7wcHJ9JyVxeu/p+6k= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+tINcixN6J6ihFsCpuV3WXH4VOjaj3uv+FEBw2ND7Y8=; b=hL6hHfoq5vVgGGtpnzmzGIfjW2yFVmU/hHKYo6bxcBquW4w6/OEISWqp/lM9NU/6vM TTbM+73tvV3asM7YN9UgDAoL/yuL+Yh/TG/u6Yc0LCBLm8niBxUYoyLRqidTaUb4JZfY R4OTx3pJ8/arxscKbYXNPUfqNZqJfyRGSxjFPydXueslyZ0hG/ajP9elG8hvzEgHbGl2 M3D69QaoUWMgV1cDD7STcrzhmPvPR0NfvxMUZ3kRecy09OCE+ZJPNHTBMVWETgm3duj9 fETHTTTltNRck8B82+ppLUrxyzzNhOzS3xjboE3uii8CvhxClja7f8seuomM6R9itN8T XZCg== X-Gm-Message-State: AJcUukdbL2xgWXO4PeefIuZiiIfjvAc2PdtHdbsaa14jJQYBdF/+yzsE 4hx4o12HEQkef3pBPbedvD33OA== X-Google-Smtp-Source: ALg8bN4ZnSh6FBIFm0IUgkughYKT/cRiAWxrFHfu8o3S9cHGX0PN9SSexIS/4ny6HXYVWck5XXPuHQ== X-Received: by 2002:a17:902:8346:: with SMTP id z6mr14286294pln.340.1547207426184; Fri, 11 Jan 2019 03:50:26 -0800 (PST) Received: from localhost.localdomain ([117.196.233.251]) by smtp.gmail.com with ESMTPSA id b2sm143199988pfm.3.2019.01.11.03.50.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 11 Jan 2019 03:50:25 -0800 (PST) From: Sumit Garg To: linux-arm-kernel@lists.infradead.org, linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, jens.wiklander@linaro.org, mpm@selenic.com, herbert@gondor.apana.org.au, robh+dt@kernel.org, mark.rutland@arm.com, arnd@arndb.de, gregkh@linuxfoundation.org, daniel.thompson@linaro.org, ard.biesheuvel@linaro.org, bhsharma@redhat.com, tee-dev@lists.linaro.org, Sumit Garg Subject: [PATCH v3 4/4] hwrng: add OP-TEE based rng driver Date: Fri, 11 Jan 2019 17:17:31 +0530 Message-Id: <1547207251-9372-5-git-send-email-sumit.garg@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1547207251-9372-1-git-send-email-sumit.garg@linaro.org> References: <1547207251-9372-1-git-send-email-sumit.garg@linaro.org> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On ARM SoC's with TrustZone enabled, peripherals like entropy sources might not be accessible to normal world (linux in this case) and rather accessible to secure world (OP-TEE in this case) only. So this driver aims to provides a generic interface to OP-TEE based random number generator service. This driver registers on TEE bus to interact with OP-TEE based rng device/service. Signed-off-by: Sumit Garg --- MAINTAINERS | 5 + drivers/char/hw_random/Kconfig | 15 ++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/optee-rng.c | 272 +++++++++++++++++++++++++++++++++++++ 4 files changed, 293 insertions(+) create mode 100644 drivers/char/hw_random/optee-rng.c diff --git a/MAINTAINERS b/MAINTAINERS index 32d44447..502733c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11260,6 +11260,11 @@ M: Jens Wiklander S: Maintained F: drivers/tee/optee/ +OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER +M: Sumit Garg +S: Maintained +F: drivers/char/hw_random/optee-rng.c + OPA-VNIC DRIVER M: Dennis Dalessandro M: Niranjana Vishwanathapura diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index dac895d..25a7d8f 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -424,6 +424,21 @@ config HW_RANDOM_EXYNOS will be called exynos-trng. If unsure, say Y. + +config HW_RANDOM_OPTEE + tristate "OP-TEE based Random Number Generator support" + depends on OPTEE + default HW_RANDOM + help + This driver provides support for OP-TEE based Random Number + Generator on ARM SoCs where hardware entropy sources are not + accessible to normal world (Linux). + + To compile this driver as a module, choose M here: the module + will be called optee-rng. + + If unsure, say Y. + endif # HW_RANDOM config UML_RANDOM diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index e35ec3c..7c9ef4a 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o +obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o diff --git a/drivers/char/hw_random/optee-rng.c b/drivers/char/hw_random/optee-rng.c new file mode 100644 index 0000000..24f7435 --- /dev/null +++ b/drivers/char/hw_random/optee-rng.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018-2019 Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "optee-rng" + +#define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 + +/* + * TA_CMD_GET_ENTROPY - Get Entropy from RNG + * + * param[0] (inout memref) - Entropy buffer memory reference + * param[1] unused + * param[2] unused + * param[3] unused + * + * Result: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + * TEE_ERROR_NOT_SUPPORTED - Requested entropy size greater than size of pool + * TEE_ERROR_HEALTH_TEST_FAIL - Continuous health testing failed + */ +#define TA_CMD_GET_ENTROPY 0x0 + +/* + * TA_CMD_GET_RNG_INFO - Get RNG information + * + * param[0] (out value) - value.a: RNG data-rate in bytes per second + * value.b: Quality/Entropy per 1024 bit of data + * param[1] unused + * param[2] unused + * param[3] unused + * + * Result: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + */ +#define TA_CMD_GET_RNG_INFO 0x1 + +#define MAX_ENTROPY_REQ_SZ (4 * 1024) + +static struct tee_context *ctx; +static struct tee_shm *entropy_shm_pool; +static u32 ta_rng_data_rate; +static u32 ta_rng_session_id; + +static size_t get_optee_rng_data(void *buf, size_t req_size) +{ + u32 ret = 0; + u8 *rng_data = NULL; + size_t rng_size = 0; + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[4] = {0}; + + /* Invoke TA_CMD_GET_ENTROPY function of Trusted App */ + inv_arg.func = TA_CMD_GET_ENTROPY; + inv_arg.session = ta_rng_session_id; + inv_arg.num_params = 4; + + /* Fill invoke cmd params */ + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; + param[0].u.memref.shm = entropy_shm_pool; + param[0].u.memref.size = req_size; + param[0].u.memref.shm_offs = 0; + + ret = tee_client_invoke_func(ctx, &inv_arg, param); + if ((ret < 0) || (inv_arg.ret != 0)) { + pr_err("TA_CMD_GET_ENTROPY invoke function error: %x\n", + inv_arg.ret); + return 0; + } + + rng_data = tee_shm_get_va(entropy_shm_pool, 0); + if (IS_ERR(rng_data)) { + pr_err("tee_shm_get_va failed\n"); + return 0; + } + + rng_size = param[0].u.memref.size; + memcpy(buf, rng_data, rng_size); + + return rng_size; +} + +static int optee_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + u8 *data = buf; + size_t read = 0, rng_size = 0; + int timeout = 1; + + if (max > MAX_ENTROPY_REQ_SZ) + max = MAX_ENTROPY_REQ_SZ; + + while (read == 0) { + rng_size = get_optee_rng_data(data, (max - read)); + + data += rng_size; + read += rng_size; + + if (wait) { + if (timeout-- == 0) + return read; + msleep((1000 * (max - read)) / ta_rng_data_rate); + } else { + return read; + } + } + + return read; +} + +static int optee_rng_init(struct hwrng *rng) +{ + entropy_shm_pool = tee_shm_alloc(ctx, MAX_ENTROPY_REQ_SZ, + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); + if (IS_ERR(entropy_shm_pool)) { + pr_err("tee_shm_alloc failed\n"); + return PTR_ERR(entropy_shm_pool); + } + + return 0; +} + +static void optee_rng_cleanup(struct hwrng *rng) +{ + tee_shm_free(entropy_shm_pool); +} + +static struct hwrng optee_rng = { + .name = DRIVER_NAME, + .init = optee_rng_init, + .cleanup = optee_rng_cleanup, + .read = optee_rng_read, +}; + +static int get_optee_rng_info(struct device *dev) +{ + u32 ret = 0; + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[4] = {0}; + + /* Invoke TA_CMD_GET_RNG_INFO function of Trusted App */ + inv_arg.func = TA_CMD_GET_RNG_INFO; + inv_arg.session = ta_rng_session_id; + inv_arg.num_params = 4; + + /* Fill invoke cmd params */ + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; + + ret = tee_client_invoke_func(ctx, &inv_arg, param); + if ((ret < 0) || (inv_arg.ret != 0)) { + dev_err(dev, "TA_CMD_GET_RNG_INFO invoke func error: %x\n", + inv_arg.ret); + return -EINVAL; + } + + ta_rng_data_rate = param[0].u.value.a; + optee_rng.quality = param[0].u.value.b; + + return 0; +} + +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) +{ + if (ver->impl_id == TEE_IMPL_ID_OPTEE) + return 1; + else + return 0; +} + +static int optee_rng_probe(struct device *dev) +{ + struct tee_client_device *rng_device = to_tee_client_device(dev); + int ret = 0, err = -ENODEV; + struct tee_ioctl_open_session_arg sess_arg = {0}; + + /* Open context with TEE driver */ + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); + if (IS_ERR(ctx)) + return -ENODEV; + + /* Open session with hwrng Trusted App */ + memcpy(sess_arg.uuid, rng_device->id.uuid.b, TEE_IOCTL_UUID_LEN); + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; + sess_arg.num_params = 0; + + ret = tee_client_open_session(ctx, &sess_arg, NULL); + if ((ret < 0) || (sess_arg.ret != 0)) { + dev_err(dev, "tee_client_open_session failed, error: %x\n", + sess_arg.ret); + err = -EINVAL; + goto out_ctx; + } + ta_rng_session_id = sess_arg.session; + + err = get_optee_rng_info(dev); + if (err) + goto out_sess; + + err = hwrng_register(&optee_rng); + if (err) { + dev_err(dev, "hwrng registration failed (%d)\n", err); + goto out_sess; + } + + return 0; + +out_sess: + tee_client_close_session(ctx, ta_rng_session_id); +out_ctx: + tee_client_close_context(ctx); + + return err; +} + +static int optee_rng_remove(struct device *dev) +{ + tee_client_close_session(ctx, ta_rng_session_id); + tee_client_close_context(ctx); + hwrng_unregister(&optee_rng); + + return 0; +} + +const struct tee_client_device_id optee_rng_id_table[] = { + {UUID_INIT(0xab7a617c, 0xb8e7, 0x4d8f, + 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64)}, + {} +}; + +static struct tee_client_driver optee_rng_driver = { + .id_table = optee_rng_id_table, + .driver = { + .name = DRIVER_NAME, + .bus = &tee_bus_type, + .probe = optee_rng_probe, + .remove = optee_rng_remove, + }, +}; + +static int __init optee_rng_mod_init(void) +{ + int rc; + + rc = driver_register(&optee_rng_driver.driver); + if (rc) + pr_warn("driver registration failed, err: %d", rc); + + return rc; +} + +static void __exit optee_rng_mod_exit(void) +{ + driver_unregister(&optee_rng_driver.driver); +} + +module_init(optee_rng_mod_init); +module_exit(optee_rng_mod_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sumit Garg "); +MODULE_DESCRIPTION("OP-TEE based random number generator driver");