From patchwork Mon Jul 17 14:44:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 9845351 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 753496037F for ; Mon, 17 Jul 2017 14:45:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 654E922A68 for ; Mon, 17 Jul 2017 14:45:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5A05B22B27; Mon, 17 Jul 2017 14:45:13 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B081722A68 for ; Mon, 17 Jul 2017 14:45:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=BmyKBlGdTyzG9Ek9cWRlAK5yihk/lGSUPfHdd9geGq4=; b=HI4 HTlJa9M3EIHl4jka0TiudVvRVTiQEnUPY86bLiiLUeZj/ezrmlWJPxgwV0sKygMOX3sumEyPCji4x qUoI64aDVjLxrlYAXhyLrq6wVoe1hemTIi8UGARlvontlJavEQEDyegtUcYMSWkbIhseKq6bsPw5l rxeit9WseZDfLlO1mlHkBoBblAgmtHp3zCUnkAuUdcefdRXxOT/R5hz8DCL1b0VdKzyc8jiW2uYJ7 43cIZCcX56U8kjpnZ54HsXFXH/JFebohnk/swXLrlxivMvWN7nuyTbZjzB2VTKhA5FVCgxwiswiax KeQzDPdLnAWlmGOkJwr8SpLAcaUQPcQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dX7Go-00065X-5I; Mon, 17 Jul 2017 14:45:10 +0000 Received: from mail-lf0-x234.google.com ([2a00:1450:4010:c07::234]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dX7Gf-0004pl-1D for linux-arm-kernel@lists.infradead.org; Mon, 17 Jul 2017 14:45:08 +0000 Received: by mail-lf0-x234.google.com with SMTP id w198so19326138lff.2 for ; Mon, 17 Jul 2017 07:44:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=3ecR2M7k4JAmF+Btj+eB3MElXwjeWbV4qSSkCo3S6eM=; b=PyD9HDpJBQM42E7+usk6bK62mJM2qUrKuUkf6/OQdJLi1nG5VE3uEmQiKbJKTfv+BS LymCjllrvRb8whprZz55XZ2O0Ky2hbEHFBHKQrAv0pUx9+GxYHE8eOlvwkbldLmGCiBq XwdBu+6scnk1+ugvXn4gjSTSfRgaek+iOCEvI= 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; bh=3ecR2M7k4JAmF+Btj+eB3MElXwjeWbV4qSSkCo3S6eM=; b=euOzzoDF5dqxOjMoWn9bZZrUqd2FWM7jbioFQyUXTt5s69RXjOB+YUduUFo844av+w aA1PM2pi4lWEhf4TbHLeJCzKhY7SYadQKg34GjanmOI6aqnzvHVCE0HzV+oXSBafUnqN 0kuTMafR63CPPkT71Vp6GGtRZDu7sD4ykINLGTsvpvzCLL046NMX/QCVSwieDLHTgySs D4t0Ph1fPzdvYYM1pkQsNuMUKR6xwpJgdnbimNjc2YMI+L2x7ImOA67jZ4cq8J4OykHx U4r1zCbkZJgRhXrQT0WTUsN4mULXx9oZqKMMT8kUaTb/+BWHlZ7EMwR+WMdNUCgv1XOh V3Og== X-Gm-Message-State: AIVw11030ciFZqjzn8mIuHgn9jWPK3sdKOKhoOltMCFwi6p8AidWkxEo 0tQaEpPvGbQXdjEu X-Received: by 10.46.7.80 with SMTP id i16mr4849575ljd.1.1500302678911; Mon, 17 Jul 2017 07:44:38 -0700 (PDT) Received: from jax.urgonet (h-84-45.A175.priv.bahnhof.se. [79.136.84.45]) by smtp.gmail.com with ESMTPSA id e8sm3907697ljb.58.2017.07.17.07.44.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 17 Jul 2017 07:44:38 -0700 (PDT) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, tee-dev@lists.linaro.org Subject: [PATCH] tee: add kernel internal client interface Date: Mon, 17 Jul 2017 16:44:15 +0200 Message-Id: <1500302655-4909-1-git-send-email-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.7.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170717_074501_265323_4C9AC1D1 X-CRM114-Status: GOOD ( 16.33 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: acarb95@cs.ubc.ca, Jens Wiklander MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Adds a kernel internal TEE client interface to be used by other drivers. Signed-off-by: Jens Wiklander --- drivers/tee/tee_core.c | 124 +++++++++++++++++++++++++++++++++++++++++++----- include/linux/tee_drv.h | 73 ++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+), 11 deletions(-) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 58a5009eacc3..bcc39e263bdd 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -38,15 +38,13 @@ static DEFINE_SPINLOCK(driver_lock); static struct class *tee_class; static dev_t tee_devt; -static int tee_open(struct inode *inode, struct file *filp) +static struct tee_context *teedev_open(struct tee_device *teedev) { int rc; - struct tee_device *teedev; struct tee_context *ctx; - teedev = container_of(inode->i_cdev, struct tee_device, cdev); if (!tee_device_get(teedev)) - return -EINVAL; + return ERR_PTR(-EINVAL); ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) { @@ -56,22 +54,20 @@ static int tee_open(struct inode *inode, struct file *filp) ctx->teedev = teedev; INIT_LIST_HEAD(&ctx->list_shm); - filp->private_data = ctx; rc = teedev->desc->ops->open(ctx); if (rc) goto err; - return 0; + return ctx; err: kfree(ctx); tee_device_put(teedev); - return rc; + return ERR_PTR(rc); + } -static int tee_release(struct inode *inode, struct file *filp) +static void teedev_close_context(struct tee_context *ctx) { - struct tee_context *ctx = filp->private_data; - struct tee_device *teedev = ctx->teedev; struct tee_shm *shm; ctx->teedev->desc->ops->release(ctx); @@ -79,8 +75,25 @@ static int tee_release(struct inode *inode, struct file *filp) list_for_each_entry(shm, &ctx->list_shm, link) shm->ctx = NULL; mutex_unlock(&ctx->teedev->mutex); + tee_device_put(ctx->teedev); kfree(ctx); - tee_device_put(teedev); +} + +static int tee_open(struct inode *inode, struct file *filp) +{ + struct tee_context *ctx; + + ctx = teedev_open(container_of(inode->i_cdev, struct tee_device, cdev)); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + filp->private_data = ctx; + return 0; +} + +static int tee_release(struct inode *inode, struct file *filp) +{ + teedev_close_context(filp->private_data); return 0; } @@ -862,6 +875,95 @@ void *tee_get_drvdata(struct tee_device *teedev) } EXPORT_SYMBOL_GPL(tee_get_drvdata); +struct match_dev_data { + struct tee_ioctl_version_data *vers; + const void *data; + int (*match)(struct tee_ioctl_version_data *, const void *); +}; + +static int match_dev(struct device *dev, const void *data) +{ + const struct match_dev_data *match_data = data; + struct tee_device *teedev = container_of(dev, struct tee_device, dev); + + teedev->desc->ops->get_version(teedev, match_data->vers); + return match_data->match(match_data->vers, match_data->data); +} + +struct tee_context * +tee_client_open_context(struct tee_context *start, + int (*match)(struct tee_ioctl_version_data *, + const void *), + const void *data, struct tee_ioctl_version_data *vers) +{ + struct device *dev = NULL; + struct device *put_dev = NULL; + struct tee_context *ctx = NULL; + struct tee_ioctl_version_data v; + struct match_dev_data match_data = { vers ? vers : &v, data, match }; + + if (start) + dev = &start->teedev->dev; + + do { + dev = class_find_device(tee_class, dev, &match_data, match_dev); + if (!dev) { + ctx = ERR_PTR(-ENOENT); + break; + } + + put_device(put_dev); + put_dev = dev; + + ctx = teedev_open(container_of(dev, struct tee_device, dev)); + } while (IS_ERR(ctx) && PTR_ERR(ctx) != -ENOMEM); + + put_device(put_dev); + return ctx; +} +EXPORT_SYMBOL_GPL(tee_client_open_context); + +void tee_client_close_context(struct tee_context *ctx) +{ + teedev_close_context(ctx); +} +EXPORT_SYMBOL_GPL(tee_client_close_context); + +void tee_client_get_version(struct tee_context *ctx, + struct tee_ioctl_version_data *vers) +{ + ctx->teedev->desc->ops->get_version(ctx->teedev, vers); +} +EXPORT_SYMBOL_GPL(tee_client_get_version); + +int tee_client_open_session(struct tee_context *ctx, + struct tee_ioctl_open_session_arg *arg, + struct tee_param *param) +{ + if (!ctx->teedev->desc->ops->open_session) + return -EINVAL; + return ctx->teedev->desc->ops->open_session(ctx, arg, param); +} +EXPORT_SYMBOL_GPL(tee_client_open_session); + +int tee_client_close_session(struct tee_context *ctx, u32 session) +{ + if (!ctx->teedev->desc->ops->close_session) + return -EINVAL; + return ctx->teedev->desc->ops->close_session(ctx, session); +} +EXPORT_SYMBOL_GPL(tee_client_close_session); + +int tee_client_invoke_func(struct tee_context *ctx, + struct tee_ioctl_invoke_arg *arg, + struct tee_param *param) +{ + if (!ctx->teedev->desc->ops->invoke_func) + return -EINVAL; + return ctx->teedev->desc->ops->invoke_func(ctx, arg, param); +} +EXPORT_SYMBOL_GPL(tee_client_invoke_func); + static int __init tee_init(void) { int rc; diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index 0f175b8f6456..39440c7c7558 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -274,4 +274,77 @@ int tee_shm_get_id(struct tee_shm *shm); */ struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id); +/** + * tee_client_open_context() - Open a TEE context + * @start: if not NULL, continue search after this context + * @match: function to check TEE device + * @data: data for match function + * @vers: if not NULL, version data of TEE device of the context returned + * + * This function does an operation similar to open("/dev/teeX") in user space. + * A returned context must be released with tee_client_close_context(). + * + * Returns a TEE context of the first TEE device matched by the match() + * callback or an ERR_PTR. + */ +struct tee_context * +tee_client_open_context(struct tee_context *start, + int (*match)(struct tee_ioctl_version_data *, + const void *), + const void *data, struct tee_ioctl_version_data *vers); + +/** + * tee_client_close_context() - Close a TEE context + * @ctx: TEE context to close + * + * Note that all sessions previously opened with this context will be + * closed when this function is called. + */ +void tee_client_close_context(struct tee_context *ctx); + +/** + * tee_client_get_version() - Query version of TEE + * @ctx: TEE context to TEE to query + * @vers: Pointer to version data + */ +void tee_client_get_version(struct tee_context *ctx, + struct tee_ioctl_version_data *vers); + +/** + * tee_client_open_session() - Open a session to a Trusted Application + * @ctx: TEE context + * @arg: Open session arguments, see description of + * struct tee_ioctl_open_session_arg + * @param: Parameters passed to the Trusted Application + * + * Returns < 0 on error else see @arg->ret for result. If @arg->ret + * is TEEC_SUCCESS the session identifier is available in @arg->session. + */ +int tee_client_open_session(struct tee_context *ctx, + struct tee_ioctl_open_session_arg *arg, + struct tee_param *param); + +/** + * tee_client_close_session() - Close a session to a Trusted Application + * @ctx: TEE Context + * @session: Session id + * + * Return < 0 on error else 0, regardless the session will not be + * valid after this function has returned. + */ +int tee_client_close_session(struct tee_context *ctx, u32 session); + +/** + * tee_client_invoke_func() - Invoke a function in a Trusted Application + * @ctx: TEE Context + * @arg: Invoke arguments, see description of + * struct tee_ioctl_invoke_arg + * @param: Parameters passed to the Trusted Application + * + * Returns < 0 on error else see @arg->ret for result. + */ +int tee_client_invoke_func(struct tee_context *ctx, + struct tee_ioctl_invoke_arg *arg, + struct tee_param *param); + #endif /*__TEE_DRV_H*/