From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753155AbdK2Mvl (ORCPT ); Wed, 29 Nov 2017 07:51:41 -0500 Received: from mail-he1eur01on0072.outbound.protection.outlook.com ([104.47.0.72]:15904 "EHLO EUR01-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752172AbdK2Mta (ORCPT ); Wed, 29 Nov 2017 07:49:30 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Volodymyr_Babchuk@epam.com; 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 , volodymyr_babchuk@epam.com Subject: [RESEND PATCH v2 06/14] tee: optee: add page list manipulation functions Date: Wed, 29 Nov 2017 14:48:30 +0200 Message-Id: <1511959718-5421-7-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: DB6PR0301CA0052.eurprd03.prod.outlook.com (2603:10a6:4:54::20) To DB5PR03MB1766.eurprd03.prod.outlook.com (2a01:111:e400:c580::7) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: eea32b7d-3d49-43d8-ec75-08d537279fbe X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(5600026)(4604075)(4534020)(4602075)(7168020)(4627115)(201703031133081)(201702281549075)(2017052603199);SRVR:DB5PR03MB1766; X-Microsoft-Exchange-Diagnostics: 1;DB5PR03MB1766;3:RdQ8y+lEEiKTTEmowl/N6GJXc7Uw9pCnZzuxFRpAqGfS2N+CiZe/k9ctpI6DxpfsMxKT5J2+WebRfuVcG+iFBsap7tJTk5sU84DiPuC+SnIn6chpQOAHMV+QcgAoDIcFyLF5L+WoWUzdoaDNMQoDm2DVNU+wEA8mYchp6FrO89gXxnOXW0Vc0rdbvqqObFhxBcZoikVFloQ1PXZytD7pzrrXB+ejZlwlFzzXpgMFylL8UQ8yjzwVPgKyDfL1faaE;25:dp0aYr2t2VIQmynI5BxIPrXTXg5ib7g5KeoUEXdOpbYqUPTcoxSLaVXkALbCzWuVcBpympiNeTEj7p4DKtesCHraeF0TESGdB0XZ9o9DceEA0vQfPurexoOshvC74GM0mZcTQTxmNwdv1BOsRD57yJhYBFqDlE6sPbKzRoH15ZxBGNVyBsafuXYvVm+PJtCgJfYMn3Q/c56Xxdvm3yBRfDk7CuCCZsh9Yy9pxBN/5wxkc/MFIvPwqmxcoyqAeA5q2iMjkhwzawR238nHXg1Vy2dstZIfmcs/+dN79QYHLaEI1JuLLTkEwoFNwRt4HrzjtlD0dIiUUMtmJeh/YoagFS/lw2h4WcQBitkwLHSv83E=;31:emhuRD/FfTSSSNp8r8fKwCQkiT4rq+kEtignywRJYcfqY+rVimfb0mpb3gAnDcQmZJ6RJ48SsQpKrHSV6BLVclBMAV01v8MByhw7BYCDuKvAJ49E7iqhhrYlauZ63EyAL+hlYgJ7Ol+pHEUEQSHwdvD70x24+Xo/E2yXO3NFe1dm2KpylDvfISYJ03POuA23MF167rqYing5u3Zv9EfA8A6A9g2SJIYKL7X6urNdK20= X-MS-TrafficTypeDiagnostic: DB5PR03MB1766: X-Microsoft-Exchange-Diagnostics: 1;DB5PR03MB1766;20:wJcin82O005sAizc45UY+z0pYHcNEQtzflLcAAHyrKTmyRl3oO4xZCDV8uh0gIHBclJuEhEBsBr3ahtZqILMhNL41CocFz9F0DpIiUx08ZIskh4fmPlckyLPZZzpwSWiNEd0hu/Zbu9OxXLyyvws27d6snbQ9EAf+x28ugQElTfp9JzJJ/WAkEvqkKmTfCvKIN+BZ/yLOzSduNqcaohfCn/gxPQvXDxOrpNx0oVstm03mSY9bC7UIYVnTwTvWjNl7ahEp7URud8hwi09Gu3/0/XWXSV7T8r/RFTwU3afH3tzqrMFmpiixJ0Xxo1qHFtDeKQGMjUw74a4ZOvQXLiKYaAVdPdOu+vCN+A95I4tdtlifGKYuLUYAWogJTIfVEpBAiPDp84eApUE8NFI8kbFSmSNYXm8AAwHVEJoazwioKbPnDR5UMKLEdZxGciWDLwhCtIWhgbnyMeRubxhQWsVoMjndxe9NEtN9KAgT+tS0s56WzK/jRw0zp+LQ9ybaXB6;4:Bdlqw6vHR0tfmSQBCyhDxldFpv21glzpDV0m/Sf8pzW0gwi5wgw+2/FnHuX2QFVRPyx2uUzxRTtBYPavViqHKgZji4FGI3U2Pux2qhMAd4XIvsOHeIA9xHk8IcWOvmlJOIb6fabVsoYRfLGhLPZVinCRJuOM4j3aByuCl7wrPo1BEYgPO39LgZ9/iDEA3oNgYgaC6d+WsAzwsaW/oqAVRRuSlh3XB+zkLFfzTmbix95OjvBIr6iCt+K1mdlTdkO2Vced0m2Jna2+MMJFLxsbTQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040450)(2401047)(5005006)(8121501046)(3002001)(3231022)(93006095)(93001095)(10201501046)(6041248)(20161123564025)(20161123558100)(20161123555025)(20161123560025)(20161123562025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011);SRVR:DB5PR03MB1766;BCL:0;PCL:0;RULEID:(100000803101)(100110400095);SRVR:DB5PR03MB1766; X-Forefront-PRVS: 05066DEDBB X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(366004)(346002)(376002)(199003)(189002)(51416003)(80792005)(36756003)(50466002)(106356001)(33646002)(50986999)(105586002)(76176999)(39060400002)(72206003)(478600001)(107886003)(52116002)(4326008)(66066001)(55236003)(101416001)(53936002)(122856001)(16586007)(316002)(42186006)(48376002)(47776003)(8936002)(5660300001)(6666003)(6916009)(2950100002)(189998001)(6116002)(2906002)(3846002)(68736007)(50226002)(8676002)(7736002)(305945005)(97736004)(86362001)(81156014)(81166006)(217873001);DIR:OUT;SFP:1101;SCL:1;SRVR:DB5PR03MB1766;H:EPUAKYIW2556.kyiv.epam.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DB5PR03MB1766;23:Xrh44IjaZHnoftpFNO9amFSW9NrQKyxYTWDKfS5Cm?= =?us-ascii?Q?uqgKOrm3lZ2VjNLQaMSrC3CZRpjmaOh2DITbIQuz/SDCCts10WA3Lw2MvUK7?= =?us-ascii?Q?EPWBbK9Qn750+ZyzOwFt08lQPQnqsR7TQjB5uArJXaTuiABWjmUULhIYd5bD?= =?us-ascii?Q?LcD0xdYJKSOjSbqy1zA0j320//D+MZ6fkpKMQ/ChtpCz7oIjDdYzMbSg0svH?= =?us-ascii?Q?u6yfGDvHgqOp4qLZuuDqi/Fr+I9raKzTyjdIkZHR56Tyn0W+pI7VLLFRnDbT?= =?us-ascii?Q?81wjqF+OtZWo70bo9GVF27hjOlzkTK7Vaf5dQZAKr78mq6dSuh5squd7SlBl?= =?us-ascii?Q?uRD0HpMiY0CIXfjMRHdsdLkM7U4O2hykiH762EDzhYlA9Ec0vzhBcVCywHjy?= =?us-ascii?Q?J99DbTVfNyR7xGr4PmfYozZWfgFzb5CT2mCUkkHO9eaaQgxzcbbNXrau8Sam?= =?us-ascii?Q?G8mqWx3CInAdEHBg5PmCdfZMJeNJXQ8XN+cfzfPrrg4s7UQgw7VNbhLD6ew6?= =?us-ascii?Q?OMvVIqfDxScwA2cFM+sBX0tIQW4ZIbSC8uUuzbUB1lSkMY0ugwT8tCxas6Pb?= =?us-ascii?Q?RM1e0Z7/I0gQoeT/IWnUboToTHoln8jhmUZTPIUW0m+QOSA7CIxJzIE2/keG?= =?us-ascii?Q?CZhhWA9ndQGIwkyUrFZcdtLSbhnntXCyLlI4uGo21TXLj/9qHdyFfrDgH8JY?= =?us-ascii?Q?XpkzcjDPFbzsmt04fe9ZsfUTpQkoiiuZ6qUh+nzvyFXRx6ytDF2XwhsRruvS?= =?us-ascii?Q?4PS4khOV9PY6F9borByImQ7HLuy7MC6qUX0OLJGc122jarWrPky6xU3tuyhS?= =?us-ascii?Q?MKGImtieWFXfmf5sxOvOAWOc2/Taza3FijO2VuizytYxGLk7xcNvaEhPqkUx?= =?us-ascii?Q?WiZVeFGPIjYoenLGjEXlZ9lovd48MJ4niyTpzbCKAbcC4/iIubcO8pFtmjRY?= =?us-ascii?Q?2agsQXDMMJIsNzEltZd+WNvcAiLxNMcSSLoZ+lj1MTBwN4W91gqEdfZdWxSN?= =?us-ascii?Q?I/v4iaFmKveQ0LvF0bwmuXLaWBN+YNXteInjSkErPAHPUe3fDdpoSGWgqRH0?= =?us-ascii?Q?B69isEj7dpM9SmeWa7n/c2dJJB7IIdzmAEynoRhj5vRRmmsWrzGI3teg+sop?= =?us-ascii?Q?lGw2g2D53yHnhQEdjhFPXawGQimH8J/OUTMGPlQzEI+X8bpslWscg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;DB5PR03MB1766;6:znUeuTOzucPcO0bZXg9WfuvJsghecYSUNpKAF+0Uqs+bA7AAwvYw/NmlbmzURgwkcP8d1V4tGYmVjn/l75M0V38xOjffYLK1eS2yB2L2s65pdSJz8EtPc5baT2p0I6SNDLjKLctJgstZGru6GupYoUGyUwqeGZa37N0Fi+WvYS0JUMsUZZ66oqXZoLccbeJMb+4yvhcC1zgZAjyLSXZRXnpPoivLe5FI7lE7pQmCbJFpEW6tdbyFLf58xYnAAGMIx5lTnR9PHnrM20UTQIieL2kAgwWfJ6eb2zDuGkoEEThwOncmJ7B1tR9dGbFH27xpOm+a+XGgGWOqsvGqw0gUEEqFuUXSNRjlfT6/jlRkWRM=;5:G61LXTgn1/+qqHAjDL5oxu6jK9w50+oQr6bEeyElYIRtk/+8G0eREM0AcWHYyeScxWGQc0yhnCASN1R4BA6L+PMjNscLig3VD3TfUP77OyyFiwimoXf/dUZJwj1PnwnidwQEep3MP2B7bsfd0tD+ags5TN8Zhjp5NkWclHrD4MY=;24:1ykogqZFeeCabZcxBBGtQoU63Zqd0uOiZlYaxJtHNedsCcP8aC3jhF/0nsAtPoE0HLgOXIwR/aCkzZH6bzdxGnr3Q/xisBVIaIIeJP5g3fo=;7:lpgHJ18zQ+3vFm1iImiSiJ16cLV41Y+1CJ+eKmDMQnayuy/eB7msX5Lpr9fbtuicBnhFaKA7hEUf9UwdjEd+wmb0BpUaxh2s4Y1BTnhYBqf4zijxCPlkGjR2/5Kwyk3RAO2O8jz0rMzl6YHc6U8jj6l3Cl4Mghd1wNOP1DU41jwNr1qAOv0VW7bBUxt++kIZ1kgj3P2etT59ZIdQoIBnU2Qc3c6Am2z+VIdiauFZs+gxq3fcy6yE5y85XONbH/tv SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: epam.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Nov 2017 12:49:26.1447 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: eea32b7d-3d49-43d8-ec75-08d537279fbe X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b41b72d0-4e9f-4c26-8a69-f949f367c91d X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB5PR03MB1766 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Volodymyr Babchuk These functions will be used to pass information about shared buffers to OP-TEE. ABI between Linux and OP-TEE is defined in optee_msg.h and optee_smc.h. optee_msg.h defines OPTEE_MSG_ATTR_NONCONTIG attribute for shared memory references and describes how such references should be passed. Note that it uses 64-bit page addresses even on 32 bit systems. This is done to support LPAE and to unify interface. Signed-off-by: Volodymyr Babchuk --- drivers/tee/optee/call.c | 91 +++++++++++++++++++++++++++++++++++++++ drivers/tee/optee/optee_private.h | 5 +++ 2 files changed, 96 insertions(+) diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c index f7b7b40..4db52fe 100644 --- a/drivers/tee/optee/call.c +++ b/drivers/tee/optee/call.c @@ -11,6 +11,7 @@ * GNU General Public License for more details. * */ +#include #include #include #include @@ -442,3 +443,93 @@ void optee_disable_shm_cache(struct optee *optee) } optee_cq_wait_final(&optee->call_queue, &w); } + +#define PAGELIST_ENTRIES_PER_PAGE \ + ((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1) + +/** + * optee_fill_pages_list() - write list of user pages to given shared + * buffer. + * + * @dst: page-aligned buffer where list of pages will be stored + * @pages: array of pages that represents shared buffer + * @num_pages: number of entries in @pages + * @page_offset: offset of user buffer from page start + * + * @dst should be big enough to hold list of user page addresses and + * links to the next pages of buffer + */ +void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages, + size_t page_offset) +{ + int n = 0; + phys_addr_t optee_page; + /* + * Refer to OPTEE_MSG_ATTR_NONCONTIG description in optee_msg.h + * for details. + */ + struct { + uint64_t pages_list[PAGELIST_ENTRIES_PER_PAGE]; + uint64_t next_page_data; + } *pages_data; + + /* + * Currently OP-TEE uses 4k page size and it does not looks + * like this will change in the future. On other hand, there are + * no know ARM architectures with page size < 4k. + * Thus the next built assert looks redundant. But the following + * code heavily relies on this assumption, so it is better be + * safe than sorry. + */ + BUILD_BUG_ON(PAGE_SIZE < OPTEE_MSG_NONCONTIG_PAGE_SIZE); + + pages_data = (void *)dst; + /* + * If linux page is bigger than 4k, and user buffer offset is + * larger than 4k/8k/12k/etc this will skip first 4k pages, + * because they bear no value data for OP-TEE. + */ + optee_page = page_to_phys(*pages) + + round_down(page_offset, OPTEE_MSG_NONCONTIG_PAGE_SIZE); + + while (true) { + pages_data->pages_list[n++] = optee_page; + + if (n == PAGELIST_ENTRIES_PER_PAGE) { + pages_data->next_page_data = + virt_to_phys(pages_data + 1); + pages_data++; + n = 0; + } + + optee_page += OPTEE_MSG_NONCONTIG_PAGE_SIZE; + if (!(optee_page & ~PAGE_MASK)) { + if (!--num_pages) + break; + pages++; + optee_page = page_to_phys(*pages); + } + } +} + +/* + * The final entry in each pagelist page is a pointer to the next + * pagelist page. + */ +static size_t get_pages_list_size(size_t num_entries) +{ + int pages = DIV_ROUND_UP(num_entries, PAGELIST_ENTRIES_PER_PAGE); + + return pages * OPTEE_MSG_NONCONTIG_PAGE_SIZE; +} + +u64 *optee_allocate_pages_list(size_t num_entries) +{ + return alloc_pages_exact(get_pages_list_size(num_entries), GFP_KERNEL); +} + +void optee_free_pages_list(void *list, size_t num_entries) +{ + free_pages_exact(list, get_pages_list_size(num_entries)); +} + diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h index c374cd5..b63213d 100644 --- a/drivers/tee/optee/optee_private.h +++ b/drivers/tee/optee/optee_private.h @@ -165,6 +165,11 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params, int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params, const struct tee_param *params); +u64 *optee_allocate_pages_list(size_t num_entries); +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); + /* * Small helpers */ -- 2.7.4 From mboxrd@z Thu Jan 1 00:00:00 1970 From: volodymyr_babchuk@epam.com (Volodymyr Babchuk) Date: Wed, 29 Nov 2017 14:48:30 +0200 Subject: [RESEND PATCH v2 06/14] tee: optee: add page list manipulation functions 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> Message-ID: <1511959718-5421-7-git-send-email-volodymyr_babchuk@epam.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org From: Volodymyr Babchuk These functions will be used to pass information about shared buffers to OP-TEE. ABI between Linux and OP-TEE is defined in optee_msg.h and optee_smc.h. optee_msg.h defines OPTEE_MSG_ATTR_NONCONTIG attribute for shared memory references and describes how such references should be passed. Note that it uses 64-bit page addresses even on 32 bit systems. This is done to support LPAE and to unify interface. Signed-off-by: Volodymyr Babchuk --- drivers/tee/optee/call.c | 91 +++++++++++++++++++++++++++++++++++++++ drivers/tee/optee/optee_private.h | 5 +++ 2 files changed, 96 insertions(+) diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c index f7b7b40..4db52fe 100644 --- a/drivers/tee/optee/call.c +++ b/drivers/tee/optee/call.c @@ -11,6 +11,7 @@ * GNU General Public License for more details. * */ +#include #include #include #include @@ -442,3 +443,93 @@ void optee_disable_shm_cache(struct optee *optee) } optee_cq_wait_final(&optee->call_queue, &w); } + +#define PAGELIST_ENTRIES_PER_PAGE \ + ((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1) + +/** + * optee_fill_pages_list() - write list of user pages to given shared + * buffer. + * + * @dst: page-aligned buffer where list of pages will be stored + * @pages: array of pages that represents shared buffer + * @num_pages: number of entries in @pages + * @page_offset: offset of user buffer from page start + * + * @dst should be big enough to hold list of user page addresses and + * links to the next pages of buffer + */ +void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages, + size_t page_offset) +{ + int n = 0; + phys_addr_t optee_page; + /* + * Refer to OPTEE_MSG_ATTR_NONCONTIG description in optee_msg.h + * for details. + */ + struct { + uint64_t pages_list[PAGELIST_ENTRIES_PER_PAGE]; + uint64_t next_page_data; + } *pages_data; + + /* + * Currently OP-TEE uses 4k page size and it does not looks + * like this will change in the future. On other hand, there are + * no know ARM architectures with page size < 4k. + * Thus the next built assert looks redundant. But the following + * code heavily relies on this assumption, so it is better be + * safe than sorry. + */ + BUILD_BUG_ON(PAGE_SIZE < OPTEE_MSG_NONCONTIG_PAGE_SIZE); + + pages_data = (void *)dst; + /* + * If linux page is bigger than 4k, and user buffer offset is + * larger than 4k/8k/12k/etc this will skip first 4k pages, + * because they bear no value data for OP-TEE. + */ + optee_page = page_to_phys(*pages) + + round_down(page_offset, OPTEE_MSG_NONCONTIG_PAGE_SIZE); + + while (true) { + pages_data->pages_list[n++] = optee_page; + + if (n == PAGELIST_ENTRIES_PER_PAGE) { + pages_data->next_page_data = + virt_to_phys(pages_data + 1); + pages_data++; + n = 0; + } + + optee_page += OPTEE_MSG_NONCONTIG_PAGE_SIZE; + if (!(optee_page & ~PAGE_MASK)) { + if (!--num_pages) + break; + pages++; + optee_page = page_to_phys(*pages); + } + } +} + +/* + * The final entry in each pagelist page is a pointer to the next + * pagelist page. + */ +static size_t get_pages_list_size(size_t num_entries) +{ + int pages = DIV_ROUND_UP(num_entries, PAGELIST_ENTRIES_PER_PAGE); + + return pages * OPTEE_MSG_NONCONTIG_PAGE_SIZE; +} + +u64 *optee_allocate_pages_list(size_t num_entries) +{ + return alloc_pages_exact(get_pages_list_size(num_entries), GFP_KERNEL); +} + +void optee_free_pages_list(void *list, size_t num_entries) +{ + free_pages_exact(list, get_pages_list_size(num_entries)); +} + diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h index c374cd5..b63213d 100644 --- a/drivers/tee/optee/optee_private.h +++ b/drivers/tee/optee/optee_private.h @@ -165,6 +165,11 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params, int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params, const struct tee_param *params); +u64 *optee_allocate_pages_list(size_t num_entries); +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); + /* * Small helpers */ -- 2.7.4