From patchwork Fri Sep 7 22:36:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 10592653 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0445B1515 for ; Fri, 7 Sep 2018 22:35:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E774C2B030 for ; Fri, 7 Sep 2018 22:35:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DAFF82B2ED; Fri, 7 Sep 2018 22:35:31 +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=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 43E322B030 for ; Fri, 7 Sep 2018 22:35:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726561AbeIHDSi (ORCPT ); Fri, 7 Sep 2018 23:18:38 -0400 Received: from mga18.intel.com ([134.134.136.126]:12494 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726284AbeIHDSi (ORCPT ); Fri, 7 Sep 2018 23:18:38 -0400 X-Amp-Result: UNSCANNABLE X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Sep 2018 15:35:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,344,1531810800"; d="scan'208";a="71260822" Received: from alison-desk.jf.intel.com ([10.54.74.53]) by orsmga007.jf.intel.com with ESMTP; 07 Sep 2018 15:35:29 -0700 Date: Fri, 7 Sep 2018 15:36:12 -0700 From: Alison Schofield To: dhowells@redhat.com, tglx@linutronix.de Cc: Kai Huang , Jun Nakajima , Kirill Shutemov , Dave Hansen , Jarkko Sakkinen , jmorris@namei.org, keyrings@vger.kernel.org, linux-security-module@vger.kernel.org, mingo@redhat.com, hpa@zytor.com, x86@kernel.org, linux-mm@kvack.org Subject: [RFC 04/12] x86/mm: Add helper functions to manage memory encryption keys Message-ID: <28a55df5da1ecfea28bac588d3ac429cf1419b42.1536356108.git.alison.schofield@intel.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Define a global mapping structure to track the mapping of userspace keys to hardware keyids in MKTME (Multi-Key Total Memory Encryption). This data will be used for the memory encryption system call and the kernel key service API. Implement helper functions to access this mapping structure and make them visible to the MKTME Kernel Key Service: security/keys/mktme_keys Signed-off-by: Alison Schofield --- arch/x86/include/asm/mktme.h | 11 ++++++ arch/x86/mm/mktme.c | 85 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/arch/x86/include/asm/mktme.h b/arch/x86/include/asm/mktme.h index dbfbd955da98..f6acd551457f 100644 --- a/arch/x86/include/asm/mktme.h +++ b/arch/x86/include/asm/mktme.h @@ -13,6 +13,17 @@ extern phys_addr_t mktme_keyid_mask; extern int mktme_nr_keyids; extern int mktme_keyid_shift; +/* Manage mappings between hardware keyids and userspace keys */ +extern int mktme_map_alloc(void); +extern void mktme_map_free(void); +extern void mktme_map_lock(void); +extern void mktme_map_unlock(void); +extern int mktme_map_get_free_keyid(void); +extern void mktme_map_clear_keyid(int keyid); +extern void mktme_map_set_keyid(int keyid, unsigned int serial); +extern int mktme_map_keyid_from_serial(unsigned int serial); +extern unsigned int mktme_map_serial_from_keyid(int keyid); + extern struct page_ext_operations page_mktme_ops; #define page_keyid page_keyid diff --git a/arch/x86/mm/mktme.c b/arch/x86/mm/mktme.c index 660caf6a5ce1..5246d8323359 100644 --- a/arch/x86/mm/mktme.c +++ b/arch/x86/mm/mktme.c @@ -63,6 +63,91 @@ int vma_keyid(struct vm_area_struct *vma) return (prot & mktme_keyid_mask) >> mktme_keyid_shift; } +/* + * struct mktme_mapping and the mktme_map_* functions manage the mapping + * of userspace keys to hardware keyids in MKTME. They are used by the + * the encrypt_mprotect system call and the MKTME Key Service API. + */ +struct mktme_mapping { + struct mutex lock; /* protect this map & HW state */ + unsigned int mapped_keyids; + unsigned int serial[]; +}; + +struct mktme_mapping *mktme_map; + +static inline long mktme_map_size(void) +{ + long size = 0; + + size += sizeof(mktme_map); + size += sizeof(mktme_map->serial[0]) * mktme_nr_keyids; + return size; +} + +int mktme_map_alloc(void) +{ + mktme_map = kzalloc(mktme_map_size(), GFP_KERNEL); + if (!mktme_map) + return 0; + mutex_init(&mktme_map->lock); + return 1; +} + +void mktme_map_free(void) +{ + kfree(mktme_map); +} + +void mktme_map_lock(void) +{ + mutex_lock(&mktme_map->lock); +} + +void mktme_map_unlock(void) +{ + mutex_unlock(&mktme_map->lock); +} + +void mktme_map_set_keyid(int keyid, unsigned int serial) +{ + mktme_map->serial[keyid] = serial; + mktme_map->mapped_keyids++; +} + +void mktme_map_clear_keyid(int keyid) +{ + mktme_map->serial[keyid] = 0; + mktme_map->mapped_keyids--; +} + +unsigned int mktme_map_serial_from_keyid(int keyid) +{ + return mktme_map->serial[keyid]; +} + +int mktme_map_keyid_from_serial(unsigned int serial) +{ + int i; + + for (i = 1; i < mktme_nr_keyids; i++) + if (mktme_map->serial[i] == serial) + return i; + return 0; +} + +int mktme_map_get_free_keyid(void) +{ + int i; + + if (mktme_map->mapped_keyids < mktme_nr_keyids) { + for (i = 1; i < mktme_nr_keyids; i++) + if (mktme_map->serial[i] == 0) + return i; + } + return 0; +} + void prep_encrypted_page(struct page *page, int order, int keyid, bool zero) { int i;