From patchwork Sun Jul 16 03:56:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ram Pai X-Patchwork-Id: 789008 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3x9Czg0cjVz9s4s for ; Sun, 16 Jul 2017 14:26:23 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="bj3s5vZm"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3x9Czf6dNszDqn3 for ; Sun, 16 Jul 2017 14:26:22 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="bj3s5vZm"; dkim-atps=neutral X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from mail-qt0-x241.google.com (mail-qt0-x241.google.com [IPv6:2607:f8b0:400d:c0d::241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3x9CMb44X6zDqmy for ; Sun, 16 Jul 2017 13:58:35 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="bj3s5vZm"; dkim-atps=neutral Received: by mail-qt0-x241.google.com with SMTP id w12so14715392qta.2 for ; Sat, 15 Jul 2017 20:58:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=uoaA27gUZFoeovViV6bdEYHwOLpY+UNFPXIeiFVMEY8=; b=bj3s5vZmNLnN7Cb4AtyFq7mUaiU/OCgLHy/Yy5rO4ciYjTTclfWunqyiM3rgDHTGpL 7x/16wkxZL1AenTl5syP80tOhIYSE44g9TFQYrA9S6VG9l8tpkvAR2CFwHKtT7V2BJxd 4PiOeCDpOVRk7d73rUjy8gNxAg5a7vka16MHxZ9bKquhSOIjnETNQBKzq5paj/Ame/G5 aDR9hFmpLqX4T9hl9DKhp/ioLrgnOFrrLU/CcW4jX1uGnfHWJ67e7xqszEWrUtsz/Dgs w802pQTNDsvGega/jSj+UMjL5evQgO1MPkB4mX8QPMDFvuRlJyNYVf0KqaJVW5HNb8pm h90A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=uoaA27gUZFoeovViV6bdEYHwOLpY+UNFPXIeiFVMEY8=; b=CVsYDVp6riK4KP61EbET4UU2dQzZvY3iO61Qe2DPA3GiaMsvBZ2fV6TNNO6plRwWZX ztvO47bxhTUpQk9w3xwqot6/vHJZ8rWZA5cFOpTzJCL32NmCr1vihsFausT77w64YP3S g4koalU+SG8ADV19aCNzyRWQcOkD4OhCCHMWNpDKqdOGsdJsKZbddWjLBjmzZvczn559 uC5Fg/46yOIHnd/ohVlegW8vJqJTc7k9A1nftiLGuqkc9gXHtcGr2RFEBu71C8JRH9Wb ZM+uaTNKRf8sEXKmnV8Xhu2RU6c251mh8rqIIL2Vzo/hT3xIocve+gPCCpKn2H9gkrK6 8tNQ== X-Gm-Message-State: AIVw113MM0+V7qgZQ4vG1MFNbN2RtQiLJegorsEV/L1Xje/7VPiZIZat FDFWk/5je4yExXDVyy8= X-Received: by 10.237.52.194 with SMTP id x60mr21169744qtd.121.1500177513457; Sat, 15 Jul 2017 20:58:33 -0700 (PDT) Received: from localhost.localdomain (50-39-103-96.bvtn.or.frontiernet.net. [50.39.103.96]) by smtp.gmail.com with ESMTPSA id q46sm2290345qtc.54.2017.07.15.20.58.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 15 Jul 2017 20:58:33 -0700 (PDT) From: Ram Pai To: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, linux-mm@kvack.org, x86@kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [RFC v6 13/62] powerpc: track allocation status of all pkeys Date: Sat, 15 Jul 2017 20:56:15 -0700 Message-Id: <1500177424-13695-14-git-send-email-linuxram@us.ibm.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1500177424-13695-1-git-send-email-linuxram@us.ibm.com> References: <1500177424-13695-1-git-send-email-linuxram@us.ibm.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: arnd@arndb.de, corbet@lwn.net, linuxram@us.ibm.com, mhocko@kernel.org, dave.hansen@intel.com, mingo@redhat.com, paulus@samba.org, aneesh.kumar@linux.vnet.ibm.com, akpm@linux-foundation.org, khandual@linux.vnet.ibm.com Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Total 32 keys are supported on powerpc. However pkey 0,1 and 31 are reserved. So effectively we have 29 pkeys. This patch keeps track of reserved keys, allocated keys and keys that are currently free. Also it adds skeletal functions and macros, that the architecture-independent code expects to be available. Signed-off-by: Ram Pai --- arch/powerpc/include/asm/book3s/64/mmu.h | 9 +++ arch/powerpc/include/asm/mmu_context.h | 1 + arch/powerpc/include/asm/pkeys.h | 81 ++++++++++++++++++++++++++++-- arch/powerpc/mm/mmu_context_book3s64.c | 2 + 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 77529a3..104ad72 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h @@ -108,6 +108,15 @@ struct patb_entry { #ifdef CONFIG_SPAPR_TCE_IOMMU struct list_head iommu_group_mem_list; #endif + +#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS + /* + * Each bit represents one protection key. + * bit set -> key allocated + * bit unset -> key available for allocation + */ + u32 pkey_allocation_map; +#endif } mm_context_t; /* diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 4b93547..4705dab 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -184,6 +184,7 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, #ifndef CONFIG_PPC64_MEMORY_PROTECTION_KEYS #define pkey_initialize() +#define pkey_mm_init(mm) #endif /* CONFIG_PPC64_MEMORY_PROTECTION_KEYS */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h index 203d7de..09b268e 100644 --- a/arch/powerpc/include/asm/pkeys.h +++ b/arch/powerpc/include/asm/pkeys.h @@ -2,21 +2,87 @@ #define _ASM_PPC64_PKEYS_H extern bool pkey_inited; -#define ARCH_VM_PKEY_FLAGS 0 +#define arch_max_pkey() 32 +#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ + VM_PKEY_BIT3 | VM_PKEY_BIT4) +/* + * Bits are in BE format. + * NOTE: key 31, 1, 0 are not used. + * key 0 is used by default. It give read/write/execute permission. + * key 31 is reserved by the hypervisor. + * key 1 is recommended to be not used. + * PowerISA(3.0) page 1015, programming note. + */ +#define PKEY_INITIAL_ALLOCAION 0xc0000001 + +#define pkeybit_mask(pkey) (0x1 << (arch_max_pkey() - pkey - 1)) + +#define mm_pkey_allocation_map(mm) (mm->context.pkey_allocation_map) + +#define mm_set_pkey_allocated(mm, pkey) { \ + mm_pkey_allocation_map(mm) |= pkeybit_mask(pkey); \ +} + +#define mm_set_pkey_free(mm, pkey) { \ + mm_pkey_allocation_map(mm) &= ~pkeybit_mask(pkey); \ +} + +#define mm_set_pkey_is_allocated(mm, pkey) \ + (mm_pkey_allocation_map(mm) & pkeybit_mask(pkey)) + +#define mm_set_pkey_is_reserved(mm, pkey) (PKEY_INITIAL_ALLOCAION & \ + pkeybit_mask(pkey)) static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) { - return (pkey == 0); + /* a reserved key is never considered as 'explicitly allocated' */ + return ((pkey < arch_max_pkey()) && + !mm_set_pkey_is_reserved(mm, pkey) && + mm_set_pkey_is_allocated(mm, pkey)); } +/* + * Returns a positive, 5-bit key on success, or -1 on failure. + */ static inline int mm_pkey_alloc(struct mm_struct *mm) { - return -1; + /* + * Note: this is the one and only place we make sure + * that the pkey is valid as far as the hardware is + * concerned. The rest of the kernel trusts that + * only good, valid pkeys come out of here. + */ + u32 all_pkeys_mask = (u32)(~(0x0)); + int ret; + + if (!pkey_inited) + return -1; + /* + * Are we out of pkeys? We must handle this specially + * because ffz() behavior is undefined if there are no + * zeros. + */ + if (mm_pkey_allocation_map(mm) == all_pkeys_mask) + return -1; + + ret = arch_max_pkey() - + ffz((u32)mm_pkey_allocation_map(mm)) + - 1; + mm_set_pkey_allocated(mm, ret); + return ret; } static inline int mm_pkey_free(struct mm_struct *mm, int pkey) { - return -EINVAL; + if (!pkey_inited) + return -1; + + if (!mm_pkey_is_allocated(mm, pkey)) + return -EINVAL; + + mm_set_pkey_free(mm, pkey); + + return 0; } /* @@ -40,6 +106,13 @@ static inline int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, return 0; } +static inline void pkey_mm_init(struct mm_struct *mm) +{ + if (!pkey_inited) + return; + mm_pkey_allocation_map(mm) = PKEY_INITIAL_ALLOCAION; +} + static inline void pkey_initialize(void) { #ifdef CONFIG_PPC_64K_PAGES diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c index a3edf81..34a16f3 100644 --- a/arch/powerpc/mm/mmu_context_book3s64.c +++ b/arch/powerpc/mm/mmu_context_book3s64.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -120,6 +121,7 @@ static int hash__init_new_context(struct mm_struct *mm) subpage_prot_init_new_context(mm); + pkey_mm_init(mm); return index; }