From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753534AbdJMTdu (ORCPT ); Fri, 13 Oct 2017 15:33:50 -0400 Received: from mail-eopbgr30048.outbound.protection.outlook.com ([40.107.3.48]:53712 "EHLO EUR03-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751057AbdJMTdp (ORCPT ); Fri, 13 Oct 2017 15:33:45 -0400 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: [PATCH v1 06/14] tee: optee: add page list manipulation functions Date: Fri, 13 Oct 2017 22:32:36 +0300 Message-Id: <1507923164-12796-7-git-send-email-volodymyr_babchuk@epam.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1507923164-12796-1-git-send-email-volodymyr_babchuk@epam.com> References: <1506621851-6929-1-git-send-email-volodymyr_babchuk@epam.com> <1507923164-12796-1-git-send-email-volodymyr_babchuk@epam.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [85.223.209.52] X-ClientProxiedBy: AM0PR0402CA0021.eurprd04.prod.outlook.com (2603:10a6:208:15::34) To AM4PR0301MB2130.eurprd03.prod.outlook.com (2603:10a6:200:4d::15) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 44a09ae1-c564-4ae0-b390-08d512714f8a X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(2017030254152)(2017052603199)(201703131423075)(201703031133081)(201702281549075);SRVR:AM4PR0301MB2130; X-Microsoft-Exchange-Diagnostics: 1;AM4PR0301MB2130;3:9avGLLM381aYeM80VpSWqYA2LZkDqhj8fJrMMxL935A0ol77p/qUn28g+yTaHvhnofEPQ9DBCWyAvhnwOD0s5GaNTk4IVPgpY92h7gXldX6eNh/kmkfhSMb39G5Hacx1C1CHqexuNT68B3kuWxF2uYFoXIJt2w2okMXtSUO9WlO1zDcXvMAQNHCxsKtJC5vodKxlsrnnFCEWcawyFNR57zcW+RP9JJWkXI6KmkrBr0uBZ4KAIKgyOQbEtPhvMzKA;25:kUTVae575wsvcuILtuMqpS+jhVb2XTLX3fYtlQZ8ryLp4CHp2qdtkFwY48FVFcGwPV22gcG7LE+rKaSEcEDsQbtnwnptZ0c+82Ee2Dm8ZYJuOtibScJZLlzUIahe7Btz+gIggIlSWEyhoSChBzEC3T+/01NVVT5kFbCDrc7PGutRilIwJEHHCulZn1pYzaC1ctF9cdNGLVNCydWhPl1PbkCB7I4TK+lZT5tD5vNLfEDX+l3BqYynDDk3rLEB+joDtv5FAcGJ4w7KKWiOrt9PEJ5+s0RLxEultEsYtyqf5SjaSUK2s/SEPfUbSgCsfzJycxN1hirudwFSYcIdBIVmPg==;31:coBcHZasfOz5YmTfN3ogIxV967Qm03LtRpn8oVk4eVo/NPBi2F1DL1/IOi9glZ68QbXUr3pJc+k7IR8tFUJW1f3DSjYuee4JdHDhZAQ1qe7BP42wlfYjP99d21EGXMLHMmW/mHVubLtbYXj1OfGxGySrVL8dZ6Gpedlu5/M+pK230YtNCf+aWuBkfLzXPX93a1i6/qmiAq6JXyeoEPyowyEESRNqwHDHCroc+3XKGEQ= X-MS-TrafficTypeDiagnostic: AM4PR0301MB2130: X-Microsoft-Exchange-Diagnostics: 1;AM4PR0301MB2130;20:2IFyWn/kUZoDex8b7G7wnko+VVyy5oKQh5Q1zGvHza6cQN/3h1654IKksAOgyZd8d/kOyBqSafDdxh2FGlmS1lb5N5SHqy5ExLrwGj3+BWvUpCyYl2pGczvDNx29K4T+MI8bC3OKxASFznnsAc21q+6ueMTOjEUcItTDiZj/YeehsH+ld7mLZm3B/byBx0NgbamgVYrdoiaoC+IMzEcRYDj/mI32qyylX70NtddFmKra5soYAME0fIURwif/LQJ3ATlvkYi+pyVUKQTQaX6CaFAToSIAdPQrrYJgyrJfktIGdLRq4efe+FRHQg0Zfw/KGxXBIEtVpOt2wQubo8Ezw4LdS72GqgCAs6d9wOjYWL16w/NL2vz68CzHdUBGwkok8i4reBQCkpBRoHi3Aq+0UxaKMQB7uYk0Pn64SzYfuStBusF1A5PW73pGBGJL2hO4SZ3lPziIy78oY+KpxufETHcv/y8kajTiJALYd13V4uu2mLUSZbIpigEF2Ox1pVVt;4:lgu3op2HfYMv1j7FeY/ftkGMHjXSeE2Bv1cUop2nXmj28kkFMLIBv2V8CT4qx+pE2f9LrhK4d8TcDWcpMzdIU9ABX+7FHideXoQR6FbRSMV5Y3mc+V69zEx/rTXZ4Nou+M7yTwa4ixnMKgzeE8SJ/XnMeU1wuxxdcRYJqd6KTvZ30JIYolrMzSUkhEfHsvWVcM7scXKNSyC++7wEyccrzrQZT6I3ENUT16m6RcDWhBh09rHQ+yK0qKCxvO0nKHv+ X-Exchange-Antispam-Report-Test: UriScan:; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(3002001)(100000703101)(100105400095)(93006095)(93001095)(10201501046)(6041248)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(20161123560025)(20161123558100)(20161123555025)(20161123564025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:AM4PR0301MB2130;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:AM4PR0301MB2130; X-Forefront-PRVS: 04599F3534 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(376002)(346002)(199003)(189002)(2950100002)(66066001)(6916009)(47776003)(106356001)(105586002)(42186006)(33646002)(6116002)(316002)(16586007)(478600001)(72206003)(189998001)(80792005)(5003940100001)(3846002)(97736004)(101416001)(4326008)(2906002)(50226002)(50986999)(48376002)(107886003)(53936002)(39060400002)(68736007)(76176999)(86362001)(36756003)(5660300001)(81166006)(8936002)(81156014)(50466002)(8676002)(305945005)(7736002)(122856001);DIR:OUT;SFP:1101;SCL:1;SRVR:AM4PR0301MB2130;H:EPUAKYIW2556.kyiv.epam.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AM4PR0301MB2130;23:ZDZcPXis1jn067MZnwK8kUjz5ZFRn4ns7BfhBW+?= =?us-ascii?Q?iOPmbylNeszDu0PTqvhJtFK+iEYr8ukzhezqwktvwu9xNJ/fmZjacPOSg74h?= =?us-ascii?Q?U939BplKs7THujYZN1wP8XOT5WBU9NOUapNT82CmuR/g4p4up5ZASyEKKr33?= =?us-ascii?Q?mDS+D7g6v/RiDAdf9K3ArdUIWrlK4ieb380Nc23by3i1DmgAq4ZTPGSQPaAT?= =?us-ascii?Q?ow3rdxA0VTHHdMotcKyxDe9okyJEoo1JprhHEjnEIzKZMcCYpzGP1h/3JNwU?= =?us-ascii?Q?gOri2EMMO4kcbtUFXv+unWdQV1GRj/tep6z6luZFijbhOsolHDQdJKOcbSv5?= =?us-ascii?Q?7bkfhQGkJclQXSCuMRmJzOvQMrT7ORu1S3aFTJojfEF80cKx4aYHmS+Jmpve?= =?us-ascii?Q?3lULr+bx7fbrnqF/C9Zo8JzH61XMrzgTNLL0F/Lwc1SOdgYpGShXGA1FZqZK?= =?us-ascii?Q?VuHLXTrHfnkoAa+3Bz9ZSVipKNtJ+/pZPoeRcNTuuRDTVLeLm9riNmwI4mxJ?= =?us-ascii?Q?RJE+64txkllgqhSrpnTdz/wIRct4C7qER8xybT7OeqOFuC+kk7njoaxM0MOz?= =?us-ascii?Q?MDxyJ+/Rpwby5434vvPBA0IjuG3xA3JBzeeN2A0+4pRhZ15yx3DdNurHRQ78?= =?us-ascii?Q?VESynJDKq4IpEXZb7uz5gzp4Tcojnahjb8MrrYd/JFlWpXjX+ynaubDRJegI?= =?us-ascii?Q?JgrGXkpL15Ujzs4DUlMWh6QpPSG5g8Fj8GnAIHBba9H1+0YqH4fugY9jN0Bj?= =?us-ascii?Q?NFzvu/HF7KNS/vetrXaYw4sTW5DIszV+aHwlGJ/fY5CxQdsZCjffPyLfRopx?= =?us-ascii?Q?1lr5V01Oy91ESgsP7sKRPHKNb/UG9raY9PEExd+kg3lLQE1OETKdcY014ApF?= =?us-ascii?Q?E7o3i2zooWTAYunatsTqQqGPo2dk8YETZAnriAXqh2lV5+4jX/N+Lv/eH1mY?= =?us-ascii?Q?8JL/IC7ekpkc3wc4vuksU0Dg3XRgckQ7scMipEE6ReDMhRuTEZgE7YW+FUVP?= =?us-ascii?Q?H8UaKL/4Eq1I1ttyf+LgMR/guhdMTssjg9yzrw4x4W2C3QzVe2Ny3xLce67p?= =?us-ascii?Q?FcIEl5w9ypnyX0Cgl6YdU8qVG2Q/N?= X-Microsoft-Exchange-Diagnostics: 1;AM4PR0301MB2130;6:OmuQBQWRRWSLaJPgc12HzBZL3eEOih31tkk2oSaRIaP7RUvkPcApFiIbxPQZriqguNwj2pofXHtgw4VZCpvdHAMSLrxktofSbu3de12Q9EldM79SbCj+fGFj3395YaFrNZVvJwmFGUzeK8NBjI0/B/8rpq9lIncZqAiYEzV617nDQJNwYhs+aaKUN82PtLj/xoJyX70FvixHFpIY7rocFsYckKgqKs9Mp76cbvajJWaOkoUJ5VxJkptVJUUDUERigTjDtBIMyXcwmsOv9RNnKr1FSpFN1ndq4EvYc20Gdowf9oWVMk/r7Dvc3su3lPjZpHT9dHuYBTaqjieoBVX8Tg==;5:Tk0/buaB5fqHZk/j0JmdyQgZ6ifFP1vsZ23ACQzQKCImKAHB1vkQFp/V9LE7eXv63qbtskFMpkrB9Z7DYf95wn0f7nWmlwFPGrpLK4nq10E5SBfG9ApDqcPseGtzbumP4WRNVe54q0DuS5ONtgr/iv5NL+TrI/F3DDRrrl9KfU8=;24:T01uMDBLjV49Y9B5YE+psFsNZJc1VcRI+LN90kJPJC8MO+rPLsSGoEnxFawnsD8Bfh/oWT19u/BV7KEAtxeqKbngjtg45TzI2Xq6O73jzYA=;7:VMk47Bj4KSAC3iGKpAYMZnz3VItvYUdOyu0N1+msGX49RLt1cMGmSyKykHEWiIzXSbKEtgXjlQBzomdSauG5o88fcTwH9qq0ZCptgEpTnBfx9t/cNqfieqL+belq7JvbnuAUDfEyOlj9rxhDzMbJA2DIWSzISrY1Q21UGxjyhENsk0EflVURTUShHzLc30Y3/YlgumUhC2a1zs9H3TPqRJzMEjRC5G645OHEgw2WvrU= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: epam.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Oct 2017 19:33:41.4137 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b41b72d0-4e9f-4c26-8a69-f949f367c91d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR0301MB2130 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 --- * optee_allocate_pages_array() and friends were renamed to optee_allocate_pages_list() (and friends) to make naming consistent. * Reworked get_pages_list_size(). Now calculations are right. Thanks to Mark Rutland for suggestion. * Totaly reworked optee_fill_pages_list(). Now it support all possible page sizes. It was tested on qemu with page sizes of 4k and 64k. --- 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..2366300 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: Fri, 13 Oct 2017 22:32:36 +0300 Subject: [PATCH v1 06/14] tee: optee: add page list manipulation functions In-Reply-To: <1507923164-12796-1-git-send-email-volodymyr_babchuk@epam.com> References: <1506621851-6929-1-git-send-email-volodymyr_babchuk@epam.com> <1507923164-12796-1-git-send-email-volodymyr_babchuk@epam.com> Message-ID: <1507923164-12796-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 --- * optee_allocate_pages_array() and friends were renamed to optee_allocate_pages_list() (and friends) to make naming consistent. * Reworked get_pages_list_size(). Now calculations are right. Thanks to Mark Rutland for suggestion. * Totaly reworked optee_fill_pages_list(). Now it support all possible page sizes. It was tested on qemu with page sizes of 4k and 64k. --- 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..2366300 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