Files
omarchy-pkgs/pkgbuilds/linux-omarchy-eevdf/0852-futex-wait-multiple-abi-fixes.patch
T

89 lines
2.5 KiB
Diff

diff --git a/include/uapi/linux/futex.h b/include/uapi/linux/futex.h
--- a/include/uapi/linux/futex.h
+++ b/include/uapi/linux/futex.h
@@ -134,7 +134,7 @@
* @bitset: Bitset for the optional bitmasked wakeup
*/
struct futex_wait_block {
- __u32 __user *uaddr;
+ __aligned_u64 uaddr;
__u32 val;
__u32 bitset;
};
diff --git a/kernel/futex/syscalls.c b/kernel/futex/syscalls.c
--- a/kernel/futex/syscalls.c
+++ b/kernel/futex/syscalls.c
@@ -198,7 +198,8 @@
* initialize the fields) and then, for each futex_wait_block element from
* userspace, fill a futex_q element with proper values.
*/
-static inline struct futex_vector *futex_read_wait_block(u32 __user *uaddr, u32 count)
+static inline struct futex_vector *futex_read_wait_block(u32 __user *uaddr, u32 count,
+ unsigned int flags)
{
unsigned int i;
struct futex_vector *futexv;
@@ -219,10 +220,17 @@
return ERR_PTR(-EFAULT);
}
- futexv[i].w.flags = FUTEX_32;
+ if (!fwb.bitset) {
+ kfree(futexv);
+ return ERR_PTR(-EINVAL);
+ }
+
+ futexv[i].w.flags = flags;
futexv[i].w.val = fwb.val;
- futexv[i].w.uaddr = (uintptr_t) (fwb.uaddr);
+ futexv[i].w.uaddr = fwb.uaddr;
futexv[i].q = futex_q_init;
+ futexv[i].q.bitset = fwb.bitset;
+ futexv[i].q.wake = futex_wake_mark;
}
return futexv;
@@ -231,17 +239,21 @@
int futex_wait_multiple(struct futex_vector *vs, unsigned int count,
struct hrtimer_sleeper *to);
-static int futex_opcode_31(ktime_t *abs_time, u32 __user *uaddr, int count)
+static int futex_opcode_31(ktime_t *abs_time, u32 __user *uaddr, int count, int op)
{
int ret;
struct futex_vector *vs;
struct hrtimer_sleeper *to = NULL, timeout;
+ unsigned int flags = futex_to_flags(op);
+
+ if (flags & FLAGS_CLOCKRT)
+ return -ENOSYS;
- vs = futex_read_wait_block(uaddr, count);
+ vs = futex_read_wait_block(uaddr, count, flags);
if (IS_ERR(vs))
return PTR_ERR(vs);
- to = futex_setup_timer(abs_time, &timeout, 0, 0);
+ to = futex_setup_timer(abs_time, &timeout, flags, current->timer_slack_ns);
ret = futex_wait_multiple(vs, count, abs_time ? to : NULL);
kfree(vs);
@@ -274,7 +286,7 @@
}
if (cmd == FUTEX_WAIT_MULTIPLE)
- return futex_opcode_31(tp, uaddr, val);
+ return futex_opcode_31(tp, uaddr, val, op);
return do_futex(uaddr, op, val, tp, uaddr2, (unsigned long)utime, val3);
}
@@ -591,7 +603,7 @@
}
if (cmd == FUTEX_WAIT_MULTIPLE)
- return futex_opcode_31(tp, uaddr, val);
+ return futex_opcode_31(tp, uaddr, val, op);
return do_futex(uaddr, op, val, tp, uaddr2, (unsigned long)utime, val3);
}