Received: by 10.223.164.202 with SMTP id h10csp4400050wrb; Wed, 29 Nov 2017 05:54:53 -0800 (PST) X-Google-Smtp-Source: AGs4zMZuZoscmpEZ9bA0bGw+MTi8LwkKhJqvhJEEB0VlcdcfPQA/kqrrREU3aQzYgtvrE/b0p/oK X-Received: by 10.84.241.5 with SMTP id a5mr3055143pll.128.1511963693220; Wed, 29 Nov 2017 05:54:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511963693; cv=none; d=google.com; s=arc-20160816; b=Dt49gPQCUdOPgnDoXHl7nsn1WSU9NwIBTVvA2IRQ6OxH0GIyZuLI484KZIAS559rHM AtLxJGFYcNG4ULd7grfxa1YoJmsM3fVYxBFjHERVa1mqHq5dNp7kmCsnyYlNqqAuCCuk R+alWS+SLvhubhIJbZdKY2AkUxGolXyxS2VVh4+4R4SXbFQsO2FjvhTYxdcwilzhnRDT +b/yJbNj9qxVOQEs4P/J5B6juXsqMBo/r2R/dq5YFh8aWb7IVHZ1tL8DBl4F3P3JnXqm 250DWhkihiQpsFVWYmCmaYRXYMg7Z4g/DEmJX5TV5RX1zlkxZ4wkuAWYoBinAghG3tVF RDbA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:spamdiagnosticmetadata :spamdiagnosticoutput:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature:arc-authentication-results; bh=HG6Npjpz8VGKckh50V95sX5qSc0nk7FH2d8YRLD8g4U=; b=hhOm+x5rcf3kfjGpMENXdIAjTjSTLC/BJiWnm2vWGfcRR8ZLlAegV/GmIxRReFWqoB eXw5VdFKzuLcytCiPqUdEeagwer3iosYP9a3FN8U5d79xrGyYXnCyCeCMeYgVcmPu59O dikBhgYPBPkzRqGjpjA8MhfALljdevIqXhfO0tMioVLImMBx7L2Jy6enXSdTyggw2I+w zpTgOVOK5fxhCmpkhjeITpIPGahqt9m6nGCfGEmDHkbMtTZrhEAHOs8q6H13c4XLOz7h B+nH3vCsn406LVwG0WiER5c/aiemkyGOH0RttvKPg67Z3VTGmCN6EA4x9v1TQyoUTpqQ kpXQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@epam.com header.s=selector1 header.b=aXUz5hvB; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n61si1304520plb.221.2017.11.29.05.54.42; Wed, 29 Nov 2017 05:54:53 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@epam.com header.s=selector1 header.b=aXUz5hvB; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752771AbdK2Mw0 (ORCPT + 70 others); Wed, 29 Nov 2017 07:52:26 -0500 Received: from mail-he1eur01on0068.outbound.protection.outlook.com ([104.47.0.68]:36480 "EHLO EUR01-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754811AbdK2MtF (ORCPT ); Wed, 29 Nov 2017 07:49:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=epam.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=HG6Npjpz8VGKckh50V95sX5qSc0nk7FH2d8YRLD8g4U=; b=aXUz5hvBuI38p0XFciicukf/IM+nQkiPILmDKg1YeVScTq8Pv/h+mCn7XkqFoD166BpiOdooVeI0CdXhX29AF/fv2g6A5cp4OjVN58dsmLEj/uoedXnwegvobyTdFqYUyK1+r/Ae+wvOYlaK/Vl6rg+zr7owtGNqGm2Uw5+6mOo= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Volodymyr_Babchuk@epam.com; Received: from EPUAKYIW2556.kyiv.epam.com (85.223.209.56) by AM4PR03MB1763.eurprd03.prod.outlook.com (2603:10a6:200:10::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.282.5; Wed, 29 Nov 2017 12:49:00 +0000 Received: by EPUAKYIW2556.kyiv.epam.com (sSMTP sendmail emulation); Wed, 29 Nov 2017 14:48:56 +0200 From: Volodymyr Babchuk To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, tee-dev@lists.linaro.org, Jens Wiklander Cc: volodymyr_babchuk@epam.com, Volodymyr Babchuk Subject: [RESEND PATCH v2 02/14] tee: add register user memory Date: Wed, 29 Nov 2017 14:48:26 +0200 Message-Id: <1511959718-5421-3-git-send-email-volodymyr_babchuk@epam.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1511959718-5421-1-git-send-email-volodymyr_babchuk@epam.com> References: <1507923164-12796-1-git-send-email-volodymyr_babchuk@epam.com> <1511959718-5421-1-git-send-email-volodymyr_babchuk@epam.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [85.223.209.56] X-ClientProxiedBy: HE1PR0402CA0031.eurprd04.prod.outlook.com (2603:10a6:7:7c::20) To AM4PR03MB1763.eurprd03.prod.outlook.com (2603:10a6:200:10::7) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: f7ed1941-8daa-4c91-8de9-08d5372790b8 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(5600026)(4604075)(4534020)(4602075)(7168020)(4627115)(201703031133081)(201702281549075)(2017052603199);SRVR:AM4PR03MB1763; X-Microsoft-Exchange-Diagnostics: 1;AM4PR03MB1763;3:3YAhU/P5MWgHyfMNekz4JQi/DqERwSU48SQVOrKbfMGk8K5+quYLezkguPRbNIv3mHOMUtRTQYlMy1Ye6yF0Ciw58Z845Bt9L3gaV8/G0eZRcpCu+LI8nDkxBK6oBmkL6widEjt947myhQgvh/BjiZy14Y5mjFOA8rIhn57Ax1w5ZJxs0ocEMuS8DDjs4gixS6uWEsqaUnlb+G1643kV0RzkZM0wUEUJAbwow25RdZMSXnyHKqv9Bl9escSn/qgz;25:LxM2rvMZ6Qg+fGFNAE/XxNRGi/8+m8zr9jKNGiSCubqcquJVrr1piVmXV1HZtXVeXWt7eA27QdG+Lxgq5r5baTNM2KCpGvHhkl3Y/rJFAAagcY1N+U8IduZOdf7ZyjbGKx5xrSLG/O6gVIhbXELlkIciwzpvJd9Kwe6FHV7/JIyHWBqk1k+/d+W3y9qj6BUfs94uoU/KOvSrQngt6ricKW9PIBDM6P0vTPN/PfGmy/GwBKw+vi3etx6TLPQdrnUPBfmAbYvUB+Vzkhwgi62oev+UbkDBLdcKC5vvgc3ooahKyiK4ND7ry1ZuWaHaZm14V/P9yolh2SSZ3kgbNRrmiQ==;31:C5c2tfB7iljeudRVxwixr2b/4A0XRerzk/UjE8H8bmSDAL33f78c3457BuUGilSfSxmKjMp/DQAXcrOq1MHFSo2sHHrUMRXFUxPv9q7faXonDg9IMXHYQ8jtzWkq2tb47wCvTn6T2Ar9M412l5HAUKpnsR/rO9/OEd2iSPoAXcUe5Aa+022sX8y5722kGPg9OI3QsEDk4q3XTDaRVMHe66RMIBRUwlHLpurGE5uOi+s= X-MS-TrafficTypeDiagnostic: AM4PR03MB1763: X-Microsoft-Exchange-Diagnostics: 1;AM4PR03MB1763;20:fev5xWYRdfVkPVEQ64rCfsxUCFf/vJgPXr2a7hlnSUed37SF3y98X71kraV05XzCgkdLfloMltocTj0XiFcvExFZGkJc5Rxj0Gj09ZpJyAAsNxWhNYitJr7NTh/0uDR4muAsomV96SL23ewrjQvmoREEHzJNFcoRewRXHskEAg8NL6F9Y02lW4IjpMw4/1PeM7QlKdBoiu9gacK6BFZJFmwGPaWoXX/pdBNupm2led06hlkc7SESi49FwE9z0WtxXhBKFZyoC1q7rDbVqkmO+4VnP2o3Ld3RYJ+iL0KAcVCyNQD+t5Qaji5ilWAZUqVpKb5FcbQyYkkSkM8XOGOWZ/MgPVDqMSzAkkQ894xC0xxtF17l0p0TcRnDRpDSZQdGFEe0HEuTAIJKjNDRUM4HT3Iyxod9+u2DpyJItvuD/IDaeLM6WHsKy7HAns05xbkDW/SVAm3K+IuTDjytT/Yx+NqBp1ZH0ufa+8MRVlhkb3G+Qzua2Yi7+WzAd1u7BnIt;4:nJo5wNEMqU/ThyDrBTC4xTIKvWQla2zwJrQQ3yghQI+iWIGGVuJ4vfXgoui37uhglGVztCHS1+06u9UA6iXmag7lZcYL7cJ7tUcggasyGZgrzKFPDH6WusovSkJ3A9hqoUuylZHAoQ5T/hR1HGxNn60D8nidRz1gwMATnp+VoKBI0NymEi0M4POo/2RskWlhAyfffg/GyTORBx2/OuJZMRoJOzacSJg/VW2XwSuhyTxbHiOM6k6nKzeIinYHq82fCG0r6T7uyJJ40mLqVwOg0w== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040450)(2401047)(8121501046)(5005006)(3231022)(3002001)(10201501046)(93006095)(93001095)(6041248)(20161123560025)(20161123564025)(20161123555025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(20161123558100)(6072148)(201708071742011);SRVR:AM4PR03MB1763;BCL:0;PCL:0;RULEID:(100000803101)(100110400095);SRVR:AM4PR03MB1763; X-Forefront-PRVS: 05066DEDBB X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(376002)(366004)(346002)(199003)(189002)(50986999)(68736007)(76176999)(97736004)(101416001)(6916009)(2950100002)(2906002)(80792005)(6666003)(6116002)(4326008)(53936002)(3846002)(316002)(81166006)(106356001)(8936002)(33646002)(81156014)(72206003)(16586007)(5660300001)(36756003)(42186006)(305945005)(478600001)(50226002)(48376002)(51416003)(7736002)(8676002)(105586002)(50466002)(66066001)(55236003)(47776003)(86362001)(52116002)(189998001)(122856001)(39060400002)(217873001);DIR:OUT;SFP:1101;SCL:1;SRVR:AM4PR03MB1763;H:EPUAKYIW2556.kyiv.epam.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; Received-SPF: None (protection.outlook.com: epam.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AM4PR03MB1763;23:mAuJkhTDmrzZLsWSw8Ap3sgUBTwrh4QXndk6XqnhE?= =?us-ascii?Q?VoTnqE4eNo1g/2oGHRT1h88f212k9tIRytiqf7ulcskf/HT97pJov5vTs2S6?= =?us-ascii?Q?fk1JR2VQxkW0C+wU2JE9Hf0SMkLCYNPmOw8xeewoSBVDEhfq3e+yLXwSczIy?= =?us-ascii?Q?/3FsbAKolm4fq1Gvcm65A11UQ2i3f1QgvUNwIHQXnUaqMi4qDA0TaAMuHi4O?= =?us-ascii?Q?O4vFdv/HFoalP8rblckNb/gABq8Mfk9QZTaiPS85Kp2ng33LX9P7WZTbFrPH?= =?us-ascii?Q?haUGsdZX4YCMJexc91qTPvmDks+l6ysIn97ckQ1WFLuG3OFDePcRAwigivgD?= =?us-ascii?Q?cIAuEd/M1YwEMW7c85JSJwBANLgvpCs4Ky1irYlNJ3OJvodC5tMvazvXyehf?= =?us-ascii?Q?VQyHczIEM1z0/nTtKpp9wRMYg8oV3CVKzehF46IMZSNjielz1vp4xtxbKrxO?= =?us-ascii?Q?9QqvekcpsyyHHbzxInsVQMbFWqpO/+x39cK1yWsmHLVL/LH7hxvJI7xI9+J/?= =?us-ascii?Q?cFmf0A4sBmxPXXYBZSeVWiMftkfRvgJwa+RPvS5I6JFxR+7VnG6efDUt397G?= =?us-ascii?Q?0g4vMdlas+9nGOl0cocH3g4NE6PpVn2iex4qxg1VoVlPojo3TbadU2XqEQxk?= =?us-ascii?Q?PmM0rlFJf32/L3YKeDKw6GXaw/2JNPm/HO94W/OuVqDHdmqcH3ZsJsjIE7q5?= =?us-ascii?Q?qdJKU3c0h4ZEbuSgyqIjnFYz7wJWsDfq1DKWuhcANh2SieB3pqRT0/26iyVI?= =?us-ascii?Q?BoXIGIy3ddFqtg4C3I9HxGGsQmoCnsFtkfcV+iMICxQOFxd0pmBdORZRaVcc?= =?us-ascii?Q?4wcjuL1wBKfIbzYsg6xeVg2h3oUtdDP51Rg4buK24LP35rLX7xDMWdCrZwb8?= =?us-ascii?Q?62viFDr9IoLQekQxHJEcrTNoc/AwOQ3bcMBHk81lVMqn7GubScchN5x9HgKJ?= =?us-ascii?Q?/tEHw5EkPe1gYlhAELpMTPcP9y9Odb/TqtJdOnEheRRzRRFrIIjS9KGU+HyP?= =?us-ascii?Q?k9K0MxJpvJmYWn5GjD0guwiaNXwgZ4wA1Pu9fdVTJ7flH8PEjENpcmd5+rYc?= =?us-ascii?Q?ftSZGzwPs9n2vI2qRXkdZXto1DQ8o8WmZsDBtvQZ1/jw7z71aCV9HSnR7GXq?= =?us-ascii?Q?p7ZMbgcgU1NjJI4321q0ZSXT/sDQc/Y?= X-Microsoft-Exchange-Diagnostics: 1;AM4PR03MB1763;6:H/npvuTpzMLG7jIIy3QQH6Oh+YueS4vztx+0XlwkwETkC6HZKLnAO5ZtReGISNWg0JYgwnZWDeJQg5UNgY/sU7QkBSNsxmKVlKVLg/vloLs/EG3eSsy3tknxPQd/7pWz786Ua7pJV83YMKbMbnMypBrBCsGhuoitG1WtWKvc+OJee2yw/E+HHhCvIQMubKRY3MtnOasMv/FzAZIyXIZUygOvSLBVttuQE83ms1QiLPamgFvU94LpR/kLxeZV5Eq8vKeyjG7OZc8CMg2s5I9xOvSSG/y6p2TWX5E9sYmsy78bfrLZziRF7Vry/zh8/VxzJdGHKelxIJH/nfYYefJmiABZpFqlmhjc3qApnvwP1tE=;5:1IwcRd8VpkmtarsFa1uKl2xQbCHPVVm8q/1YbmwZvFLxzadetyPuwh5r0mpFa9qLqbkXLyNUpjrWyaNVZ9/xbzYEd13Va/iwfOxyYLteXbiiw/BsKqeJcGGrvhqK4AYyTD3BZLYqFSbtH0TRQb7ug1w50YxoE45VFtzxLNSwxZI=;24:hHTyU2009Um2cOO7kKa+yv66xuOQ/0qxw3GjRlKczqAe2ic1oaVjz37NKmdoo5/ZA1IEfj74qMXxQdj6wqevksTTCb/2Kvsxi+AxwEpoWbc=;7:82JaVCnOHF6eXw51x3HFtferOCv39WV8pLSRGa0VYsUrSCddCaxapjGdAPH78gV4Sfdt0ZEKilWRbdgBj7nJuBxhvKu/Un/p8uHF+8cCZbP8shk2MuWQckNZpgMAD3qdUeL24dZ8TjGlXHg02gQKnCEqZO7mKz+dJ1VHBMzE0xPM9jJlIz9cvwtSi3tb9REVFRD6OHu9xkC82G5nRCCTaB7k+sHaco14rdfsARU/JcyYHF2MtpgXyuZ3WRzVaPRf SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: epam.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Nov 2017 12:49:00.6559 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f7ed1941-8daa-4c91-8de9-08d5372790b8 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b41b72d0-4e9f-4c26-8a69-f949f367c91d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR03MB1763 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jens Wiklander Added new ioctl to allow users register own buffers as a shared memory. Signed-off-by: Jens Wiklander Signed-off-by: Volodymyr Babchuk --- drivers/tee/tee_core.c | 41 +++++++++- drivers/tee/tee_shm.c | 205 +++++++++++++++++++++++++++++++++++++++++------ include/linux/tee_drv.h | 47 ++++++++++- include/uapi/linux/tee.h | 30 +++++++ 4 files changed, 293 insertions(+), 30 deletions(-) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 58a5009..295910f 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -114,8 +114,6 @@ static int tee_ioctl_shm_alloc(struct tee_context *ctx, if (data.flags) return -EINVAL; - data.id = -1; - shm = tee_shm_alloc(ctx, data.size, TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); if (IS_ERR(shm)) return PTR_ERR(shm); @@ -138,6 +136,43 @@ static int tee_ioctl_shm_alloc(struct tee_context *ctx, return ret; } +static int +tee_ioctl_shm_register(struct tee_context *ctx, + struct tee_ioctl_shm_register_data __user *udata) +{ + long ret; + struct tee_ioctl_shm_register_data data; + struct tee_shm *shm; + + if (copy_from_user(&data, udata, sizeof(data))) + return -EFAULT; + + /* Currently no input flags are supported */ + if (data.flags) + return -EINVAL; + + shm = tee_shm_register(ctx, data.addr, data.length, + TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED); + if (IS_ERR(shm)) + return PTR_ERR(shm); + + data.id = shm->id; + data.flags = shm->flags; + data.length = shm->size; + + if (copy_to_user(udata, &data, sizeof(data))) + ret = -EFAULT; + else + ret = tee_shm_get_fd(shm); + /* + * When user space closes the file descriptor the shared memory + * should be freed or if tee_shm_get_fd() failed then it will + * be freed immediately. + */ + tee_shm_put(shm); + return ret; +} + static int params_from_user(struct tee_context *ctx, struct tee_param *params, size_t num_params, struct tee_ioctl_param __user *uparams) @@ -586,6 +621,8 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return tee_ioctl_version(ctx, uarg); case TEE_IOC_SHM_ALLOC: return tee_ioctl_shm_alloc(ctx, uarg); + case TEE_IOC_SHM_REGISTER: + return tee_ioctl_shm_register(ctx, uarg); case TEE_IOC_OPEN_SESSION: return tee_ioctl_open_session(ctx, uarg); case TEE_IOC_INVOKE: diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index fdda89e..177e341 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -23,7 +23,6 @@ static void tee_shm_release(struct tee_shm *shm) { struct tee_device *teedev = shm->teedev; - struct tee_shm_pool_mgr *poolm; mutex_lock(&teedev->mutex); idr_remove(&teedev->idr, shm->id); @@ -31,12 +30,29 @@ static void tee_shm_release(struct tee_shm *shm) list_del(&shm->link); mutex_unlock(&teedev->mutex); - if (shm->flags & TEE_SHM_DMA_BUF) - poolm = teedev->pool->dma_buf_mgr; - else - poolm = teedev->pool->private_mgr; + if (shm->flags & TEE_SHM_POOL) { + struct tee_shm_pool_mgr *poolm; + + if (shm->flags & TEE_SHM_DMA_BUF) + poolm = teedev->pool->dma_buf_mgr; + else + poolm = teedev->pool->private_mgr; + + poolm->ops->free(poolm, shm); + } else if (shm->flags & TEE_SHM_REGISTER) { + size_t n; + int rc = teedev->desc->ops->shm_unregister(shm->ctx, shm); + + if (rc) + dev_err(teedev->dev.parent, + "unregister shm %p failed: %d", shm, rc); + + for (n = 0; n < shm->num_pages; n++) + put_page(shm->pages[n]); + + kfree(shm->pages); + } - poolm->ops->free(poolm, shm); kfree(shm); tee_device_put(teedev); @@ -76,6 +92,10 @@ static int tee_shm_op_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) struct tee_shm *shm = dmabuf->priv; size_t size = vma->vm_end - vma->vm_start; + /* Refuse sharing shared memory provided by application */ + if (shm->flags & TEE_SHM_REGISTER) + return -EINVAL; + return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT, size, vma->vm_page_prot); } @@ -89,26 +109,20 @@ static const struct dma_buf_ops tee_shm_dma_buf_ops = { .mmap = tee_shm_op_mmap, }; -/** - * tee_shm_alloc() - Allocate shared memory - * @ctx: Context that allocates the shared memory - * @size: Requested size of shared memory - * @flags: Flags setting properties for the requested shared memory. - * - * Memory allocated as global shared memory is automatically freed when the - * TEE file pointer is closed. The @flags field uses the bits defined by - * TEE_SHM_* in . TEE_SHM_MAPPED must currently always be - * set. If TEE_SHM_DMA_BUF global shared memory will be allocated and - * associated with a dma-buf handle, else driver private memory. - */ -struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) +struct tee_shm *__tee_shm_alloc(struct tee_context *ctx, + struct tee_device *teedev, + size_t size, u32 flags) { - struct tee_device *teedev = ctx->teedev; struct tee_shm_pool_mgr *poolm = NULL; struct tee_shm *shm; void *ret; int rc; + if (ctx && ctx->teedev != teedev) { + dev_err(teedev->dev.parent, "ctx and teedev mismatch\n"); + return ERR_PTR(-EINVAL); + } + if (!(flags & TEE_SHM_MAPPED)) { dev_err(teedev->dev.parent, "only mapped allocations supported\n"); @@ -135,7 +149,7 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) goto err_dev_put; } - shm->flags = flags; + shm->flags = flags | TEE_SHM_POOL; shm->teedev = teedev; shm->ctx = ctx; if (flags & TEE_SHM_DMA_BUF) @@ -171,9 +185,12 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) goto err_rem; } } - mutex_lock(&teedev->mutex); - list_add_tail(&shm->link, &ctx->list_shm); - mutex_unlock(&teedev->mutex); + + if (ctx) { + mutex_lock(&teedev->mutex); + list_add_tail(&shm->link, &ctx->list_shm); + mutex_unlock(&teedev->mutex); + } return shm; err_rem: @@ -188,8 +205,139 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) tee_device_put(teedev); return ret; } +/** + * tee_shm_alloc() - Allocate shared memory + * @ctx: Context that allocates the shared memory + * @size: Requested size of shared memory + * @flags: Flags setting properties for the requested shared memory. + * + * Memory allocated as global shared memory is automatically freed when the + * TEE file pointer is closed. The @flags field uses the bits defined by + * TEE_SHM_* in . TEE_SHM_MAPPED must currently always be + * set. If TEE_SHM_DMA_BUF global shared memory will be allocated and + * associated with a dma-buf handle, else driver private memory. + */ +struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) +{ + return __tee_shm_alloc(ctx, ctx->teedev, size, flags); +} EXPORT_SYMBOL_GPL(tee_shm_alloc); +struct tee_shm *tee_shm_priv_alloc(struct tee_device *teedev, size_t size) +{ + return __tee_shm_alloc(NULL, teedev, size, TEE_SHM_MAPPED); +} +EXPORT_SYMBOL_GPL(tee_shm_priv_alloc); + +struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, + size_t length, u32 flags) +{ + struct tee_device *teedev = ctx->teedev; + const u32 req_flags = TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED; + struct tee_shm *shm; + void *ret; + int rc; + int num_pages; + unsigned long start; + + if (flags != req_flags) + return ERR_PTR(-ENOTSUPP); + + if (!tee_device_get(teedev)) + return ERR_PTR(-EINVAL); + + if (!teedev->desc->ops->shm_register || + !teedev->desc->ops->shm_unregister) { + tee_device_put(teedev); + return ERR_PTR(-ENOTSUPP); + } + + shm = kzalloc(sizeof(*shm), GFP_KERNEL); + if (!shm) { + ret = ERR_PTR(-ENOMEM); + goto err; + } + + shm->flags = flags | TEE_SHM_REGISTER; + shm->teedev = teedev; + shm->ctx = ctx; + shm->id = -1; + start = rounddown(addr, PAGE_SIZE); + shm->offset = addr - start; + shm->size = length; + num_pages = (roundup(addr + length, PAGE_SIZE) - start) / PAGE_SIZE; + shm->pages = kcalloc(num_pages, sizeof(*shm->pages), GFP_KERNEL); + if (!shm->pages) { + ret = ERR_PTR(-ENOMEM); + goto err; + } + + rc = get_user_pages_fast(start, num_pages, 1, shm->pages); + if (rc > 0) + shm->num_pages = rc; + if (rc != num_pages) { + if (rc > 0) + rc = -ENOMEM; + ret = ERR_PTR(rc); + goto err; + } + + mutex_lock(&teedev->mutex); + shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL); + mutex_unlock(&teedev->mutex); + + if (shm->id < 0) { + ret = ERR_PTR(shm->id); + goto err; + } + + rc = teedev->desc->ops->shm_register(ctx, shm, shm->pages, + shm->num_pages); + if (rc) { + ret = ERR_PTR(rc); + goto err; + } + + if (flags & TEE_SHM_DMA_BUF) { + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + + exp_info.ops = &tee_shm_dma_buf_ops; + exp_info.size = shm->size; + exp_info.flags = O_RDWR; + exp_info.priv = shm; + + shm->dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(shm->dmabuf)) { + ret = ERR_CAST(shm->dmabuf); + teedev->desc->ops->shm_unregister(ctx, shm); + goto err; + } + } + + mutex_lock(&teedev->mutex); + list_add_tail(&shm->link, &ctx->list_shm); + mutex_unlock(&teedev->mutex); + + return shm; +err: + if (shm) { + size_t n; + + if (shm->id >= 0) { + mutex_lock(&teedev->mutex); + idr_remove(&teedev->idr, shm->id); + mutex_unlock(&teedev->mutex); + } + for (n = 0; n < shm->num_pages; n++) + put_page(shm->pages[n]); + kfree(shm->pages); + } + kfree(shm); + tee_device_put(teedev); + return ret; +} +EXPORT_SYMBOL_GPL(tee_shm_register); + /** * tee_shm_get_fd() - Increase reference count and return file descriptor * @shm: Shared memory handle @@ -197,10 +345,9 @@ EXPORT_SYMBOL_GPL(tee_shm_alloc); */ int tee_shm_get_fd(struct tee_shm *shm) { - u32 req_flags = TEE_SHM_MAPPED | TEE_SHM_DMA_BUF; int fd; - if ((shm->flags & req_flags) != req_flags) + if (!(shm->flags & TEE_SHM_DMA_BUF)) return -EINVAL; fd = dma_buf_fd(shm->dmabuf, O_CLOEXEC); @@ -238,6 +385,8 @@ EXPORT_SYMBOL_GPL(tee_shm_free); */ int tee_shm_va2pa(struct tee_shm *shm, void *va, phys_addr_t *pa) { + if (!(shm->flags & TEE_SHM_MAPPED)) + return -EINVAL; /* Check that we're in the range of the shm */ if ((char *)va < (char *)shm->kaddr) return -EINVAL; @@ -258,6 +407,8 @@ EXPORT_SYMBOL_GPL(tee_shm_va2pa); */ int tee_shm_pa2va(struct tee_shm *shm, phys_addr_t pa, void **va) { + if (!(shm->flags & TEE_SHM_MAPPED)) + return -EINVAL; /* Check that we're in the range of the shm */ if (pa < shm->paddr) return -EINVAL; @@ -284,6 +435,8 @@ EXPORT_SYMBOL_GPL(tee_shm_pa2va); */ void *tee_shm_get_va(struct tee_shm *shm, size_t offs) { + if (!(shm->flags & TEE_SHM_MAPPED)) + return ERR_PTR(-EINVAL); if (offs >= shm->size) return ERR_PTR(-EINVAL); return (char *)shm->kaddr + offs; diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index e9be4a4..70b9c73 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -25,8 +25,12 @@ * specific TEE driver. */ -#define TEE_SHM_MAPPED 0x1 /* Memory mapped by the kernel */ -#define TEE_SHM_DMA_BUF 0x2 /* Memory with dma-buf handle */ +#define TEE_SHM_MAPPED BIT(0) /* Memory mapped by the kernel */ +#define TEE_SHM_DMA_BUF BIT(1) /* Memory with dma-buf handle */ +#define TEE_SHM_EXT_DMA_BUF BIT(2) /* Memory with dma-buf handle */ +#define TEE_SHM_REGISTER BIT(3) /* Memory registered in secure world */ +#define TEE_SHM_USER_MAPPED BIT(4) /* Memory mapped in user space */ +#define TEE_SHM_POOL BIT(5) /* Memory allocated from pool */ struct device; struct tee_device; @@ -76,6 +80,8 @@ struct tee_param { * @cancel_req: request cancel of an ongoing invoke or open * @supp_revc: called for supplicant to get a command * @supp_send: called for supplicant to send a response + * @shm_register: register shared memory buffer in TEE + * @shm_unregister: unregister shared memory buffer in TEE */ struct tee_driver_ops { void (*get_version)(struct tee_device *teedev, @@ -94,6 +100,9 @@ struct tee_driver_ops { struct tee_param *param); int (*supp_send)(struct tee_context *ctx, u32 ret, u32 num_params, struct tee_param *param); + int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm, + struct page **pages, size_t num_pages); + int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm); }; /** @@ -302,6 +311,30 @@ void *tee_get_drvdata(struct tee_device *teedev); struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags); /** + * tee_shm_priv_alloc() - Allocate shared memory privately + * @dev: Device that allocates the shared memory + * @size: Requested size of shared memory + * + * Allocates shared memory buffer that is not associated with any client + * context. Such buffers are owned by TEE driver and used for internal calls. + * + * @returns a pointer to 'struct tee_shm' + */ +struct tee_shm *tee_shm_priv_alloc(struct tee_device *teedev, size_t size); + +/** + * tee_shm_register() - Register shared memory buffer + * @ctx: Context that registers the shared memory + * @addr: Address is userspace of the shared buffer + * @length: Length of the shared buffer + * @flags: Flags setting properties for the requested shared memory. + * + * @returns a pointer to 'struct tee_shm' + */ +struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, + size_t length, u32 flags); + +/** * tee_shm_free() - Free shared memory * @shm: Handle to shared memory to free */ @@ -366,4 +399,14 @@ int tee_shm_get_id(struct tee_shm *shm); */ struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id); +/** + * tee_shm_is_registered() - Check if shared memory object in registered in TEE + * @shm: Shared memory handle + * @returns true if object is registered in TEE + */ +static inline bool tee_shm_is_registered(struct tee_shm *shm) +{ + return shm && (shm->flags & TEE_SHM_REGISTER); +} + #endif /*__TEE_DRV_H*/ diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h index 688782e..d41a07a 100644 --- a/include/uapi/linux/tee.h +++ b/include/uapi/linux/tee.h @@ -50,6 +50,7 @@ #define TEE_GEN_CAP_GP (1 << 0)/* GlobalPlatform compliant TEE */ #define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */ +#define TEE_GEN_CAP_REG_MEM (1 << 2)/* Supports registering shared memory */ /* * TEE Implementation ID @@ -332,6 +333,35 @@ struct tee_iocl_supp_send_arg { #define TEE_IOC_SUPPL_SEND _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 7, \ struct tee_ioctl_buf_data) +/** + * struct tee_ioctl_shm_register_data - Shared memory register argument + * @addr: [in] Start address of shared memory to register + * @length: [in/out] Length of shared memory to register + * @flags: [in/out] Flags to/from registration. + * @id: [out] Identifier of the shared memory + * + * The flags field should currently be zero as input. Updated by the call + * with actual flags as defined by TEE_IOCTL_SHM_* above. + * This structure is used as argument for TEE_IOC_SHM_REGISTER below. + */ +struct tee_ioctl_shm_register_data { + __u64 addr; + __u64 length; + __u32 flags; + __s32 id; +}; + +/** + * TEE_IOC_SHM_REGISTER - Register shared memory argument + * + * Registers shared memory between the user space process and secure OS. + * + * Returns a file descriptor on success or < 0 on failure + * + * The shared memory is unregisterred when the descriptor is closed. + */ +#define TEE_IOC_SHM_REGISTER _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \ + struct tee_ioctl_shm_register_data) /* * Five syscalls are used when communicating with the TEE driver. * open(): opens the device associated with the driver -- 2.7.4 From 1581172420273427760@xxx Fri Oct 13 19:38:47 +0000 2017 X-GM-THRID: 1579807631250973084 X-Gmail-Labels: Inbox,Category Forums