From patchwork Fri Sep 7 22:37:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 10592667 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 2DF5714E2 for ; Fri, 7 Sep 2018 22:36:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E0A52B030 for ; Fri, 7 Sep 2018 22:36:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 126832B2ED; Fri, 7 Sep 2018 22:36:52 +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 A0AB32B030 for ; Fri, 7 Sep 2018 22:36:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726452AbeIHDT6 (ORCPT ); Fri, 7 Sep 2018 23:19:58 -0400 Received: from mga09.intel.com ([134.134.136.24]:25505 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726378AbeIHDT6 (ORCPT ); Fri, 7 Sep 2018 23:19:58 -0400 X-Amp-Result: UNSCANNABLE X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Sep 2018 15:36:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,344,1531810800"; d="scan'208";a="71508767" Received: from alison-desk.jf.intel.com ([10.54.74.53]) by orsmga008.jf.intel.com with ESMTP; 07 Sep 2018 15:36:27 -0700 Date: Fri, 7 Sep 2018 15:37:10 -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 07/12] x86/mm: Add helper functions to track encrypted VMA's Message-ID: 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 In order to safely manage the usage of memory encryption keys, VMA's using each keyid need to be tracked. This tracking allows the Kernel Key Service to know when the keyid resource is actually in use, or when it is idle and may be considered for reuse. Define a global atomic encrypt_count array to track the number of VMA's oustanding for each encryption keyid. Implement helper functions to manipulate this encrypt_count array. Signed-off-by: Alison Schofield --- arch/x86/include/asm/mktme.h | 7 +++++++ arch/x86/mm/mktme.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/mm.h | 2 ++ 3 files changed, 48 insertions(+) diff --git a/arch/x86/include/asm/mktme.h b/arch/x86/include/asm/mktme.h index b707f800b68f..5f3fa0c39c1c 100644 --- a/arch/x86/include/asm/mktme.h +++ b/arch/x86/include/asm/mktme.h @@ -16,6 +16,13 @@ extern int mktme_keyid_shift; /* Set the encryption keyid bits in a VMA */ extern void mprotect_set_encrypt(struct vm_area_struct *vma, int newkeyid); +/* Manage the references to outstanding VMA's per encryption key */ +extern int vma_alloc_encrypt_array(void); +extern void vma_free_encrypt_array(void); +extern int vma_read_encrypt_ref(int keyid); +extern void vma_get_encrypt_ref(struct vm_area_struct *vma); +extern void vma_put_encrypt_ref(struct vm_area_struct *vma); + /* Manage mappings between hardware keyids and userspace keys */ extern int mktme_map_alloc(void); extern void mktme_map_free(void); diff --git a/arch/x86/mm/mktme.c b/arch/x86/mm/mktme.c index 5ee7f37e9cd0..5690ef51a79a 100644 --- a/arch/x86/mm/mktme.c +++ b/arch/x86/mm/mktme.c @@ -163,6 +163,45 @@ int mktme_map_get_free_keyid(void) return 0; } +/* + * Helper functions manage the encrypt_count[] array that tracks the + * VMA's outstanding for each encryption keyid. The gets & puts are + * used in core mm code that allocates and free's VMA's. The alloc, + * free, and read functions are used by the MKTME key service to + * manage key allocation and programming. + */ +atomic_t *encrypt_count; + +int vma_alloc_encrypt_array(void) +{ + encrypt_count = kcalloc(mktme_nr_keyids, sizeof(atomic_t), GFP_KERNEL); + if (!encrypt_count) + return -ENOMEM; + return 0; +} + +void vma_free_encrypt_array(void) +{ + kfree(encrypt_count); +} + +int vma_read_encrypt_ref(int keyid) +{ + return atomic_read(&encrypt_count[keyid]); +} + +void vma_get_encrypt_ref(struct vm_area_struct *vma) +{ + if (vma_keyid(vma)) + atomic_inc(&encrypt_count[vma_keyid(vma)]); +} + +void vma_put_encrypt_ref(struct vm_area_struct *vma) +{ + if (vma_keyid(vma)) + atomic_dec(&encrypt_count[vma_keyid(vma)]); +} + void prep_encrypted_page(struct page *page, int order, int keyid, bool zero) { int i; diff --git a/include/linux/mm.h b/include/linux/mm.h index 0f9422c7841e..b217c699dbab 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2803,6 +2803,8 @@ static inline void setup_nr_node_ids(void) {} #ifndef CONFIG_X86_INTEL_MKTME static inline void mprotect_set_encrypt(struct vm_area_struct *vma, int newkeyid) {} +static inline void vma_get_encrypt_ref(struct vm_area_struct *vma) {} +static inline void vma_put_encrypt_ref(struct vm_area_struct *vma) {} #endif /* CONFIG_X86_INTEL_MKTME */ #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */