Jens Axboe <axboe@xxxxxxxxx> writes: > From: Peter Zijlstra <peterz@xxxxxxxxxxxxx> > > Futex has 3 sets of flags: > > - legacy futex op bits > - futex2 flags > - internal flags > > Add a few helpers to convert from the API flags into the internal > flags. > > Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> > Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> > --- > kernel/futex/futex.h | 64 +++++++++++++++++++++++++++++++++++++++-- > kernel/futex/syscalls.c | 24 ++++++---------- > kernel/futex/waitwake.c | 4 +-- > 3 files changed, 72 insertions(+), 20 deletions(-) > > diff --git a/kernel/futex/futex.h b/kernel/futex/futex.h > index b5379c0e6d6d..c0e04599904a 100644 > --- a/kernel/futex/futex.h > +++ b/kernel/futex/futex.h > @@ -5,6 +5,7 @@ > #include <linux/futex.h> > #include <linux/rtmutex.h> > #include <linux/sched/wake_q.h> > +#include <linux/compat.h> > > #ifdef CONFIG_PREEMPT_RT > #include <linux/rcuwait.h> > @@ -16,8 +17,15 @@ > * Futex flags used to encode options to functions and preserve them across > * restarts. > */ > +#define FLAGS_SIZE_8 0x00 > +#define FLAGS_SIZE_16 0x01 > +#define FLAGS_SIZE_32 0x02 > +#define FLAGS_SIZE_64 0x03 > + > +#define FLAGS_SIZE_MASK 0x03 > + > #ifdef CONFIG_MMU > -# define FLAGS_SHARED 0x01 > +# define FLAGS_SHARED 0x10 > #else > /* > * NOMMU does not have per process address space. Let the compiler optimize > @@ -25,8 +33,58 @@ > */ > # define FLAGS_SHARED 0x00 > #endif > -#define FLAGS_CLOCKRT 0x02 > -#define FLAGS_HAS_TIMEOUT 0x04 > +#define FLAGS_CLOCKRT 0x20 > +#define FLAGS_HAS_TIMEOUT 0x40 > +#define FLAGS_NUMA 0x80 > + > +/* FUTEX_ to FLAGS_ */ > +static inline unsigned int futex_to_flags(unsigned int op) > +{ > + unsigned int flags = FLAGS_SIZE_32; > + > + if (!(op & FUTEX_PRIVATE_FLAG)) > + flags |= FLAGS_SHARED; > + > + if (op & FUTEX_CLOCK_REALTIME) > + flags |= FLAGS_CLOCKRT; > + > + return flags; > +} > + > +/* FUTEX2_ to FLAGS_ */ > +static inline unsigned int futex2_to_flags(unsigned int flags2) > +{ > + unsigned int flags = flags2 & FUTEX2_64; FUTEX2_64 -> FLAGS_SIZE_MASK > + > + if (!(flags2 & FUTEX2_PRIVATE)) > + flags |= FLAGS_SHARED; > + > + if (flags2 & FUTEX2_NUMA) > + flags |= FLAGS_NUMA; > + > + return flags; > +} > + > +static inline bool futex_flags_valid(unsigned int flags) > +{ > + /* Only 64bit futexes for 64bit code */ > + if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall()) { > + if ((flags & FLAGS_SIZE_MASK) == FLAGS_SIZE_64) > + return false; > + } I read the comment above as '64bit code can only have 64bit futexes', which is obviously wrong and not what the code is checking. Something like this would be better: /* Reject 64bit futexes on !64bit code. */ Or Perhaps make it generic: /* Don't allow futexes larger than the word size */ if (futex_size(flags) > (__WORDSIZE/8) || in_compat_syscall()) -- Gabriel Krisman Bertazi