Re: [RFC PATCH 5/6] pkeys: Up level pkey_free() checks
From: Christophe Leroy <hidden>
Date: 2022-06-13 09:14:44
Also in:
linux-api, linux-kselftest, linux-mm, lkml
Le 11/06/2022 à 01:35, ira.weiny@intel.com a écrit :
quoted hunk ↗ jump to hunk
From: Ira Weiny <redacted> 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: ahaas@chromium.org Cc: clemensb@chromium.org Cc: gdeepti@chromium.org Cc: jkummerow@chromium.org Cc: manoskouk@chromium.org Cc: thibaudm@chromium.org Cc: Florian Weimer <redacted> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: linux-api@vger.kernel.org Cc: Sohil Mehta <redacted> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Aneesh Kumar K.V <redacted> Signed-off-by: Ira Weiny <redacted> --- 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;
If it returns always 0, the return value is pointless and the function mm_pkey_free() should be changed to return void.
quoted hunk ↗ jump to hunk
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;
Same.
quoted hunk ↗ jump to hunk
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;
Don't initialise 'ret'
+ + if (!arch_pkeys_enabled()) + return ret;
Make it explicit, do 'return -EINVAL' Once that is done, is there any point in having a fallback version of mm_pkey_free() which returns -EINVAL ?
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);
Add: else ret = -EINVAL;
mmap_write_unlock(current->mm); /*