time/posix-timers: Move the compat copyouts to the nanosleep implementations
Turn restart_block.nanosleep.{rmtp,compat_rmtp} into a tagged union (kind =
1 -> native, kind = 2 -> compat, kind = 0 -> nothing) and make the places
doing actual copyout handle compat as well as native (that will become a
helper in the next commit). Result: compat wrappers, messing with
reassignments, etc. are gone.
[ tglx: Folded in a variant of Peter Zijlstras enum patch ]
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20170607084241.28657-6-viro@ZenIV.linux.org.uk
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include <linux/posix-timers.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/compat.h>
|
||||
|
||||
#include "posix-timers.h"
|
||||
|
||||
@@ -691,7 +692,7 @@ static enum alarmtimer_restart alarmtimer_nsleep_wakeup(struct alarm *alarm,
|
||||
static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp,
|
||||
enum alarmtimer_type type)
|
||||
{
|
||||
struct timespec __user *rmtp;
|
||||
struct restart_block *restart;
|
||||
alarm->data = (void *)current;
|
||||
do {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
@@ -709,8 +710,8 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp,
|
||||
|
||||
if (freezing(current))
|
||||
alarmtimer_freezerset(absexp, type);
|
||||
rmtp = current->restart_block.nanosleep.rmtp;
|
||||
if (rmtp) {
|
||||
restart = ¤t->restart_block;
|
||||
if (restart->nanosleep.type != TT_NONE) {
|
||||
struct timespec rmt;
|
||||
ktime_t rem;
|
||||
|
||||
@@ -720,7 +721,14 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp,
|
||||
return 0;
|
||||
rmt = ktime_to_timespec(rem);
|
||||
|
||||
if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (restart->nanosleep.type == TT_COMPAT) {
|
||||
if (compat_put_timespec(&rmt,
|
||||
restart->nanosleep.compat_rmtp))
|
||||
return -EFAULT;
|
||||
} else
|
||||
#endif
|
||||
if (copy_to_user(restart->nanosleep.rmtp, &rmt, sizeof(rmt)))
|
||||
return -EFAULT;
|
||||
}
|
||||
return -ERESTART_RESTARTBLOCK;
|
||||
|
||||
Reference in New Issue
Block a user