BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC);
        BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK);
 
-       if (flags & ~(TFD_CLOEXEC | TFD_NONBLOCK))
-               return -EINVAL;
-       if (clockid != CLOCK_MONOTONIC &&
-           clockid != CLOCK_REALTIME)
+       if ((flags & ~TFD_CREATE_FLAGS) ||
+           (clockid != CLOCK_MONOTONIC &&
+            clockid != CLOCK_REALTIME))
                return -EINVAL;
 
        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
        hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS);
 
        ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx,
-                              flags & (O_CLOEXEC | O_NONBLOCK));
+                              flags & TFD_SHARED_FCNTL_FLAGS);
        if (ufd < 0)
                kfree(ctx);
 
        if (copy_from_user(&ktmr, utmr, sizeof(ktmr)))
                return -EFAULT;
 
-       if (!timespec_valid(&ktmr.it_value) ||
+       if ((flags & ~TFD_SETTIME_FLAGS) ||
+           !timespec_valid(&ktmr.it_value) ||
            !timespec_valid(&ktmr.it_interval))
                return -EINVAL;
 
 
 /* For O_CLOEXEC and O_NONBLOCK */
 #include <linux/fcntl.h>
 
-/* Flags for timerfd_settime.  */
+/*
+ * CAREFUL: Check include/asm-generic/fcntl.h when defining
+ * new flags, since they might collide with O_* ones. We want
+ * to re-use O_* flags that couldn't possibly have a meaning
+ * from eventfd, in order to leave a free define-space for
+ * shared O_* flags.
+ */
 #define TFD_TIMER_ABSTIME (1 << 0)
-
-/* Flags for timerfd_create.  */
 #define TFD_CLOEXEC O_CLOEXEC
 #define TFD_NONBLOCK O_NONBLOCK
 
+#define TFD_SHARED_FCNTL_FLAGS (TFD_CLOEXEC | TFD_NONBLOCK)
+/* Flags for timerfd_create.  */
+#define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS
+/* Flags for timerfd_settime.  */
+#define TFD_SETTIME_FLAGS TFD_TIMER_ABSTIME
 
 #endif /* _LINUX_TIMERFD_H */
-