From patchwork Mon Jul 9 06:15:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Wiklander X-Patchwork-Id: 10513611 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 CE2536032A for ; Mon, 9 Jul 2018 06:16:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B9D8C289B2 for ; Mon, 9 Jul 2018 06:16:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ADAF328A15; Mon, 9 Jul 2018 06:16:19 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.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 2DE0128A20 for ; Mon, 9 Jul 2018 06:16:19 +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=Fo8shVTU6H5tnolzWVyUSAeOpRqE9qAwVCfNVCRQtmQ=; b=WQi M047RBDbwXhH/JFGzAR8Q6LtSwVcS1BR2avkUa+/rdBLDoykPlSWCWDBdxG1fXHqDJd2K1pLWwTUm ecDtYDje/c6DZdLt2Bz6QNrbixMZYHmI0Z9+ji+1+2N+5HhdRl10s+9ExtodD8/hAgk3xDX8GRukv b5UtiWatdqmVq90SUbeZPBFeLp2tgTc9D29reaelGfiDVLI/GHU44Ttdw5Kp3RrHaVPZW4YNN9vOy 1mqfmbXuCodYbqKGOKrG9bcgnBmqrz5hbf9+ut7NzyiS+SLPm+29yVWzkypMys4Sxe1d/wF+4oy7s 7rIsm28pkTWAgH38uPcMbsX9LSQgbJA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fcPT4-0006qL-QA; Mon, 09 Jul 2018 06:16:14 +0000 Received: from mail-lf0-x243.google.com ([2a00:1450:4010:c07::243]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fcPT1-0006oe-2I for linux-arm-kernel@lists.infradead.org; Mon, 09 Jul 2018 06:16:12 +0000 Received: by mail-lf0-x243.google.com with SMTP id l16-v6so14220898lfc.13 for ; Sun, 08 Jul 2018 23:16:00 -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=VUswySRldL/9ULe/QmdY25JftCKNFqT6wOZCs5KsqEg=; b=f7476Sm+oIkIiNX1tPSyoYHsRcaSUDxbnI1VQ9pFcUOW7wcI4Wu2s5MvbGT4e2fZau YMFmtw76brrDB0TKpK3IAQj6YhV8hKjdycX2JZsocO98Cc4NVMD0j//SlSUVZbqHnoQk HWqiELfJar1BmivUnMeuUUk0qIjst/ZaV+AUo= 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=VUswySRldL/9ULe/QmdY25JftCKNFqT6wOZCs5KsqEg=; b=S4llIqH+6neMzZtoJSKdW4PgVf/l5sciKP9BQkQ0fjSf+2ZYBD4ZFEdk3qqpN0o96t gsxl98wmFwS8e8nozoH0kPbiZIBKNAr1tl0ID7SXZxrpz+hqzXB7ssuNtsfGl1lypAt9 rr7iJK0xADZ/8NdEGsX60vm7NEITuOfwpclNs/eDxp2YpSWGYt1iW971daeOk6sVp73C Suyri0Wjx2735ntlPnKCrnZl94BH9jk+g3mXX1UFCdnbgTf7yIhBMlZwo9xxeIrgvwXx 2Jr8KZLi2p5ZWGL8XHAdVM9lIdN1GYmP4gMljszxQEge/EI+D9p4lP1SA0VR353GHcVf 0eEw== X-Gm-Message-State: APt69E1Im64Gt8toX9mPMK7YkngVm/jWvzxNsWdIlyLMHL4HmT54r1/6 tG23HcvR0ZmCTVCTkGex8ciMfQ== X-Google-Smtp-Source: AAOMgpdlC56fSqZ9np/0+4vEB54HfEGh5UGqIh7OmUlIK1EZE6ZLT3x6fplV3NHNbIfVsw8rt4L7WQ== X-Received: by 2002:a19:6b03:: with SMTP id d3-v6mr12790273lfa.81.1531116958814; Sun, 08 Jul 2018 23:15:58 -0700 (PDT) Received: from jax.urgonet (h-84-45.A175.priv.bahnhof.se. [79.136.84.45]) by smtp.gmail.com with ESMTPSA id x129-v6sm1610521lff.19.2018.07.08.23.15.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 08 Jul 2018 23:15:58 -0700 (PDT) From: Jens Wiklander To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, tee-dev@lists.linaro.org Subject: [RESEND PATCH] tee: add kernel internal client interface Date: Mon, 9 Jul 2018 08:15:49 +0200 Message-Id: <20180709061549.24382-1-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.17.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180708_231611_113882_B5C06A76 X-CRM114-Status: GOOD ( 16.52 ) 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: Jerome Forissier , Zeng Tao , 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 Reviewed-by: Sumit Garg Tested-by: Sumit Garg Tested-by: Zeng Tao --- drivers/tee/tee_core.c | 113 +++++++++++++++++++++++++++++++++++++--- include/linux/tee_drv.h | 73 ++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 7 deletions(-) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index dd46b758852a..7b2bb4c50058 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) { @@ -57,16 +55,16 @@ static int tee_open(struct inode *inode, struct file *filp) kref_init(&ctx->refcount); 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); + } void teedev_ctx_get(struct tee_context *ctx) @@ -100,6 +98,18 @@ static void teedev_close_context(struct tee_context *ctx) teedev_ctx_put(ctx); } +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); @@ -928,6 +938,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 a2b3dfcee0b5..6cfe05893a76 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -453,6 +453,79 @@ static inline 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); + static inline bool tee_param_is_memref(struct tee_param *param) { switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {