aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/thread_info.h17
-rw-r--r--kernel/futex.c25
2 files changed, 28 insertions, 14 deletions
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index 1c4eb41dbd89..9c4ad755d7e5 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -7,12 +7,25 @@
7#ifndef _LINUX_THREAD_INFO_H 7#ifndef _LINUX_THREAD_INFO_H
8#define _LINUX_THREAD_INFO_H 8#define _LINUX_THREAD_INFO_H
9 9
10#include <linux/types.h>
11
10/* 12/*
11 * System call restart block. 13 * System call restart block.
12 */ 14 */
13struct restart_block { 15struct restart_block {
14 long (*fn)(struct restart_block *); 16 long (*fn)(struct restart_block *);
15 unsigned long arg0, arg1, arg2, arg3; 17 union {
18 struct {
19 unsigned long arg0, arg1, arg2, arg3;
20 };
21 /* For futex_wait */
22 struct {
23 u32 *uaddr;
24 u32 val;
25 u32 flags;
26 u64 time;
27 } futex;
28 };
16}; 29};
17 30
18extern long do_no_restart_syscall(struct restart_block *parm); 31extern long do_no_restart_syscall(struct restart_block *parm);
diff --git a/kernel/futex.c b/kernel/futex.c
index 9dc591ab681a..e8fbdd7d95ac 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1149,9 +1149,9 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
1149 1149
1150/* 1150/*
1151 * In case we must use restart_block to restart a futex_wait, 1151 * In case we must use restart_block to restart a futex_wait,
1152 * we encode in the 'arg3' shared capability 1152 * we encode in the 'flags' shared capability
1153 */ 1153 */
1154#define ARG3_SHARED 1 1154#define FLAGS_SHARED 1
1155 1155
1156static long futex_wait_restart(struct restart_block *restart); 1156static long futex_wait_restart(struct restart_block *restart);
1157 1157
@@ -1290,12 +1290,13 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared,
1290 struct restart_block *restart; 1290 struct restart_block *restart;
1291 restart = &current_thread_info()->restart_block; 1291 restart = &current_thread_info()->restart_block;
1292 restart->fn = futex_wait_restart; 1292 restart->fn = futex_wait_restart;
1293 restart->arg0 = (unsigned long)uaddr; 1293 restart->futex.uaddr = (u32 *)uaddr;
1294 restart->arg1 = (unsigned long)val; 1294 restart->futex.val = val;
1295 restart->arg2 = (unsigned long)abs_time; 1295 restart->futex.time = abs_time->tv64;
1296 restart->arg3 = 0; 1296 restart->futex.flags = 0;
1297
1297 if (fshared) 1298 if (fshared)
1298 restart->arg3 |= ARG3_SHARED; 1299 restart->futex.flags |= FLAGS_SHARED;
1299 return -ERESTART_RESTARTBLOCK; 1300 return -ERESTART_RESTARTBLOCK;
1300 } 1301 }
1301 1302
@@ -1310,15 +1311,15 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared,
1310 1311
1311static long futex_wait_restart(struct restart_block *restart) 1312static long futex_wait_restart(struct restart_block *restart)
1312{ 1313{
1313 u32 __user *uaddr = (u32 __user *)restart->arg0; 1314 u32 __user *uaddr = (u32 __user *)restart->futex.uaddr;
1314 u32 val = (u32)restart->arg1;
1315 ktime_t *abs_time = (ktime_t *)restart->arg2;
1316 struct rw_semaphore *fshared = NULL; 1315 struct rw_semaphore *fshared = NULL;
1316 ktime_t t;
1317 1317
1318 t.tv64 = restart->futex.time;
1318 restart->fn = do_no_restart_syscall; 1319 restart->fn = do_no_restart_syscall;
1319 if (restart->arg3 & ARG3_SHARED) 1320 if (restart->futex.flags & FLAGS_SHARED)
1320 fshared = &current->mm->mmap_sem; 1321 fshared = &current->mm->mmap_sem;
1321 return (long)futex_wait(uaddr, fshared, val, abs_time); 1322 return (long)futex_wait(uaddr, fshared, restart->futex.val, &t);
1322} 1323}
1323 1324
1324 1325