From: Ira Weiny <ira.we...@intel.com> x86 is missing a hardware check for pkey support in pkey_free(). While the net result is the same (-EINVAL returned), pkey_free() has well defined behavior which will be easier to maintain in one place.
For powerpc the return code is -1 rather than -EINVAL. This changes that behavior slightly but this is very unlikely to break any user space. Lift the checks for pkey_free() to the core mm code and ensure consistency with returning -EINVAL. Cc: ah...@chromium.org Cc: cleme...@chromium.org Cc: gdee...@chromium.org Cc: jkumme...@chromium.org Cc: manosk...@chromium.org Cc: thiba...@chromium.org Cc: Florian Weimer <fwei...@redhat.com> Cc: Andrew Morton <a...@linux-foundation.org> Cc: linux-...@vger.kernel.org Cc: Sohil Mehta <sohil.me...@intel.com> Cc: Dave Hansen <dave.han...@linux.intel.com> Cc: Aneesh Kumar K.V <aneesh.ku...@linux.ibm.com> Signed-off-by: Ira Weiny <ira.we...@intel.com> --- Thanks to Sohil for suggesting I mention the powerpc return value in the commit message. Also Sohil suggested changing mm_pkey_free() from int to void. This is added as a separate patch with his suggested by. --- arch/powerpc/include/asm/pkeys.h | 6 ------ arch/x86/include/asm/pkeys.h | 3 --- mm/mprotect.c | 8 ++++++-- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h index 2c8351248793..e96aa91f817b 100644 --- a/arch/powerpc/include/asm/pkeys.h +++ b/arch/powerpc/include/asm/pkeys.h @@ -107,12 +107,6 @@ static inline int mm_pkey_alloc(struct mm_struct *mm) static inline int mm_pkey_free(struct mm_struct *mm, int pkey) { - if (!mmu_has_feature(MMU_FTR_PKEY)) - return -1; - - if (!mm_pkey_is_allocated(mm, pkey)) - return -EINVAL; - __mm_pkey_free(mm, pkey); return 0; diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h index 2e6c04d8a45b..da02737cc4d1 100644 --- a/arch/x86/include/asm/pkeys.h +++ b/arch/x86/include/asm/pkeys.h @@ -107,9 +107,6 @@ int mm_pkey_alloc(struct mm_struct *mm) static inline int mm_pkey_free(struct mm_struct *mm, int pkey) { - if (!mm_pkey_is_allocated(mm, pkey)) - return -EINVAL; - mm_set_pkey_free(mm, pkey); return 0; diff --git a/mm/mprotect.c b/mm/mprotect.c index 56d35de33725..41458e729c27 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -803,10 +803,14 @@ SYSCALL_DEFINE2(pkey_alloc, unsigned long, flags, unsigned long, init_val) SYSCALL_DEFINE1(pkey_free, int, pkey) { - int ret; + int ret = -EINVAL; + + if (!arch_pkeys_enabled()) + return ret; mmap_write_lock(current->mm); - ret = mm_pkey_free(current->mm, pkey); + if (mm_pkey_is_allocated(current->mm, pkey)) + ret = mm_pkey_free(current->mm, pkey); mmap_write_unlock(current->mm); /* -- 2.35.1