Le 11/06/2022 à 01:35, ira.weiny@xxxxxxxxx a écrit : > From: Ira Weiny <ira.weiny@xxxxxxxxx> > > 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@xxxxxxxxxxxx > Cc: clemensb@xxxxxxxxxxxx > Cc: gdeepti@xxxxxxxxxxxx > Cc: jkummerow@xxxxxxxxxxxx > Cc: manoskouk@xxxxxxxxxxxx > Cc: thibaudm@xxxxxxxxxxxx > Cc: Florian Weimer <fweimer@xxxxxxxxxx> > Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> > Cc: linux-api@xxxxxxxxxxxxxxx > Cc: Sohil Mehta <sohil.mehta@xxxxxxxxx> > Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx> > Cc: Aneesh Kumar K.V <aneesh.kumar@xxxxxxxxxxxxx> > Signed-off-by: Ira Weiny <ira.weiny@xxxxxxxxx> > > --- > 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. > 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. > 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); > > /*