Received: by 10.223.164.202 with SMTP id h10csp17985wrb; Mon, 6 Nov 2017 01:40:08 -0800 (PST) X-Google-Smtp-Source: ABhQp+RearvoM2PgtK5+NiLqZ00DYmVmww52HjzGJE/Zomp4XJzeuxk9dLuzQSEVq3ATxswSDUrB X-Received: by 10.84.229.5 with SMTP id b5mr14447906plk.405.1509961208311; Mon, 06 Nov 2017 01:40:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1509961208; cv=none; d=google.com; s=arc-20160816; b=wqBF1K6j744Xli2XhrVtgjMP/FTCF2BLIMFigsR1kJHP/ESLZzGDL8CAF6SFKWBn6+ W7SF5c1EiCnEQS+fMJtxtwMBaAxykq3lADgZmB/rdABhznbXjXwYrEu/U2zQ0XZ1WmN/ Utrw6P47q/uylk9Hd8uHBDG+SvZ/lkLd04DGtU7rQ/FgLlHvOjHbEOTrb3CMHylenwjh 2Hz/OB/kAHiPC5CieS0LFQmUL5FuaMcQDITEmAHUePi0ONDM7zqUa2NVpaffY+/gGj2O i1Qca5yGKL33xQ7oQBqGELPsfyzs97e/MgmwMppNYV5xTi1xhI6FL2BseNCaOKcmKDzh RJ3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=53nGVeoLR1FOYTinmTzbOcIU3Rgr7GUfmOMuAyOtunw=; b=AkiwV5VM53y4Uu5xV6Rglgdb6pXrzNTFc/HNJ+vRlf+jJe5OEuoNzMn/5XM8ANbQdF rcSaTj4YFfomTYDxSZSLjGWQS8CqvSa0+Y+uCf245iObozGcWbloTEo4lTBPWkaIag2D ntGp7hmJ37RCqzYaOxZm7TxEhwhLYEt7oPkPk65oj1nNGtN4WeryZd3Tpow/qq8FIAGv 95HjsoH0qWuBuHwRmSY25kWopN4/g58Qa6kpPAmS1l2Wlko2He7yu+zb0PleqiNLfJVs IiBX4p+tdl+iCb/wuUkn8kjdmwE65H5BhYqiCgpjlGx5btFdYPCeSWKQ9N5AcM5VwlJs Lkrw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=LZbk6qtz; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f17si11092561pga.566.2017.11.06.01.39.54; Mon, 06 Nov 2017 01:40:08 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=LZbk6qtz; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752119AbdKFI6h (ORCPT + 98 others); Mon, 6 Nov 2017 03:58:37 -0500 Received: from mail-qk0-f196.google.com ([209.85.220.196]:46082 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752001AbdKFI6c (ORCPT ); Mon, 6 Nov 2017 03:58:32 -0500 Received: by mail-qk0-f196.google.com with SMTP id o6so3052192qkh.3; Mon, 06 Nov 2017 00:58:32 -0800 (PST) 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=53nGVeoLR1FOYTinmTzbOcIU3Rgr7GUfmOMuAyOtunw=; b=LZbk6qtz12hk5dbJjWlZHbxPQ+tiZGT8yOlG7rvID4En0/7R7GyFB7Tm46G1VRgyuc fwQBnoYmVB+1WHyV23Ch23UG6tnRAus5gX6CyZjpIXc25i89taLYm0KxlSoHfdoNhPXb LfIt8Ua4Q2PWL0ZNBlEpO3WdDLE5NnY+8FUECSMXXp3NcgchWhP0IUJaY8OeP114Zq+b rSNUmVYVcEtpctGmdfnLc0Z2SydAQbBUMLaBOoe/9OrnKDCoHpYNGO/y8SUof4XAlJoV x8j98+qlvsleRjM8PhvjCo7waDgbV4VY4UbR4vyLmbRjOtLddNvLP9cvJ5NLZj4wUFWU W6CQ== 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=53nGVeoLR1FOYTinmTzbOcIU3Rgr7GUfmOMuAyOtunw=; b=FwlCGpsDJsvE0DLH7bULZeOfzSs8YD4z6V1J3qEGOYtwGClJccsTMmuu+4nPUZHE+r 3XoaouDlUvUh1mKRRMkiwvXxSIhp+ZyVrXhgR+AWKgwDUPhCqRxe6BKwliYRKwgtmP5d nZJognhqSDTFIBeH5xA45H/4wOD7z+9G6iUd8e/H5PPLOPG9yUvajnTQ4tiqFXryxDz9 KNycEJorLrRb41icl/DwqhN4w6Ba3WGYSDNKtxWeqi9xckhNH6PUz+BBQLpugZbL8BlJ aFxKJ9PanQufFwV/oReC5z9VZ3b60XfbdvxlR4tnk0KhLSc2cNVo9FKpkEJloQzzOdpu 3dvQ== X-Gm-Message-State: AMCzsaXs7Xo+K67637eNG4KvizYoVhnHwgWgzEG6jFMLPwJMoT8PGkZt eEZ/ZGq2xLDHkAO2TNJZdPk= X-Received: by 10.55.184.71 with SMTP id i68mr19564059qkf.150.1509958711551; Mon, 06 Nov 2017 00:58:31 -0800 (PST) Received: from localhost.localdomain (50-39-103-96.bvtn.or.frontiernet.net. [50.39.103.96]) by smtp.gmail.com with ESMTPSA id r26sm8001094qki.42.2017.11.06.00.58.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 06 Nov 2017 00:58:31 -0800 (PST) From: Ram Pai To: mpe@ellerman.id.au, mingo@redhat.com, akpm@linux-foundation.org, corbet@lwn.net, arnd@arndb.de Cc: linuxppc-dev@lists.ozlabs.org, linux-mm@kvack.org, x86@kernel.org, linux-arch@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, dave.hansen@intel.com, benh@kernel.crashing.org, paulus@samba.org, khandual@linux.vnet.ibm.com, aneesh.kumar@linux.vnet.ibm.com, bsingharora@gmail.com, hbabu@us.ibm.com, mhocko@kernel.org, bauerman@linux.vnet.ibm.com, ebiederm@xmission.com, linuxram@us.ibm.com Subject: [PATCH v9 04/51] powerpc: track allocation status of all pkeys Date: Mon, 6 Nov 2017 00:56:56 -0800 Message-Id: <1509958663-18737-5-git-send-email-linuxram@us.ibm.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1509958663-18737-1-git-send-email-linuxram@us.ibm.com> References: <1509958663-18737-1-git-send-email-linuxram@us.ibm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Total 32 keys are available on power7 and above. However pkey 0,1 are reserved. So effectively we have 30 pkeys. On 4K kernels, we do not have 5 bits in the PTE to represent all the keys; we only have 3bits.Two of those keys are reserved; pkey 0 and pkey 1. So effectively we have 6 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. Reviewed-by: Thiago Jung Bauermann 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 | 95 ++++++++++++++++++++++++++++- arch/powerpc/mm/mmu_context_book3s64.c | 2 + arch/powerpc/mm/pkeys.c | 33 ++++++++++ 5 files changed, 136 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 37fdede..df17fbc 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_PPC_MEM_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 2c24447..6d7c4f1 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -145,6 +145,7 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, #ifndef CONFIG_PPC_MEM_KEYS #define pkey_initialize() +#define pkey_mm_init(mm) #endif /* CONFIG_PPC_MEM_KEYS */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h index a54cb39..e5deac7 100644 --- a/arch/powerpc/include/asm/pkeys.h +++ b/arch/powerpc/include/asm/pkeys.h @@ -15,21 +15,101 @@ #include DECLARE_STATIC_KEY_TRUE(pkey_disabled); -#define ARCH_VM_PKEY_FLAGS 0 +extern int pkeys_total; /* total pkeys as per device tree */ +extern u32 initial_allocation_mask; /* bits set for reserved keys */ + +/* + * powerpc needs VM_PKEY_BIT* bit to enable pkey system. + * Without them, at least compilation needs to succeed. + */ +#ifndef VM_PKEY_BIT0 +#define VM_PKEY_SHIFT 0 +#define VM_PKEY_BIT0 0 +#define VM_PKEY_BIT1 0 +#define VM_PKEY_BIT2 0 +#define VM_PKEY_BIT3 0 +#endif + +/* + * powerpc needs an additional vma bit to support 32 keys. Till the additional + * vma bit lands in include/linux/mm.h we can only support 16 keys. + */ +#ifndef VM_PKEY_BIT4 +#define VM_PKEY_BIT4 0 +#endif + +#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ + VM_PKEY_BIT3 | VM_PKEY_BIT4) + +#define arch_max_pkey() pkeys_total + +#define pkey_alloc_mask(pkey) (0x1 << pkey) + +#define mm_pkey_allocation_map(mm) (mm->context.pkey_allocation_map) + +#define __mm_pkey_allocated(mm, pkey) { \ + mm_pkey_allocation_map(mm) |= pkey_alloc_mask(pkey); \ +} + +#define __mm_pkey_free(mm, pkey) { \ + mm_pkey_allocation_map(mm) &= ~pkey_alloc_mask(pkey); \ +} + +#define __mm_pkey_is_allocated(mm, pkey) \ + (mm_pkey_allocation_map(mm) & pkey_alloc_mask(pkey)) + +#define __mm_pkey_is_reserved(pkey) (initial_allocation_mask & \ + pkey_alloc_mask(pkey)) static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) { - return false; + /* A reserved key is never considered as 'explicitly allocated' */ + return ((pkey < arch_max_pkey()) && + !__mm_pkey_is_reserved(pkey) && + __mm_pkey_is_allocated(mm, pkey)); } +/* + * Returns a positive, 5-bit key on success, or -1 on failure. + * Relies on the mmap_sem to protect against concurrency in mm_pkey_alloc() and + * mm_pkey_free(). + */ 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 (static_branch_likely(&pkey_disabled)) + 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 = ffz((u32)mm_pkey_allocation_map(mm)); + __mm_pkey_allocated(mm, ret); + return ret; } static inline int mm_pkey_free(struct mm_struct *mm, int pkey) { - return -EINVAL; + if (static_branch_likely(&pkey_disabled)) + return -1; + + if (!mm_pkey_is_allocated(mm, pkey)) + return -EINVAL; + + __mm_pkey_free(mm, pkey); + + return 0; } /* @@ -53,5 +133,12 @@ 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 (static_branch_likely(&pkey_disabled)) + return; + mm_pkey_allocation_map(mm) = initial_allocation_mask; +} + extern void pkey_initialize(void); #endif /*_ASM_POWERPC_KEYS_H */ diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c index 05e1538..5df223a 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 @@ -118,6 +119,7 @@ static int hash__init_new_context(struct mm_struct *mm) subpage_prot_init_new_context(mm); + pkey_mm_init(mm); return index; } diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c index c97a7a0..512bdf2 100644 --- a/arch/powerpc/mm/pkeys.c +++ b/arch/powerpc/mm/pkeys.c @@ -13,18 +13,51 @@ DEFINE_STATIC_KEY_TRUE(pkey_disabled); bool pkey_execute_disable_supported; +int pkeys_total; /* Total pkeys as per device tree */ +u32 initial_allocation_mask; /* Bits set for reserved keys */ void __init pkey_initialize(void) { + int os_reserved, i; + /* * Disable the pkey system till everything is in place. A subsequent * patch will enable it. */ static_branch_enable(&pkey_disabled); + /* Lets assume 32 keys */ + pkeys_total = 32; + + /* + * Adjust the upper limit, based on the number of bits supported by + * arch-neutral code. + */ + pkeys_total = min_t(int, pkeys_total, + (ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT)); + /* * Disable execute_disable support for now. A subsequent patch will * enable it. */ pkey_execute_disable_supported = false; + +#ifdef CONFIG_PPC_4K_PAGES + /* + * The OS can manage only 8 pkeys due to its inability to represent them + * in the Linux 4K PTE. + */ + os_reserved = pkeys_total - 8; +#else + os_reserved = 0; +#endif + /* + * Bits are in LE format. NOTE: 1, 0 are reserved. + * key 0 is the default key, which allows read/write/execute. + * key 1 is recommended not to be used. PowerISA(3.0) page 1015, + * programming note. + */ + initial_allocation_mask = ~0x0; + for (i = 2; i < (pkeys_total - os_reserved); i++) + initial_allocation_mask &= ~(0x1 << i); } -- 1.7.1 From 1583346967196310157@xxx Mon Nov 06 19:42:16 +0000 2017 X-GM-THRID: 1583346967196310157 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread