sanitizing compat nanosleep and other timer-related syscalls
Subsystems (3)
PATCH 1/1 sanitizing compat nanosleep and other timer-related syscalls
The series is on top of tip.git#timers/core; the first half
massages {clock_,}nanosleep(), the rest deals with other timer-related compat syscalls.
As it is, nanosleep() has rather convoluted logics for
copying the timespec to userland. It can happen in the syscall itself, or in restart callback triggered on restart. Naturally, there is quite a bit of shared code between those; after all, restart callbacks mimic what would've been a plain syscall restart, if not for the need to recalculate timeouts. However, copying the timespec to userland is *not* a part of shared code - it's duplicated in sys_nanosleep() and hrtimer_nanosleep_restart(), and similar for clock_nanosleep(). Moving that copyout into hrtimer_nanosleep() and its ilk simplifies life.
What's more, that allows to deal with another bit of
nastiness - compat side of nanosleep(2) has to play very sick games. It calls sys_nanosleep() under set_fs(KERNEL_DS) and passes it a pointer to on-stack (native) timespec. Then it converts that to 32bit timespec and copies it to userland; so far, so good, but if we are going to hit a restart, we can't leave the restart callback (and arguments for it) as-is - after all, the pointer to "userland" timespec actually points to kernel stack frame, long gone by the time we get to restart. So we flip the restart callback to one of our own and stash the real userland pointer for it. When that callback is finally called, it plays with restart args again and calls the native callback under KERNEL_DS, followed by the same dance as in the compat syscall itself. For clock_nanosleep() it's even more convoluted...
All that mess goes away if we teach hrtimer_nanosleep()
to handle both the native and compat copyout. All we need is to turn the (userland pointer to native timespec, userland pointer to compat timespec) pair in restart_block into a tagged union and add a helper used by hrtimer_nanosleep() (and clock_... counterparts thereof), doing the actual copyout. Massage to get there is longer than I would like, but the code is convoluted enough to make doing that in a single step too scary.
The second half is a plain and simple "move compat syscall
towards the native one, get rid of set_fs() by doing what the native one would with different copyin/copyout" stuff; that avoids double copying and set_fs() games in cases where we used to play those and allows to make the guts static in cases when we didn't. Either way, compat syscalls are better off next to the native ones.
Please, review. The patches will go in followups to this
mail; for those who prefer to use git tree, it is visible ingit://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git#timers-compat
(the first half - in #timers-nanosleep in the same repo).
Al Viro (16):
move copyout of timespec into do_cpu_nanosleep()
move copyout and freeze handling into alarmtimer_do_nsleep() hrtimer_nanosleep(): pass rmtp in restart_block
move copyout to do_nanosleel()
clock_nanosleep(): stash rmtp into restart_block nanosleep/clock_nanosleep: teach to do compat copyouts {clock_,}nanosleep(2): merge timespec copyout logics into a new helper kill ->nsleep_restart()
move adjtimex-related compat syscalls to native counterparts take compat timer_settime(2) to native one
take compat timer_gettime(2) to native one
move compat itimer syscalls to native ones clock_gettime/clock_settime/clock_getres: move to native syscalls timer_create(): move compat to native, get rid of set_fs() time()/stime(): move compat to native gettimeofday()/settimeofday(): move compat to native
PATCH 1/16 move copyout of timespec into do_cpu_nanosleep()
From: Al Viro <[email protected]>
--- kernel/time/posix-cpu-timers.c | 62 ++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 35 deletions(-)
kernel/time/posix-cpu-timers.c +27 -35
@@ -1226,9 +1226,10 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx, }static int do_cpu_nanosleep (const clockid_t which_clock,int flags, -struct timespec64 *rqtp,struct itimerspec64 *it) +struct timespec64 *rqtp) {struct k_itimer timer; +struct itimerspec64 it;int error;/*
@@ -1242,12 +1243,14 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, timer.it_process = current;if (!error) {static struct itimerspec64 zero_it; +struct restart_block *restart = ¤t->restart_block; +struct timespec __user *rmtp; -memset (it,0 ,sizeof *it); - it->it_value = *rqtp; +memset (&it,0 ,sizeof it); + it.it_value = *rqtp;spin_lock_irq (&timer.it_lock); - error =posix_cpu_timer_set (&timer, flags, it,NULL ); + error =posix_cpu_timer_set (&timer, flags, &it,NULL );if (error) {spin_unlock_irq (&timer.it_lock);return error;
@@ -1277,7 +1280,7 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,* We were interrupted by a signal. */ *rqtp =ns_to_timespec64 (timer.it.cpu.expires); - error =posix_cpu_timer_set (&timer,0 , &zero_it, it); + error =posix_cpu_timer_set (&timer,0 , &zero_it, &it);if (!error) {/* * Timer is now unarmed, deletion can not fail.
@@ -1297,7 +1300,7 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,spin_unlock_irq (&timer.it_lock); } -if ((it->it_value.tv_sec | it->it_value.tv_nsec) ==0 ) { +if ((it.it_value.tv_sec | it.it_value.tv_nsec) ==0 ) {/* * It actually did fire already. */
@@ -1305,6 +1308,17 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, } error = -ERESTART_RESTARTBLOCK ; +/* +* Report back to the user the time still remaining. +*/ + rmtp = restart->nanosleep.rmtp; +if (rmtp) { +struct timespec ts; + ts =timespec64_to_timespec (it.it_value); +if (copy_to_user (rmtp, &ts,sizeof (*rmtp))) +return -EFAULT ; + } + restart->nanosleep.expires =timespec64_to_ns (rqtp); }return error;
@@ -1316,10 +1330,13 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags, struct timespec64 *rqtp, struct timespec __user *rmtp) { struct restart_block *restart_block = ¤t->restart_block; -struct itimerspec64 it; -struct timespec ts;int error; +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + + restart_block->nanosleep.rmtp = rmtp; +/* * Diagnose required errors first. */
@@ -1328,23 +1345,15 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags, CPUCLOCK_PID(which_clock) == task_pid_vnr(current))) return -EINVAL; - error =do_cpu_nanosleep (which_clock, flags, rqtp, &it); + error =do_cpu_nanosleep (which_clock, flags, rqtp);if (error == -ERESTART_RESTARTBLOCK ) {if (flags &TIMER_ABSTIME )return -ERESTARTNOHAND ; -/* -* Report back to the user the time still remaining. -*/ - ts =timespec64_to_timespec (it.it_value); -if (rmtp &©_to_user (rmtp, &ts,sizeof (*rmtp))) -return -EFAULT ; restart_block->fn = posix_cpu_nsleep_restart; restart_block->nanosleep.clockid = which_clock; - restart_block->nanosleep.rmtp = rmtp; - restart_block->nanosleep.expires =timespec64_to_ns (rqtp); }return error; }
@@ -1352,28 +1361,11 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags,static long posix_cpu_nsleep_restart (struct restart_block *restart_block) {clockid_t which_clock = restart_block->nanosleep.clockid; -struct itimerspec64 it;struct timespec64 t; -struct timespec tmp; -int error; t =ns_to_timespec64 (restart_block->nanosleep.expires); - error =do_cpu_nanosleep (which_clock,TIMER_ABSTIME , &t, &it); - -if (error == -ERESTART_RESTARTBLOCK ) { -struct timespec __user *rmtp = restart_block->nanosleep.rmtp; -/* -* Report back to the user the time still remaining. -*/ - tmp =timespec64_to_timespec (it.it_value); -if (rmtp &©_to_user (rmtp, &tmp,sizeof (*rmtp))) -return -EFAULT ; - - restart_block->nanosleep.expires =timespec64_to_ns (&t); - } -return error; - +return do_cpu_nanosleep (which_clock,TIMER_ABSTIME , &t); }#define PROCESS_CLOCK MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED)
Signature · 1 line
2.11.0
PATCH 2/16 move copyout and freeze handling into alarmtimer_do_nsleep()
From: Al Viro <[email protected]>
--- kernel/time/alarmtimer.c | 102 +++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 70 deletions(-)
kernel/time/alarmtimer.c +32 -70
@@ -688,8 +688,10 @@ static enum alarmtimer_restart alarmtimer_nsleep_wakeup(struct alarm *alarm,* * Sets the alarm timer and sleeps until it is fired or interrupted. */ -static int alarmtimer_do_nsleep (struct alarm *alarm,ktime_t absexp) +static int alarmtimer_do_nsleep (struct alarm *alarm,ktime_t absexp, +enum alarmtimer_type type) { +struct timespec __user *rmtp; alarm->data = (void *)current; do { set_current_state(TASK_INTERRUPTIBLE);
@@ -702,36 +704,26 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp)__set_current_state (TASK_RUNNING ); -return (alarm->data ==NULL ); -} - - -/** -* update_rmtp - Update remaining timespec value -* @exp: expiration time -* @type: timer type -* @rmtp: user pointer to remaining timepsec value -* -* Helper function that fills in rmtp value with time between -* now and the exp value -*/ -static int update_rmtp (ktime_t exp,enum alarmtimer_type type, -struct timespec __user *rmtp) -{ -struct timespec rmt; -ktime_t rem; - - rem =ktime_sub (exp, alarm_bases[type].gettime ()); - -if (rem <=0 ) +if (!alarm->data)return 0 ; - rmt =ktime_to_timespec (rem); -if (copy_to_user (rmtp, &rmt,sizeof (*rmtp))) -return -EFAULT ; +if (freezing (current)) +alarmtimer_freezerset (absexp, type); + rmtp = current->restart_block.nanosleep.rmtp; +if (rmtp) { +struct timespec rmt; +ktime_t rem; -return 1 ; + rem =ktime_sub (absexp, alarm_bases[type].gettime ()); +if (rem <=0 ) +return 0 ; + rmt =ktime_to_timespec (rem); + +if (copy_to_user (rmtp, &rmt,sizeof (*rmtp))) +return -EFAULT ; + } +return -ERESTART_RESTARTBLOCK ; }/**
@@ -743,32 +735,12 @@ static int update_rmtp(ktime_t exp, enum alarmtimer_type type,static long __sched alarm_timer_nsleep_restart (struct restart_block *restart) {enum alarmtimer_type type = restart->nanosleep.clockid; -ktime_t exp; -struct timespec __user *rmtp; +ktime_t exp = restart->nanosleep.expires;struct alarm alarm; -int ret =0 ; - exp = restart->nanosleep.expires;alarm_init (&alarm, type, alarmtimer_nsleep_wakeup); -if (alarmtimer_do_nsleep (&alarm, exp)) - goto out; - -if (freezing (current)) -alarmtimer_freezerset (exp, type); - - rmtp = restart->nanosleep.rmtp; -if (rmtp) { - ret =update_rmtp (exp, type, rmtp); -if (ret <=0 ) - goto out; - } - - -/* The other values in restart are already filled in */ - ret = -ERESTART_RESTARTBLOCK ; -out: -return ret; +return alarmtimer_do_nsleep (&alarm, exp, type); }/**
@@ -785,11 +757,16 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags, struct timespec __user *rmtp) {enum alarmtimer_type type =clock2alarm (which_clock); -struct restart_block *restart; +struct restart_block *restart = ¤t->restart_block;struct alarm alarm;ktime_t exp;int ret =0 ; +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + + restart->nanosleep.rmtp = rmtp; +if (!alarmtimer_get_rtcdev ())return -ENOTSUPP ;
@@ -808,32 +785,17 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags, exp =ktime_add (now, exp); } -if (alarmtimer_do_nsleep (&alarm, exp)) - goto out; - -if (freezing (current)) -alarmtimer_freezerset (exp, type); + ret =alarmtimer_do_nsleep (&alarm, exp, type); +if (ret != -ERESTART_RESTARTBLOCK ) +return ret;/* abs timers don't set remaining time or restart */ -if (flags ==TIMER_ABSTIME ) { - ret = -ERESTARTNOHAND ; - goto out; - } - -if (rmtp) { - ret =update_rmtp (exp, type, rmtp); -if (ret <=0 ) - goto out; - } +if (flags ==TIMER_ABSTIME ) +return -ERESTARTNOHAND ; - restart = ¤t->restart_block; restart->fn = alarm_timer_nsleep_restart; restart->nanosleep.clockid = type; restart->nanosleep.expires = exp; - restart->nanosleep.rmtp = rmtp; - ret = -ERESTART_RESTARTBLOCK ; - -out:return ret; }
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] alarmtimer: Move copyout and freeze handling into alarmtimer_do_nsleep()
alarmtimer: Move copyout and freeze handling into alarmtimer_do_nsleep()
Commit-ID: 15f27ce24cb613e6e01ce27c4094c55e55dde5d4 Gitweb: http://git.kernel.org/tip/15f27ce24cb613e6e01ce27c4094c55e55dde5d4 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:27 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:40 +0200
alarmtimer: Move copyout and freeze handling into alarmtimer_do_nsleep()
The alarmtimer nanosleep() implementation can be simplified by moving the copy out of the remaining time to alarmtimer_do_nsleep() which is shared between the real nanosleep function and the restart function.
The pointer to the timespec64 which is updated has to be stored in the restart block anyway. Instead of storing it only in the restart case, store it before calling alarmtimer_do_nsleep() and copy the remaining time in the signal exit path.
[ tglx: Added changelog ]
--- kernel/time/alarmtimer.c | 102 +++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 70 deletions(-)
kernel/time/alarmtimer.c +32 -70
@@ -688,8 +688,10 @@ static enum alarmtimer_restart alarmtimer_nsleep_wakeup(struct alarm *alarm,* * Sets the alarm timer and sleeps until it is fired or interrupted. */ -static int alarmtimer_do_nsleep (struct alarm *alarm,ktime_t absexp) +static int alarmtimer_do_nsleep (struct alarm *alarm,ktime_t absexp, +enum alarmtimer_type type) { +struct timespec __user *rmtp; alarm->data = (void *)current; do { set_current_state(TASK_INTERRUPTIBLE);
@@ -702,36 +704,26 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp)__set_current_state (TASK_RUNNING ); -return (alarm->data ==NULL ); -} - - -/** -* update_rmtp - Update remaining timespec value -* @exp: expiration time -* @type: timer type -* @rmtp: user pointer to remaining timepsec value -* -* Helper function that fills in rmtp value with time between -* now and the exp value -*/ -static int update_rmtp (ktime_t exp,enum alarmtimer_type type, -struct timespec __user *rmtp) -{ -struct timespec rmt; -ktime_t rem; - - rem =ktime_sub (exp, alarm_bases[type].gettime ()); - -if (rem <=0 ) +if (!alarm->data)return 0 ; - rmt =ktime_to_timespec (rem); -if (copy_to_user (rmtp, &rmt,sizeof (*rmtp))) -return -EFAULT ; +if (freezing (current)) +alarmtimer_freezerset (absexp, type); + rmtp = current->restart_block.nanosleep.rmtp; +if (rmtp) { +struct timespec rmt; +ktime_t rem; -return 1 ; + rem =ktime_sub (absexp, alarm_bases[type].gettime ()); +if (rem <=0 ) +return 0 ; + rmt =ktime_to_timespec (rem); + +if (copy_to_user (rmtp, &rmt,sizeof (*rmtp))) +return -EFAULT ; + } +return -ERESTART_RESTARTBLOCK ; }/**
@@ -743,32 +735,12 @@ static int update_rmtp(ktime_t exp, enum alarmtimer_type type,static long __sched alarm_timer_nsleep_restart (struct restart_block *restart) {enum alarmtimer_type type = restart->nanosleep.clockid; -ktime_t exp; -struct timespec __user *rmtp; +ktime_t exp = restart->nanosleep.expires;struct alarm alarm; -int ret =0 ; - exp = restart->nanosleep.expires;alarm_init (&alarm, type, alarmtimer_nsleep_wakeup); -if (alarmtimer_do_nsleep (&alarm, exp)) - goto out; - -if (freezing (current)) -alarmtimer_freezerset (exp, type); - - rmtp = restart->nanosleep.rmtp; -if (rmtp) { - ret =update_rmtp (exp, type, rmtp); -if (ret <=0 ) - goto out; - } - - -/* The other values in restart are already filled in */ - ret = -ERESTART_RESTARTBLOCK ; -out: -return ret; +return alarmtimer_do_nsleep (&alarm, exp, type); }/**
@@ -785,11 +757,16 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags, struct timespec __user *rmtp) {enum alarmtimer_type type =clock2alarm (which_clock); -struct restart_block *restart; +struct restart_block *restart = ¤t->restart_block;struct alarm alarm;ktime_t exp;int ret =0 ; +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + + restart->nanosleep.rmtp = rmtp; +if (!alarmtimer_get_rtcdev ())return -ENOTSUPP ;
@@ -808,32 +785,17 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags, exp =ktime_add (now, exp); } -if (alarmtimer_do_nsleep (&alarm, exp)) - goto out; - -if (freezing (current)) -alarmtimer_freezerset (exp, type); + ret =alarmtimer_do_nsleep (&alarm, exp, type); +if (ret != -ERESTART_RESTARTBLOCK ) +return ret;/* abs timers don't set remaining time or restart */ -if (flags ==TIMER_ABSTIME ) { - ret = -ERESTARTNOHAND ; - goto out; - } - -if (rmtp) { - ret =update_rmtp (exp, type, rmtp); -if (ret <=0 ) - goto out; - } +if (flags ==TIMER_ABSTIME ) +return -ERESTARTNOHAND ; - restart = ¤t->restart_block; restart->fn = alarm_timer_nsleep_restart; restart->nanosleep.clockid = type; restart->nanosleep.expires = exp; - restart->nanosleep.rmtp = rmtp; - ret = -ERESTART_RESTARTBLOCK ; - -out:return ret; }
PATCH 3/16 hrtimer_nanosleep(): pass rmtp in restart_block
In reply to Al ViroFrom: Al Viro <[email protected]>
--- include/linux/hrtimer.h | 1 - kernel/compat.c | 6 +++--- kernel/time/hrtimer.c | 11 ++++++----- kernel/time/posix-stubs.c | 5 ++++- kernel/time/posix-timers.c | 5 ++++- 5 files changed, 17 insertions(+), 11 deletions(-)
include/linux/hrtimer.h +0 -1
@@ -453,7 +453,6 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer,/* Precise sleep: */ extern long hrtimer_nanosleep (struct timespec64 *rqtp, -struct timespec __user *rmtp,const enum hrtimer_mode mode,const clockid_t clockid);extern long hrtimer_nanosleep_restart (struct restart_block *restart_block);
kernel/compat.c +3 -3
@@ -253,9 +253,9 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, oldfs =get_fs ();set_fs (KERNEL_DS ); - ret =hrtimer_nanosleep (&tu64, - rmtp ? (struct timespec __user *)&rmt :NULL , -HRTIMER_MODE_REL ,CLOCK_MONOTONIC ); + current->restart_block.nanosleep.rmtp = + rmtp ? (struct timespec __user *)&rmt :NULL ; + ret =hrtimer_nanosleep (&tu64,HRTIMER_MODE_REL ,CLOCK_MONOTONIC );set_fs (oldfs);/*
kernel/time/hrtimer.c +6 -5
@@ -1503,10 +1503,11 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart)return ret; } -long hrtimer_nanosleep (struct timespec64 *rqtp,struct timespec __user *rmtp, +long hrtimer_nanosleep (struct timespec64 *rqtp,const enum hrtimer_mode mode,const clockid_t clockid) { -struct restart_block *restart; +struct restart_block *restart = ¤t->restart_block; +struct timespec __user *rmtp;struct hrtimer_sleeper t;int ret =0 ;u64 slack;
@@ -1526,16 +1527,15 @@ long hrtimer_nanosleep(struct timespec64 *rqtp, struct timespec __user *rmtp, goto out; } + rmtp = restart->nanosleep.rmtp;if (rmtp) { ret =update_rmtp (&t.timer, rmtp);if (ret <=0 ) goto out; } - restart = ¤t->restart_block; restart->fn = hrtimer_nanosleep_restart; restart->nanosleep.clockid = t.timer.base->clockid; - restart->nanosleep.rmtp = rmtp; restart->nanosleep.expires =hrtimer_get_expires_tv64 (&t.timer); ret = -ERESTART_RESTARTBLOCK ;
@@ -1557,7 +1557,8 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,if (!timespec64_valid (&tu64))return -EINVAL ; -return hrtimer_nanosleep (&tu64, rmtp,HRTIMER_MODE_REL ,CLOCK_MONOTONIC ); + current->restart_block.nanosleep.rmtp = rmtp; +return hrtimer_nanosleep (&tu64,HRTIMER_MODE_REL ,CLOCK_MONOTONIC ); }/*
kernel/time/posix-stubs.c +4 -1
@@ -115,7 +115,10 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, t64 =timespec_to_timespec64 (t);if (!timespec64_valid (&t64))return -EINVAL ; -return hrtimer_nanosleep (&t64, rmtp, flags &TIMER_ABSTIME ? +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + current->restart_block.nanosleep.rmtp = rmtp; +return hrtimer_nanosleep (&t64, flags &TIMER_ABSTIME ?HRTIMER_MODE_ABS :HRTIMER_MODE_REL , which_clock);default :
kernel/time/posix-timers.c +4 -1
@@ -1028,7 +1028,10 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,static int common_nsleep (const clockid_t which_clock,int flags,struct timespec64 *tsave,struct timespec __user *rmtp) { -return hrtimer_nanosleep (tsave, rmtp, flags &TIMER_ABSTIME ? +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + current->restart_block.nanosleep.rmtp = rmtp; +return hrtimer_nanosleep (tsave, flags &TIMER_ABSTIME ?HRTIMER_MODE_ABS :HRTIMER_MODE_REL , which_clock); }
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] hrtimer_nanosleep(): Pass rmtp in restart_block
hrtimer_nanosleep(): Pass rmtp in restart_block
Commit-ID: 192a82f9003fe8fabd6088aa646e829225a94c55 Gitweb: http://git.kernel.org/tip/192a82f9003fe8fabd6088aa646e829225a94c55 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:28 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:40 +0200
hrtimer_nanosleep(): Pass rmtp in restart_block
Store the pointer to the timespec which gets updated with the remaining time in the restart block and remove the function argument.
[ tglx: Added changelog ]
--- include/linux/hrtimer.h | 1 - kernel/compat.c | 6 +++--- kernel/time/hrtimer.c | 11 ++++++----- kernel/time/posix-stubs.c | 5 ++++- kernel/time/posix-timers.c | 5 ++++- 5 files changed, 17 insertions(+), 11 deletions(-)
include/linux/hrtimer.h +0 -1
@@ -453,7 +453,6 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer,/* Precise sleep: */ extern long hrtimer_nanosleep (struct timespec64 *rqtp, -struct timespec __user *rmtp,const enum hrtimer_mode mode,const clockid_t clockid);extern long hrtimer_nanosleep_restart (struct restart_block *restart_block);
kernel/compat.c +3 -3
@@ -253,9 +253,9 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, oldfs =get_fs ();set_fs (KERNEL_DS ); - ret =hrtimer_nanosleep (&tu64, - rmtp ? (struct timespec __user *)&rmt :NULL , -HRTIMER_MODE_REL ,CLOCK_MONOTONIC ); + current->restart_block.nanosleep.rmtp = + rmtp ? (struct timespec __user *)&rmt :NULL ; + ret =hrtimer_nanosleep (&tu64,HRTIMER_MODE_REL ,CLOCK_MONOTONIC );set_fs (oldfs);/*
kernel/time/hrtimer.c +6 -5
@@ -1503,10 +1503,11 @@ out:return ret; } -long hrtimer_nanosleep (struct timespec64 *rqtp,struct timespec __user *rmtp, +long hrtimer_nanosleep (struct timespec64 *rqtp,const enum hrtimer_mode mode,const clockid_t clockid) { -struct restart_block *restart; +struct restart_block *restart = ¤t->restart_block; +struct timespec __user *rmtp;struct hrtimer_sleeper t;int ret =0 ;u64 slack;
@@ -1526,16 +1527,15 @@ long hrtimer_nanosleep(struct timespec64 *rqtp, struct timespec __user *rmtp, goto out; } + rmtp = restart->nanosleep.rmtp;if (rmtp) { ret =update_rmtp (&t.timer, rmtp);if (ret <=0 ) goto out; } - restart = ¤t->restart_block; restart->fn = hrtimer_nanosleep_restart; restart->nanosleep.clockid = t.timer.base->clockid; - restart->nanosleep.rmtp = rmtp; restart->nanosleep.expires =hrtimer_get_expires_tv64 (&t.timer); ret = -ERESTART_RESTARTBLOCK ;
@@ -1557,7 +1557,8 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,if (!timespec64_valid (&tu64))return -EINVAL ; -return hrtimer_nanosleep (&tu64, rmtp,HRTIMER_MODE_REL ,CLOCK_MONOTONIC ); + current->restart_block.nanosleep.rmtp = rmtp; +return hrtimer_nanosleep (&tu64,HRTIMER_MODE_REL ,CLOCK_MONOTONIC ); }/*
kernel/time/posix-stubs.c +4 -1
@@ -115,7 +115,10 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, t64 =timespec_to_timespec64 (t);if (!timespec64_valid (&t64))return -EINVAL ; -return hrtimer_nanosleep (&t64, rmtp, flags &TIMER_ABSTIME ? +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + current->restart_block.nanosleep.rmtp = rmtp; +return hrtimer_nanosleep (&t64, flags &TIMER_ABSTIME ?HRTIMER_MODE_ABS :HRTIMER_MODE_REL , which_clock);default :
kernel/time/posix-timers.c +4 -1
@@ -1043,7 +1043,10 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,static int common_nsleep (const clockid_t which_clock,int flags,struct timespec64 *tsave,struct timespec __user *rmtp) { -return hrtimer_nanosleep (tsave, rmtp, flags &TIMER_ABSTIME ? +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + current->restart_block.nanosleep.rmtp = rmtp; +return hrtimer_nanosleep (tsave, flags &TIMER_ABSTIME ?HRTIMER_MODE_ABS :HRTIMER_MODE_REL , which_clock); }
PATCH 4/16 move copyout to do_nanosleel()
In reply to Al ViroFrom: Al Viro <[email protected]>
--- kernel/time/hrtimer.c | 62 +++++++++++++++++---------------------------------- 1 file changed, 20 insertions(+), 42 deletions(-)
kernel/time/hrtimer.c +20 -42
@@ -1441,6 +1441,7 @@ EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) { +struct timespec __user *rmtp;hrtimer_init_sleeper (t, current); do {
@@ -1457,48 +1458,33 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod__set_current_state (TASK_RUNNING ); -return t->task ==NULL ; -} - -static int update_rmtp (struct hrtimer *timer,struct timespec __user *rmtp) -{ -struct timespec rmt; -ktime_t rem; - - rem =hrtimer_expires_remaining (timer); -if (rem <=0 ) +if (!t->task)return 0 ; - rmt =ktime_to_timespec (rem); -if (copy_to_user (rmtp, &rmt,sizeof (*rmtp))) -return -EFAULT ; - -return 1 ; + rmtp = current->restart_block.nanosleep.rmtp; +if (rmtp) { +struct timespec rmt; +ktime_t rem =hrtimer_expires_remaining (&t->timer); +if (rem <=0 ) +return 0 ; + rmt =ktime_to_timespec (rem); + +if (copy_to_user (rmtp, &rmt,sizeof (*rmtp))) +return -EFAULT ; + } +return -ERESTART_RESTARTBLOCK ; }long __sched hrtimer_nanosleep_restart (struct restart_block *restart) {struct hrtimer_sleeper t; -struct timespec __user *rmtp; -int ret =0 ; +int ret;hrtimer_init_on_stack (&t.timer, restart->nanosleep.clockid,HRTIMER_MODE_ABS );hrtimer_set_expires_tv64 (&t.timer, restart->nanosleep.expires); -if (do_nanosleep (&t,HRTIMER_MODE_ABS )) - goto out; - - rmtp = restart->nanosleep.rmtp; -if (rmtp) { - ret =update_rmtp (&t.timer, rmtp); -if (ret <=0 ) - goto out; - } - -/* The other values in restart are already filled in */ - ret = -ERESTART_RESTARTBLOCK ; -out: + ret =do_nanosleep (&t,HRTIMER_MODE_ABS );destroy_hrtimer_on_stack (&t.timer);return ret; }
@@ -1506,8 +1492,7 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart)long hrtimer_nanosleep (struct timespec64 *rqtp,const enum hrtimer_mode mode,const clockid_t clockid) { -struct restart_block *restart = ¤t->restart_block; -struct timespec __user *rmtp; +struct restart_block *restart;struct hrtimer_sleeper t;int ret =0 ;u64 slack;
@@ -1518,7 +1503,8 @@ long hrtimer_nanosleep(struct timespec64 *rqtp,hrtimer_init_on_stack (&t.timer, clockid, mode);hrtimer_set_expires_range_ns (&t.timer,timespec64_to_ktime (*rqtp), slack); -if (do_nanosleep (&t, mode)) + ret =do_nanosleep (&t, mode); +if (ret != -ERESTART_RESTARTBLOCK ) goto out;/* Absolute timers do not update the rmtp value and restart: */
@@ -1527,18 +1513,10 @@ long hrtimer_nanosleep(struct timespec64 *rqtp, goto out; } - rmtp = restart->nanosleep.rmtp; -if (rmtp) { - ret =update_rmtp (&t.timer, rmtp); -if (ret <=0 ) - goto out; - } - + restart = ¤t->restart_block; restart->fn = hrtimer_nanosleep_restart; restart->nanosleep.clockid = t.timer.base->clockid; restart->nanosleep.expires =hrtimer_get_expires_tv64 (&t.timer); - - ret = -ERESTART_RESTARTBLOCK ; out:destroy_hrtimer_on_stack (&t.timer);return ret;
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] hrtimer: Move copyout of remaining time to do_nanosleep()
hrtimer: Move copyout of remaining time to do_nanosleep()
Commit-ID: a7602681fc63f1a3ddd3da336296c9634c2ff974 Gitweb: http://git.kernel.org/tip/a7602681fc63f1a3ddd3da336296c9634c2ff974 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:29 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:41 +0200
hrtimer: Move copyout of remaining time to do_nanosleep()
The hrtimer nanosleep() implementation can be simplified by moving the copy out of the remaining time to do_nanosleep() which is shared between the real nanosleep function and the restart function.
The pointer to the timespec64 which is updated is already stored in the restart block at the call site, so the seperate handling of nanosleep and restart function can be avoided.
[ tglx: Added changelog ]
--- kernel/time/hrtimer.c | 62 +++++++++++++++++---------------------------------- 1 file changed, 20 insertions(+), 42 deletions(-)
kernel/time/hrtimer.c +20 -42
@@ -1441,6 +1441,7 @@ EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) { +struct timespec __user *rmtp;hrtimer_init_sleeper (t, current); do {
@@ -1457,48 +1458,33 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod__set_current_state (TASK_RUNNING ); -return t->task ==NULL ; -} - -static int update_rmtp (struct hrtimer *timer,struct timespec __user *rmtp) -{ -struct timespec rmt; -ktime_t rem; - - rem =hrtimer_expires_remaining (timer); -if (rem <=0 ) +if (!t->task)return 0 ; - rmt =ktime_to_timespec (rem); -if (copy_to_user (rmtp, &rmt,sizeof (*rmtp))) -return -EFAULT ; - -return 1 ; + rmtp = current->restart_block.nanosleep.rmtp; +if (rmtp) { +struct timespec rmt; +ktime_t rem =hrtimer_expires_remaining (&t->timer); +if (rem <=0 ) +return 0 ; + rmt =ktime_to_timespec (rem); + +if (copy_to_user (rmtp, &rmt,sizeof (*rmtp))) +return -EFAULT ; + } +return -ERESTART_RESTARTBLOCK ; }long __sched hrtimer_nanosleep_restart (struct restart_block *restart) {struct hrtimer_sleeper t; -struct timespec __user *rmtp; -int ret =0 ; +int ret;hrtimer_init_on_stack (&t.timer, restart->nanosleep.clockid,HRTIMER_MODE_ABS );hrtimer_set_expires_tv64 (&t.timer, restart->nanosleep.expires); -if (do_nanosleep (&t,HRTIMER_MODE_ABS )) - goto out; - - rmtp = restart->nanosleep.rmtp; -if (rmtp) { - ret =update_rmtp (&t.timer, rmtp); -if (ret <=0 ) - goto out; - } - -/* The other values in restart are already filled in */ - ret = -ERESTART_RESTARTBLOCK ; -out: + ret =do_nanosleep (&t,HRTIMER_MODE_ABS );destroy_hrtimer_on_stack (&t.timer);return ret; }
@@ -1506,8 +1492,7 @@ out:long hrtimer_nanosleep (struct timespec64 *rqtp,const enum hrtimer_mode mode,const clockid_t clockid) { -struct restart_block *restart = ¤t->restart_block; -struct timespec __user *rmtp; +struct restart_block *restart;struct hrtimer_sleeper t;int ret =0 ;u64 slack;
@@ -1518,7 +1503,8 @@ long hrtimer_nanosleep(struct timespec64 *rqtp,hrtimer_init_on_stack (&t.timer, clockid, mode);hrtimer_set_expires_range_ns (&t.timer,timespec64_to_ktime (*rqtp), slack); -if (do_nanosleep (&t, mode)) + ret =do_nanosleep (&t, mode); +if (ret != -ERESTART_RESTARTBLOCK ) goto out;/* Absolute timers do not update the rmtp value and restart: */
@@ -1527,18 +1513,10 @@ long hrtimer_nanosleep(struct timespec64 *rqtp, goto out; } - rmtp = restart->nanosleep.rmtp; -if (rmtp) { - ret =update_rmtp (&t.timer, rmtp); -if (ret <=0 ) - goto out; - } - + restart = ¤t->restart_block; restart->fn = hrtimer_nanosleep_restart; restart->nanosleep.clockid = t.timer.base->clockid; restart->nanosleep.expires =hrtimer_get_expires_tv64 (&t.timer); - - ret = -ERESTART_RESTARTBLOCK ; out:destroy_hrtimer_on_stack (&t.timer);return ret;
PATCH 5/16 clock_nanosleep(): stash rmtp into restart_block
In reply to Al ViroFrom: Al Viro <[email protected]>
... instead of doing that in every ->nsleep() instance
--- kernel/time/alarmtimer.c | 8 +------- kernel/time/posix-cpu-timers.c | 12 +++--------- kernel/time/posix-timers.c | 10 +++++----- kernel/time/posix-timers.h | 2 +- 4 files changed, 10 insertions(+), 22 deletions(-)
kernel/time/alarmtimer.c +1 -7
@@ -753,8 +753,7 @@ static long __sched alarm_timer_nsleep_restart(struct restart_block *restart)* Handles clock_nanosleep calls against _ALARM clockids */ static int alarm_timer_nsleep (const clockid_t which_clock,int flags, -struct timespec64 *tsreq, -struct timespec __user *rmtp) +struct timespec64 *tsreq) {enum alarmtimer_type type =clock2alarm (which_clock);struct restart_block *restart = ¤t->restart_block;
@@ -762,11 +761,6 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags,ktime_t exp;int ret =0 ; -if (flags &TIMER_ABSTIME ) - rmtp =NULL ; - - restart->nanosleep.rmtp = rmtp; -if (!alarmtimer_get_rtcdev ())return -ENOTSUPP ;
kernel/time/posix-cpu-timers.c +3 -9
@@ -1327,16 +1327,11 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,static long posix_cpu_nsleep_restart (struct restart_block *restart_block);static int posix_cpu_nsleep (const clockid_t which_clock,int flags, -struct timespec64 *rqtp,struct timespec __user *rmtp) +struct timespec64 *rqtp) {struct restart_block *restart_block = ¤t->restart_block;int error; -if (flags &TIMER_ABSTIME ) - rmtp =NULL ; - - restart_block->nanosleep.rmtp = rmtp; -/* * Diagnose required errors first. */
@@ -1387,10 +1382,9 @@ static int process_cpu_timer_create(struct k_itimer *timer)return posix_cpu_timer_create (timer); }static int process_cpu_nsleep (const clockid_t which_clock,int flags, -struct timespec64 *rqtp, -struct timespec __user *rmtp) +struct timespec64 *rqtp) { -return posix_cpu_nsleep (PROCESS_CLOCK , flags, rqtp, rmtp); +return posix_cpu_nsleep (PROCESS_CLOCK , flags, rqtp); }static long process_cpu_nsleep_restart (struct restart_block *restart_block) {
kernel/time/posix-timers.c +5 -5
@@ -1026,11 +1026,8 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,* nanosleep for monotonic and realtime clocks */ static int common_nsleep (const clockid_t which_clock,int flags, -struct timespec64 *tsave,struct timespec __user *rmtp) +struct timespec64 *tsave) { -if (flags &TIMER_ABSTIME ) - rmtp =NULL ; - current->restart_block.nanosleep.rmtp = rmtp;return hrtimer_nanosleep (tsave, flags &TIMER_ABSTIME ?HRTIMER_MODE_ABS :HRTIMER_MODE_REL , which_clock);
@@ -1055,8 +1052,11 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, t64 =timespec_to_timespec64 (t);if (!timespec64_valid (&t64))return -EINVAL ; +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + current->restart_block.nanosleep.rmtp = rmtp; -return kc->nsleep (which_clock, flags, &t64, rmtp); +return kc->nsleep (which_clock, flags, &t64); }/*
kernel/time/posix-timers.h +1 -1
@@ -10,7 +10,7 @@ struct k_clock {int (*clock_adj)(const clockid_t which_clock,struct timex *tx);int (*timer_create)(struct k_itimer *timer);int (*nsleep)(const clockid_t which_clock,int flags, -struct timespec64 *,struct timespec __user *); +struct timespec64 *);long (*nsleep_restart)(struct restart_block *restart_block); int (*timer_set)(struct k_itimer *timr, int flags, struct itimerspec64 *new_setting,
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] posix-timers: Store rmtp into restart_block in sys_clock_nanosleep()
posix-timers: Store rmtp into restart_block in sys_clock_nanosleep()
Commit-ID: 99e6c0e6ec349575886ca7daffc9cb7ec583176f Gitweb: http://git.kernel.org/tip/99e6c0e6ec349575886ca7daffc9cb7ec583176f Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:30 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:41 +0200
posix-timers: Store rmtp into restart_block in sys_clock_nanosleep()
... instead of doing that in every ->nsleep() instance
--- kernel/time/alarmtimer.c | 8 +------- kernel/time/posix-cpu-timers.c | 12 +++--------- kernel/time/posix-timers.c | 10 +++++----- kernel/time/posix-timers.h | 2 +- 4 files changed, 10 insertions(+), 22 deletions(-)
kernel/time/alarmtimer.c +1 -7
@@ -753,8 +753,7 @@ static long __sched alarm_timer_nsleep_restart(struct restart_block *restart)* Handles clock_nanosleep calls against _ALARM clockids */ static int alarm_timer_nsleep (const clockid_t which_clock,int flags, -struct timespec64 *tsreq, -struct timespec __user *rmtp) +struct timespec64 *tsreq) {enum alarmtimer_type type =clock2alarm (which_clock);struct restart_block *restart = ¤t->restart_block;
@@ -762,11 +761,6 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags,ktime_t exp;int ret =0 ; -if (flags &TIMER_ABSTIME ) - rmtp =NULL ; - - restart->nanosleep.rmtp = rmtp; -if (!alarmtimer_get_rtcdev ())return -ENOTSUPP ;
kernel/time/posix-cpu-timers.c +3 -9
@@ -1328,16 +1328,11 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,static long posix_cpu_nsleep_restart (struct restart_block *restart_block);static int posix_cpu_nsleep (const clockid_t which_clock,int flags, -struct timespec64 *rqtp,struct timespec __user *rmtp) +struct timespec64 *rqtp) {struct restart_block *restart_block = ¤t->restart_block;int error; -if (flags &TIMER_ABSTIME ) - rmtp =NULL ; - - restart_block->nanosleep.rmtp = rmtp; -/* * Diagnose required errors first. */
@@ -1388,10 +1383,9 @@ static int process_cpu_timer_create(struct k_itimer *timer)return posix_cpu_timer_create (timer); }static int process_cpu_nsleep (const clockid_t which_clock,int flags, -struct timespec64 *rqtp, -struct timespec __user *rmtp) +struct timespec64 *rqtp) { -return posix_cpu_nsleep (PROCESS_CLOCK , flags, rqtp, rmtp); +return posix_cpu_nsleep (PROCESS_CLOCK , flags, rqtp); }static long process_cpu_nsleep_restart (struct restart_block *restart_block) {
kernel/time/posix-timers.c +5 -5
@@ -1041,11 +1041,8 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,* nanosleep for monotonic and realtime clocks */ static int common_nsleep (const clockid_t which_clock,int flags, -struct timespec64 *tsave,struct timespec __user *rmtp) +struct timespec64 *tsave) { -if (flags &TIMER_ABSTIME ) - rmtp =NULL ; - current->restart_block.nanosleep.rmtp = rmtp;return hrtimer_nanosleep (tsave, flags &TIMER_ABSTIME ?HRTIMER_MODE_ABS :HRTIMER_MODE_REL , which_clock);
@@ -1070,8 +1067,11 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, t64 =timespec_to_timespec64 (t);if (!timespec64_valid (&t64))return -EINVAL ; +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + current->restart_block.nanosleep.rmtp = rmtp; -return kc->nsleep (which_clock, flags, &t64, rmtp); +return kc->nsleep (which_clock, flags, &t64); }/*
kernel/time/posix-timers.h +1 -1
@@ -10,7 +10,7 @@ struct k_clock {int (*clock_adj)(const clockid_t which_clock,struct timex *tx);int (*timer_create)(struct k_itimer *timer);int (*nsleep)(const clockid_t which_clock,int flags, -struct timespec64 *,struct timespec __user *); +struct timespec64 *);long (*nsleep_restart)(struct restart_block *restart_block); int (*timer_set)(struct k_itimer *timr, int flags, struct itimerspec64 *new_setting,
PATCH 6/16 nanosleep/clock_nanosleep: teach to do compat copyouts
In reply to Al ViroFrom: Al Viro <[email protected]>
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.
--- include/linux/posix-timers.h | 2 - include/linux/restart_block.h | 7 ++- kernel/compat.c | 131 ----------------------------------------- kernel/time/alarmtimer.c | 16 +++-- kernel/time/hrtimer.c | 38 ++++++++++-- kernel/time/posix-cpu-timers.c | 18 ++++-- kernel/time/posix-stubs.c | 29 ++++++++- kernel/time/posix-timers.c | 32 +++++++--- 8 files changed, 115 insertions(+), 158 deletions(-)
include/linux/posix-timers.h +0 -2
@@ -110,8 +110,6 @@ void posix_cpu_timers_exit_group(struct task_struct *task);void set_process_cpu_timer (struct task_struct *task,unsigned int clock_idx,u64 *newval,u64 *oldval); -long clock_nanosleep_restart (struct restart_block *restart_block); -void update_rlimit_cpu (struct task_struct *task,unsigned long rlim_new);void posixtimer_rearm (struct siginfo *info);
include/linux/restart_block.h +5 -2
@@ -29,10 +29,13 @@ struct restart_block {/* For nanosleep */ struct {clockid_t clockid; -struct timespec __user *rmtp; +int kind; +union { +struct timespec __user *rmtp;#ifdef CONFIG_COMPAT -struct compat_timespec __user *compat_rmtp; +struct compat_timespec __user *compat_rmtp;#endif + };u64 expires; } nanosleep;/* For poll */
kernel/compat.c +0 -131
143 lines not on this page · raw message
kernel/time/alarmtimer.c +12 -4
@@ -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.kind) {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.kind ==2 ) { +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 ;
kernel/time/hrtimer.c +34 -4
@@ -51,6 +51,7 @@#include <linux/sched/debug.h> #include <linux/timer.h> #include <linux/freezer.h> +#include <linux/compat.h> #include <linux/uaccess.h>
@@ -1441,7 +1442,7 @@ EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) { -struct timespec __user *rmtp; +struct restart_block *restart;hrtimer_init_sleeper (t, current); do {
@@ -1461,15 +1462,22 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode modif (!t->task)return 0 ; - rmtp = current->restart_block.nanosleep.rmtp; -if (rmtp) { + restart = ¤t->restart_block; +if (restart->nanosleep.kind) {struct timespec rmt;ktime_t rem =hrtimer_expires_remaining (&t->timer);if (rem <=0 )return 0 ; rmt =ktime_to_timespec (rem); -if (copy_to_user (rmtp, &rmt,sizeof (*rmtp))) +#ifdef CONFIG_COMPAT +if (restart->nanosleep.kind ==2 ) { +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 ;
@@ -1535,10 +1543,32 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,if (!timespec64_valid (&tu64))return -EINVAL ; + current->restart_block.nanosleep.kind = rmtp ?1 :0 ; current->restart_block.nanosleep.rmtp = rmtp;return hrtimer_nanosleep (&tu64,HRTIMER_MODE_REL ,CLOCK_MONOTONIC ); } +#ifdef CONFIG_COMPAT + +COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, + struct compat_timespec __user *, rmtp) +{ +struct timespec tu; +struct timespec64 tu64; + +if (compat_get_timespec (&tu, rqtp)) +return -EFAULT ; + + tu64 =timespec_to_timespec64 (tu); +if (!timespec64_valid (&tu64)) +return -EINVAL ; + + current->restart_block.nanosleep.kind = rmtp ?2 :0 ; + current->restart_block.nanosleep.compat_rmtp = rmtp; +return hrtimer_nanosleep (&tu64,HRTIMER_MODE_REL ,CLOCK_MONOTONIC ); +} +#endif +/* * Functions related to boot-time initialization: */
kernel/time/posix-cpu-timers.c +13 -5
@@ -12,6 +12,7 @@#include <trace/events/timer.h> #include <linux/tick.h> #include <linux/workqueue.h> +#include <linux/compat.h> #include "posix-timers.h"
@@ -1243,8 +1244,7 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, timer.it_process = current;if (!error) {static struct itimerspec64 zero_it; -struct restart_block *restart = ¤t->restart_block; -struct timespec __user *rmtp; +struct restart_block *restart;memset (&it,0 ,sizeof it); it.it_value = *rqtp;
@@ -1311,11 +1311,19 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,/* * Report back to the user the time still remaining. */ - rmtp = restart->nanosleep.rmtp; -if (rmtp) { + restart = ¤t->restart_block; +if (restart->nanosleep.kind) {struct timespec ts; ts =timespec64_to_timespec (it.it_value); -if (copy_to_user (rmtp, &ts,sizeof (*rmtp))) +#ifdef CONFIG_COMPAT +if (restart->nanosleep.kind ==2 ) { +if (compat_put_timespec (&ts, + restart->nanosleep.compat_rmtp)) +return -EFAULT ; + } else +#endif +if (copy_to_user (restart->nanosleep.rmtp, &ts, +sizeof (ts)))return -EFAULT ; } restart->nanosleep.expires =timespec64_to_ns (rqtp);
kernel/time/posix-stubs.c +27 -2
@@ -17,6 +17,7 @@#include <linux/ktime.h> #include <linux/timekeeping.h> #include <linux/posix-timers.h> +#include <linux/compat.h> asmlinkage long sys_ni_posix_timers (void ) {
@@ -117,6 +118,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,return -EINVAL ;if (flags &TIMER_ABSTIME ) rmtp =NULL ; + current->restart_block.nanosleep.kind = rmtp ?1 :0 ; current->restart_block.nanosleep.rmtp = rmtp; return hrtimer_nanosleep(&t64, flags & TIMER_ABSTIME ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
@@ -127,8 +129,31 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, }#ifdef CONFIG_COMPAT -long clock_nanosleep_restart (struct restart_block *restart_block) +COMPAT_SYSCALL_DEFINE4 (clock_nanosleep, clockid_t, which_clock, int, flags, + struct compat_timespec __user *, rqtp, + struct compat_timespec __user *, rmtp) { -return hrtimer_nanosleep_restart (restart_block); +struct timespec64 t64; +struct timespec t; + +switch (which_clock) { +case CLOCK_REALTIME : +case CLOCK_MONOTONIC : +case CLOCK_BOOTTIME : +if (compat_get_timespec (&t, rqtp)) +return -EFAULT ; + t64 =timespec_to_timespec64 (t); +if (!timespec64_valid (&t64)) +return -EINVAL ; +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + current->restart_block.nanosleep.kind = rmtp ?2 :0 ; + current->restart_block.nanosleep.compat_rmtp = rmtp; +return hrtimer_nanosleep (&t64, flags &TIMER_ABSTIME ? +HRTIMER_MODE_ABS :HRTIMER_MODE_REL , + which_clock); +default : +return -EINVAL ; + } }#endif
kernel/time/posix-timers.c +24 -8
@@ -49,6 +49,7 @@#include <linux/workqueue.h> #include <linux/export.h> #include <linux/hashtable.h> +#include <linux/compat.h> #include "timekeeping.h" #include "posix-timers.h"
@@ -1054,25 +1055,40 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,return -EINVAL ;if (flags &TIMER_ABSTIME ) rmtp =NULL ; + current->restart_block.nanosleep.kind = rmtp ?1 :0 ; current->restart_block.nanosleep.rmtp = rmtp;return kc->nsleep (which_clock, flags, &t64); } -/* -* This will restart clock_nanosleep. This is required only by -* compat_clock_nanosleep_restart for now. -*/ -long clock_nanosleep_restart (struct restart_block *restart_block) +#ifdef CONFIG_COMPAT +COMPAT_SYSCALL_DEFINE4 (clock_nanosleep, clockid_t, which_clock, int, flags, + struct compat_timespec __user *, rqtp, + struct compat_timespec __user *, rmtp) { -clockid_t which_clock = restart_block->nanosleep.clockid;const struct k_clock *kc =clockid_to_kclock (which_clock); +struct timespec64 t64; +struct timespec t; -if (WARN_ON_ONCE (!kc || !kc->nsleep_restart)) +if (!kc)return -EINVAL ; +if (!kc->nsleep) +return -ENANOSLEEP_NOTSUP ; + +if (compat_get_timespec (&t, rqtp)) +return -EFAULT ; -return kc->nsleep_restart (restart_block); + t64 =timespec_to_timespec64 (t); +if (!timespec64_valid (&t64)) +return -EINVAL ; +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + current->restart_block.nanosleep.kind = rmtp ?2 :0 ; + current->restart_block.nanosleep.compat_rmtp = rmtp; + +return kc->nsleep (which_clock, flags, &t64); } +#endif static const struct k_clock clock_realtime = { .clock_getres = posix_get_hrtimer_res,
Signature · 1 line
2.11.0
Re: [PATCH 06/16] nanosleep/clock_nanosleep: teach to do compat copyouts
Quoted 7 lines · Al Viro
From: Al Viro <[email protected]>
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.
I found something like the below on top slightly easier to read. Ignore if hated..
--- include/linux/restart_block.h | 10 +++++++++- kernel/time/alarmtimer.c | 2 +- kernel/time/hrtimer.c | 23 +++++++++++++++-------- kernel/time/posix-cpu-timers.c | 2 +- kernel/time/posix-stubs.c | 4 ++-- kernel/time/posix-timers.c | 4 ++-- 6 files changed, 30 insertions(+), 15 deletions(-)
include/linux/restart_block.h +9 -1
@@ -11,6 +11,14 @@ struct timespec;struct compat_timespec ;struct pollfd ; +enum timespec_type { + tt_nothing =0 , + tt_native =1 , +#ifdef CONFIG_COMPAT + tt_compat =2 , +#endif +}; +/* * System call restart block. */
@@ -29,7 +37,7 @@ struct restart_block {/* For nanosleep */ struct {clockid_t clockid; -int kind; +enum timespec_type type;union {struct timespec __user *rmtp;#ifdef CONFIG_COMPAT
kernel/time/alarmtimer.c +1 -1
@@ -711,7 +711,7 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp,if (freezing (current))alarmtimer_freezerset (absexp, type); restart = ¤t->restart_block; -if (restart->nanosleep.kind) { +if (restart->nanosleep.type) {struct timespec rmt;ktime_t rem;
kernel/time/hrtimer.c +15 -8
@@ -1442,15 +1442,22 @@ EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);int nanosleep_copyout (struct restart_block *restart,struct timespec *ts) { -BUG_ON (!restart->nanosleep.kind); +switch (restart->nanosleep.type) {#ifdef CONFIG_COMPAT -if (restart->nanosleep.kind ==2 ) { +case tt_compat:if (compat_put_timespec (ts, restart->nanosleep.compat_rmtp))return -EFAULT ; - } else +break ;#endif -if (copy_to_user (restart->nanosleep.rmtp, ts,sizeof (struct timespec ))) -return -EFAULT ; +case tt_native: +if (copy_to_user (restart->nanosleep.rmtp, ts,sizeof (struct timespec ))) +return -EFAULT ; +break ; + +case tt_nothing: +BUG (); + } +return -ERESTART_RESTARTBLOCK ; }
@@ -1477,7 +1484,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode modreturn 0 ; restart = ¤t->restart_block; -if (restart->nanosleep.kind) { +if (restart->nanosleep.type) {struct timespec rmt;ktime_t rem =hrtimer_expires_remaining (&t->timer);if (rem <=0 )
@@ -1549,7 +1556,7 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,if (!timespec64_valid (&tu64))return -EINVAL ; - current->restart_block.nanosleep.kind = rmtp ?1 :0 ; + current->restart_block.nanosleep.type = rmtp ? tt_native : tt_nothing; current->restart_block.nanosleep.rmtp = rmtp;return hrtimer_nanosleep (&tu64,HRTIMER_MODE_REL ,CLOCK_MONOTONIC ); }
@@ -1569,7 +1576,7 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,if (!timespec64_valid (&tu64))return -EINVAL ; - current->restart_block.nanosleep.kind = rmtp ?2 :0 ; + current->restart_block.nanosleep.type = rmtp ? tt_compat : tt_nothing; current->restart_block.nanosleep.compat_rmtp = rmtp;return hrtimer_nanosleep (&tu64,HRTIMER_MODE_REL ,CLOCK_MONOTONIC ); }
kernel/time/posix-cpu-timers.c +1 -1
@@ -1313,7 +1313,7 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,*/ restart = ¤t->restart_block; restart->nanosleep.expires =timespec64_to_ns (rqtp); -if (restart->nanosleep.kind) { +if (restart->nanosleep.type) {struct timespec ts; ts =timespec64_to_timespec (it.it_value); error =nanosleep_copyout (restart, &ts);
kernel/time/posix-stubs.c +2 -2
@@ -125,7 +125,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,return -EINVAL ;if (flags &TIMER_ABSTIME ) rmtp =NULL ; - current->restart_block.nanosleep.kind = rmtp ?1 :0 ; + current->restart_block.nanosleep.type = rmtp ? tt_native : tt_nothing; current->restart_block.nanosleep.rmtp = rmtp; return hrtimer_nanosleep(&t64, flags & TIMER_ABSTIME ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
@@ -206,7 +206,7 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,return -EINVAL ;if (flags &TIMER_ABSTIME ) rmtp =NULL ; - current->restart_block.nanosleep.kind = rmtp ?2 :0 ; + current->restart_block.nanosleep.type = rmtp ? tt_compat : tt_nothing; current->restart_block.nanosleep.compat_rmtp = rmtp; return hrtimer_nanosleep(&t64, flags & TIMER_ABSTIME ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
kernel/time/posix-timers.c +2 -2
@@ -1228,7 +1228,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,return -EINVAL ;if (flags &TIMER_ABSTIME ) rmtp =NULL ; - current->restart_block.nanosleep.kind = rmtp ?1 :0 ; + current->restart_block.nanosleep.type = rmtp ? tt_native : tt_nothing; current->restart_block.nanosleep.rmtp = rmtp;return kc->nsleep (which_clock, flags, &t64);
@@ -1256,7 +1256,7 @@ COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,return -EINVAL ;if (flags &TIMER_ABSTIME ) rmtp =NULL ; - current->restart_block.nanosleep.kind = rmtp ?2 :0 ; + current->restart_block.nanosleep.type = rmtp ? tt_compat : tt_nothing; current->restart_block.nanosleep.compat_rmtp = rmtp;return kc->nsleep (which_clock, flags, &t64);
tip-bot for Al Viro
merge bot[tip:timers/core] time/posix-timers: Move the compat copyouts to the nanosleep implementations
In reply to Al Virotime/posix-timers: Move the compat copyouts to the nanosleep implementations
Commit-ID: edbeda46322fbcb15af2d2d0f2daffb0cd349a5a Gitweb: http://git.kernel.org/tip/edbeda46322fbcb15af2d2d0f2daffb0cd349a5a Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:31 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:42 +0200
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 ]
--- include/linux/posix-timers.h | 2 - include/linux/restart_block.h | 15 ++++- kernel/compat.c | 131 ----------------------------------------- kernel/time/alarmtimer.c | 16 +++-- kernel/time/hrtimer.c | 42 +++++++++++-- kernel/time/posix-cpu-timers.c | 20 +++++-- kernel/time/posix-stubs.c | 55 +++++++++++++---- kernel/time/posix-timers.c | 32 +++++++--- 8 files changed, 142 insertions(+), 171 deletions(-)
include/linux/posix-timers.h +0 -2
@@ -110,8 +110,6 @@ void posix_cpu_timers_exit_group(struct task_struct *task);void set_process_cpu_timer (struct task_struct *task,unsigned int clock_idx,u64 *newval,u64 *oldval); -long clock_nanosleep_restart (struct restart_block *restart_block); -void update_rlimit_cpu (struct task_struct *task,unsigned long rlim_new);void posixtimer_rearm (struct siginfo *info);
include/linux/restart_block.h +13 -2
@@ -11,6 +11,14 @@ struct timespec;struct compat_timespec ;struct pollfd ; +enum timespec_type { +TT_NONE =0 , +TT_NATIVE =1 , +#ifdef CONFIG_COMPAT +TT_COMPAT =2 , +#endif +}; +/* * System call restart block. */
@@ -29,10 +37,13 @@ struct restart_block {/* For nanosleep */ struct {clockid_t clockid; -struct timespec __user *rmtp; +enum timespec_type type; +union { +struct timespec __user *rmtp;#ifdef CONFIG_COMPAT -struct compat_timespec __user *compat_rmtp; +struct compat_timespec __user *compat_rmtp;#endif + };u64 expires; } nanosleep;/* For poll */
kernel/compat.c +0 -131
143 lines not on this page · raw message
kernel/time/alarmtimer.c +12 -4
@@ -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 ;
kernel/time/hrtimer.c +37 -5
75 lines not on this page · raw message
kernel/time/posix-cpu-timers.c +14 -6
@@ -12,6 +12,7 @@#include <trace/events/timer.h> #include <linux/tick.h> #include <linux/workqueue.h> +#include <linux/compat.h> #include "posix-timers.h"
@@ -1243,10 +1244,9 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, timer.it_process = current;if (!error) {static struct itimerspec64 zero_it; -struct restart_block *restart = ¤t->restart_block; -struct timespec __user *rmtp; +struct restart_block *restart; -memset (&it,0 ,sizeof it); +memset (&it,0 ,sizeof (it)); it.it_value = *rqtp;spin_lock_irq (&timer.it_lock);
@@ -1311,12 +1311,20 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,/* * Report back to the user the time still remaining. */ - rmtp = restart->nanosleep.rmtp; -if (rmtp) { + restart = ¤t->restart_block; +if (restart->nanosleep.type !=TT_NONE ) {struct timespec ts; ts =timespec64_to_timespec (it.it_value); -if (copy_to_user (rmtp, &ts,sizeof (*rmtp))) +#ifdef CONFIG_COMPAT +if (restart->nanosleep.type ==TT_COMPAT ) { +if (compat_put_timespec (&ts, + restart->nanosleep.compat_rmtp)) +return -EFAULT ; + } else +#endif +if (copy_to_user (restart->nanosleep.rmtp, &ts, +sizeof (ts)))return -EFAULT ; } restart->nanosleep.expires =timespec64_to_ns (rqtp);
kernel/time/posix-stubs.c +42 -13
73 lines not on this page · raw message
kernel/time/posix-timers.c +24 -8
@@ -49,6 +49,7 @@#include <linux/workqueue.h> #include <linux/export.h> #include <linux/hashtable.h> +#include <linux/compat.h> #include "timekeeping.h" #include "posix-timers.h"
@@ -1069,25 +1070,40 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,return -EINVAL ;if (flags &TIMER_ABSTIME ) rmtp =NULL ; + current->restart_block.nanosleep.type = rmtp ?TT_NATIVE :TT_NONE ; current->restart_block.nanosleep.rmtp = rmtp;return kc->nsleep (which_clock, flags, &t64); } -/* -* This will restart clock_nanosleep. This is required only by -* compat_clock_nanosleep_restart for now. -*/ -long clock_nanosleep_restart (struct restart_block *restart_block) +#ifdef CONFIG_COMPAT +COMPAT_SYSCALL_DEFINE4 (clock_nanosleep, clockid_t, which_clock, int, flags, + struct compat_timespec __user *, rqtp, + struct compat_timespec __user *, rmtp) { -clockid_t which_clock = restart_block->nanosleep.clockid;const struct k_clock *kc =clockid_to_kclock (which_clock); +struct timespec64 t64; +struct timespec t; -if (WARN_ON_ONCE (!kc || !kc->nsleep_restart)) +if (!kc)return -EINVAL ; +if (!kc->nsleep) +return -ENANOSLEEP_NOTSUP ; + +if (compat_get_timespec (&t, rqtp)) +return -EFAULT ; -return kc->nsleep_restart (restart_block); + t64 =timespec_to_timespec64 (t); +if (!timespec64_valid (&t64)) +return -EINVAL ; +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + current->restart_block.nanosleep.type = rmtp ?TT_COMPAT :TT_NONE ; + current->restart_block.nanosleep.compat_rmtp = rmtp; + +return kc->nsleep (which_clock, flags, &t64); } +#endif static const struct k_clock clock_realtime = { .clock_getres = posix_get_hrtimer_res,
PATCH 7/16 {clock_,}nanosleep(2): merge timespec copyout logics into a new helper
In reply to Al ViroFrom: Al Viro <[email protected]>
--- include/linux/hrtimer.h | 2 ++ kernel/time/alarmtimer.c | 10 +--------- kernel/time/hrtimer.c | 24 +++++++++++++++--------- kernel/time/posix-cpu-timers.c | 13 ++----------- 4 files changed, 20 insertions(+), 29 deletions(-)
include/linux/hrtimer.h +2 -0
@@ -452,6 +452,8 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer, }/* Precise sleep: */ + +extern int nanosleep_copyout (struct restart_block *,struct timespec *);extern long hrtimer_nanosleep (struct timespec64 *rqtp,const enum hrtimer_mode mode,const clockid_t clockid);
kernel/time/alarmtimer.c +1 -9
@@ -721,15 +721,7 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp,return 0 ; rmt =ktime_to_timespec (rem); -#ifdef CONFIG_COMPAT -if (restart->nanosleep.kind ==2 ) { -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 nanosleep_copyout (restart, &rmt); }return -ERESTART_RESTARTBLOCK ; }
kernel/time/hrtimer.c +15 -9
@@ -1440,6 +1440,20 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task) }EXPORT_SYMBOL_GPL (hrtimer_init_sleeper); +int nanosleep_copyout (struct restart_block *restart,struct timespec *ts) +{ +BUG_ON (!restart->nanosleep.kind); +#ifdef CONFIG_COMPAT +if (restart->nanosleep.kind ==2 ) { +if (compat_put_timespec (ts, restart->nanosleep.compat_rmtp)) +return -EFAULT ; + } else +#endif +if (copy_to_user (restart->nanosleep.rmtp, ts,sizeof (struct timespec ))) +return -EFAULT ; +return -ERESTART_RESTARTBLOCK ; +} + static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) {struct restart_block *restart;
@@ -1470,15 +1484,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode modreturn 0 ; rmt =ktime_to_timespec (rem); -#ifdef CONFIG_COMPAT -if (restart->nanosleep.kind ==2 ) { -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 nanosleep_copyout (restart, &rmt); }return -ERESTART_RESTARTBLOCK ; }
kernel/time/posix-cpu-timers.c +2 -11
@@ -1312,21 +1312,12 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,* Report back to the user the time still remaining. */ restart = ¤t->restart_block; + restart->nanosleep.expires =timespec64_to_ns (rqtp);if (restart->nanosleep.kind) {struct timespec ts; ts =timespec64_to_timespec (it.it_value); -#ifdef CONFIG_COMPAT -if (restart->nanosleep.kind ==2 ) { -if (compat_put_timespec (&ts, - restart->nanosleep.compat_rmtp)) -return -EFAULT ; - } else -#endif -if (copy_to_user (restart->nanosleep.rmtp, &ts, -sizeof (ts))) -return -EFAULT ; + error =nanosleep_copyout (restart, &ts); } - restart->nanosleep.expires =timespec64_to_ns (rqtp); }return error;
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] hrtimers/posix-timers: Merge nanosleep timespec copyout logics into a new helper
hrtimers/posix-timers: Merge nanosleep timespec copyout logics into a new helper
Commit-ID: ce41aaf47af3d28c4c958e07675a3e0a51f09bd3 Gitweb: http://git.kernel.org/tip/ce41aaf47af3d28c4c958e07675a3e0a51f09bd3 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:32 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:42 +0200
hrtimers/posix-timers: Merge nanosleep timespec copyout logics into a new helper
--- include/linux/hrtimer.h | 2 ++ kernel/time/alarmtimer.c | 10 +--------- kernel/time/hrtimer.c | 29 ++++++++++++++++++++--------- kernel/time/posix-cpu-timers.c | 13 ++----------- 4 files changed, 25 insertions(+), 29 deletions(-)
include/linux/hrtimer.h +2 -0
@@ -452,6 +452,8 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer, }/* Precise sleep: */ + +extern int nanosleep_copyout (struct restart_block *,struct timespec *);extern long hrtimer_nanosleep (struct timespec64 *rqtp,const enum hrtimer_mode mode,const clockid_t clockid);
kernel/time/alarmtimer.c +1 -9
@@ -721,15 +721,7 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp,return 0 ; rmt =ktime_to_timespec (rem); -#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 nanosleep_copyout (restart, &rmt); }return -ERESTART_RESTARTBLOCK ; }
kernel/time/hrtimer.c +20 -9
@@ -1440,6 +1440,25 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task) }EXPORT_SYMBOL_GPL (hrtimer_init_sleeper); +int nanosleep_copyout (struct restart_block *restart,struct timespec *ts) +{ +switch (restart->nanosleep.type) { +#ifdef CONFIG_COMPAT +case TT_COMPAT : +if (compat_put_timespec (ts, restart->nanosleep.compat_rmtp)) +return -EFAULT ; +break ; +#endif +case TT_NATIVE : +if (copy_to_user (restart->nanosleep.rmtp, ts,sizeof (struct timespec ))) +return -EFAULT ; +break ; +default : +BUG (); + } +return -ERESTART_RESTARTBLOCK ; +} + static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) {struct restart_block *restart;
@@ -1472,15 +1491,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode modreturn 0 ; rmt =ktime_to_timespec (rem); -#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 nanosleep_copyout (restart, &rmt); }return -ERESTART_RESTARTBLOCK ; }
kernel/time/posix-cpu-timers.c +2 -11
@@ -1312,22 +1312,13 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,* Report back to the user the time still remaining. */ restart = ¤t->restart_block; + restart->nanosleep.expires =timespec64_to_ns (rqtp);if (restart->nanosleep.type !=TT_NONE ) {struct timespec ts; ts =timespec64_to_timespec (it.it_value); -#ifdef CONFIG_COMPAT -if (restart->nanosleep.type ==TT_COMPAT ) { -if (compat_put_timespec (&ts, - restart->nanosleep.compat_rmtp)) -return -EFAULT ; - } else -#endif -if (copy_to_user (restart->nanosleep.rmtp, &ts, -sizeof (ts))) -return -EFAULT ; + error =nanosleep_copyout (restart, &ts); } - restart->nanosleep.expires =timespec64_to_ns (rqtp); }return error;
PATCH 8/16 kill ->nsleep_restart()
In reply to Al ViroFrom: Al Viro <[email protected]>
--- include/linux/hrtimer.h | 1 - kernel/time/hrtimer.c | 2 +- kernel/time/posix-cpu-timers.c | 6 ------ kernel/time/posix-timers.c | 4 ---- kernel/time/posix-timers.h | 1 - 5 files changed, 1 insertion(+), 13 deletions(-)
include/linux/hrtimer.h +0 -1
@@ -457,7 +457,6 @@ extern int nanosleep_copyout(struct restart_block *, struct timespec *);extern long hrtimer_nanosleep (struct timespec64 *rqtp,const enum hrtimer_mode mode,const clockid_t clockid); -extern long hrtimer_nanosleep_restart (struct restart_block *restart_block);extern void hrtimer_init_sleeper (struct hrtimer_sleeper *sl,struct task_struct *tsk);
kernel/time/hrtimer.c +1 -1
@@ -1489,7 +1489,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode modreturn -ERESTART_RESTARTBLOCK ; } -long __sched hrtimer_nanosleep_restart (struct restart_block *restart) +static long __sched hrtimer_nanosleep_restart (struct restart_block *restart) {struct hrtimer_sleeper t;int ret;
kernel/time/posix-cpu-timers.c +0 -6
@@ -1385,10 +1385,6 @@ static int process_cpu_nsleep(const clockid_t which_clock, int flags, {return posix_cpu_nsleep (PROCESS_CLOCK , flags, rqtp); } -static long process_cpu_nsleep_restart (struct restart_block *restart_block) -{ -return -EINVAL ; -}static int thread_cpu_clock_getres (const clockid_t which_clock,struct timespec64 *tp) {
@@ -1411,7 +1407,6 @@ const struct k_clock clock_posix_cpu = { .clock_get = posix_cpu_clock_get, .timer_create = posix_cpu_timer_create, .nsleep = posix_cpu_nsleep, - .nsleep_restart = posix_cpu_nsleep_restart, .timer_set = posix_cpu_timer_set, .timer_del = posix_cpu_timer_del, .timer_get = posix_cpu_timer_get,
@@ -1423,7 +1418,6 @@ const struct k_clock clock_process = { .clock_get = process_cpu_clock_get, .timer_create = process_cpu_timer_create, .nsleep = process_cpu_nsleep, - .nsleep_restart = process_cpu_nsleep_restart, };const struct k_clock clock_thread = {
kernel/time/posix-timers.c +0 -4
@@ -1096,7 +1096,6 @@ static const struct k_clock clock_realtime = { .clock_set = posix_clock_realtime_set, .clock_adj = posix_clock_realtime_adj, .nsleep = common_nsleep, - .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, .timer_set = common_timer_set, .timer_get = common_timer_get,
@@ -1112,7 +1111,6 @@ static const struct k_clock clock_monotonic = { .clock_getres = posix_get_hrtimer_res, .clock_get = posix_ktime_get_ts, .nsleep = common_nsleep, - .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, .timer_set = common_timer_set, .timer_get = common_timer_get,
@@ -1143,7 +1141,6 @@ static const struct k_clock clock_tai = { .clock_getres = posix_get_hrtimer_res, .clock_get = posix_get_tai, .nsleep = common_nsleep, - .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, .timer_set = common_timer_set, .timer_get = common_timer_get,
@@ -1159,7 +1156,6 @@ static const struct k_clock clock_boottime = { .clock_getres = posix_get_hrtimer_res, .clock_get = posix_get_boottime, .nsleep = common_nsleep, - .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, .timer_set = common_timer_set, .timer_get = common_timer_get,
kernel/time/posix-timers.h +0 -1
@@ -11,7 +11,6 @@ struct k_clock {int (*timer_create)(struct k_itimer *timer);int (*nsleep)(const clockid_t which_clock,int flags,struct timespec64 *); -long (*nsleep_restart)(struct restart_block *restart_block);int (*timer_set)(struct k_itimer *timr,int flags,struct itimerspec64 *new_setting,struct itimerspec64 *old_setting);
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] posix-timers: Kill ->nsleep_restart()
posix-timers: Kill ->nsleep_restart()
Commit-ID: fb923c4a3c2ee735755d4a93522150fc35d0ecbd Gitweb: http://git.kernel.org/tip/fb923c4a3c2ee735755d4a93522150fc35d0ecbd Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:33 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:42 +0200
posix-timers: Kill ->nsleep_restart()
No more users.
--- include/linux/hrtimer.h | 1 - kernel/time/hrtimer.c | 2 +- kernel/time/posix-cpu-timers.c | 6 ------ kernel/time/posix-timers.c | 4 ---- kernel/time/posix-timers.h | 1 - 5 files changed, 1 insertion(+), 13 deletions(-)
include/linux/hrtimer.h +0 -1
@@ -457,7 +457,6 @@ extern int nanosleep_copyout(struct restart_block *, struct timespec *);extern long hrtimer_nanosleep (struct timespec64 *rqtp,const enum hrtimer_mode mode,const clockid_t clockid); -extern long hrtimer_nanosleep_restart (struct restart_block *restart_block);extern void hrtimer_init_sleeper (struct hrtimer_sleeper *sl,struct task_struct *tsk);
kernel/time/hrtimer.c +1 -1
@@ -1496,7 +1496,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode modreturn -ERESTART_RESTARTBLOCK ; } -long __sched hrtimer_nanosleep_restart (struct restart_block *restart) +static long __sched hrtimer_nanosleep_restart (struct restart_block *restart) {struct hrtimer_sleeper t;int ret;
kernel/time/posix-cpu-timers.c +0 -6
@@ -1386,10 +1386,6 @@ static int process_cpu_nsleep(const clockid_t which_clock, int flags, {return posix_cpu_nsleep (PROCESS_CLOCK , flags, rqtp); } -static long process_cpu_nsleep_restart (struct restart_block *restart_block) -{ -return -EINVAL ; -}static int thread_cpu_clock_getres (const clockid_t which_clock,struct timespec64 *tp) {
@@ -1412,7 +1408,6 @@ const struct k_clock clock_posix_cpu = { .clock_get = posix_cpu_clock_get, .timer_create = posix_cpu_timer_create, .nsleep = posix_cpu_nsleep, - .nsleep_restart = posix_cpu_nsleep_restart, .timer_set = posix_cpu_timer_set, .timer_del = posix_cpu_timer_del, .timer_get = posix_cpu_timer_get,
@@ -1424,7 +1419,6 @@ const struct k_clock clock_process = { .clock_get = process_cpu_clock_get, .timer_create = process_cpu_timer_create, .nsleep = process_cpu_nsleep, - .nsleep_restart = process_cpu_nsleep_restart, };const struct k_clock clock_thread = {
kernel/time/posix-timers.c +0 -4
@@ -1111,7 +1111,6 @@ static const struct k_clock clock_realtime = { .clock_set = posix_clock_realtime_set, .clock_adj = posix_clock_realtime_adj, .nsleep = common_nsleep, - .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, .timer_set = common_timer_set, .timer_get = common_timer_get,
@@ -1127,7 +1126,6 @@ static const struct k_clock clock_monotonic = { .clock_getres = posix_get_hrtimer_res, .clock_get = posix_ktime_get_ts, .nsleep = common_nsleep, - .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, .timer_set = common_timer_set, .timer_get = common_timer_get,
@@ -1158,7 +1156,6 @@ static const struct k_clock clock_tai = { .clock_getres = posix_get_hrtimer_res, .clock_get = posix_get_tai, .nsleep = common_nsleep, - .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, .timer_set = common_timer_set, .timer_get = common_timer_get,
@@ -1174,7 +1171,6 @@ static const struct k_clock clock_boottime = { .clock_getres = posix_get_hrtimer_res, .clock_get = posix_get_boottime, .nsleep = common_nsleep, - .nsleep_restart = hrtimer_nanosleep_restart, .timer_create = common_timer_create, .timer_set = common_timer_set, .timer_get = common_timer_get,
kernel/time/posix-timers.h +0 -1
@@ -11,7 +11,6 @@ struct k_clock {int (*timer_create)(struct k_itimer *timer);int (*nsleep)(const clockid_t which_clock,int flags,struct timespec64 *); -long (*nsleep_restart)(struct restart_block *restart_block);int (*timer_set)(struct k_itimer *timr,int flags,struct itimerspec64 *new_setting,struct itimerspec64 *old_setting);
PATCH 9/16 move adjtimex-related compat syscalls to native counterparts
In reply to Al ViroFrom: Al Viro <[email protected]>
Get rid of set_fs() mess and sanitize compat_{get,put}_timex(), while we are at it.
--- include/linux/compat.h | 4 ++ kernel/compat.c | 141 +++++++++++++++++---------------------------- kernel/time/posix-stubs.c | 2 + kernel/time/posix-timers.c | 27 +++++++++ kernel/time/time.c | 24 +++++++- 5 files changed, 108 insertions(+), 90 deletions(-)
include/linux/compat.h +4 -0
@@ -128,6 +128,10 @@ struct compat_timex { compat_int_t:32 ; compat_int_t:32 ; compat_int_t:32 ; }; +struct timex ; +int compat_get_timex (struct timex *,const struct compat_timex __user *); +int compat_put_timex (struct compat_timex __user *,const struct timex *); +#define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) typedef struct {
kernel/compat.c +52 -89
165 lines not on this page · raw message
kernel/time/posix-stubs.c +2 -0
@@ -28,6 +28,7 @@ asmlinkage long sys_ni_posix_timers(void) }#define SYS_NI (name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers) +#define COMPAT_SYS_NI (name) SYSCALL_ALIAS(compat_sys_##name, sys_ni_posix_timers)SYS_NI (timer_create);SYS_NI (timer_gettime);
@@ -40,6 +41,7 @@ SYS_NI(setitimer);#ifdef __ARCH_WANT_SYS_ALARMSYS_NI (alarm);#endif +COMPAT_SYS_NI (clock_adjtime);/* * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
kernel/time/posix-timers.c +27 -0
@@ -1003,6 +1003,33 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,return err; } +#ifdef CONFIG_COMPAT + +COMPAT_SYSCALL_DEFINE2 (clock_adjtime, clockid_t, which_clock, + struct compat_timex __user *, utp) +{ +const struct k_clock *kc =clockid_to_kclock (which_clock); +struct timex ktx; +int err; + +if (!kc) +return -EINVAL ; +if (!kc->clock_adj) +return -EOPNOTSUPP ; + + err =compat_get_timex (&ktx, utp); +if (err) +return err; + + err = kc->clock_adj (which_clock, &ktx); + +if (err >=0 ) + err =compat_put_timex (utp, &ktx); + +return err; +} +#endif + SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) {
kernel/time/time.c +23 -1
@@ -39,6 +39,7 @@#include <linux/ptrace.h> #include <linux/uaccess.h> +#include <linux/compat.h> #include <asm/unistd.h> #include <generated/timeconst.h>
@@ -224,12 +225,33 @@ SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p)* structure. But bear in mind that the structures * may change */ -if (copy_from_user (&txc, txc_p,sizeof (struct timex ))) +if (copy_from_user (&txc, txc_p,sizeof (struct timex )))return -EFAULT ; ret =do_adjtimex (&txc);return copy_to_user (txc_p, &txc,sizeof (struct timex )) ? -EFAULT : ret; } +#ifdef CONFIG_COMPAT + +COMPAT_SYSCALL_DEFINE1(adjtimex, struct compat_timex __user *, utp) +{ +struct timex txc; +int err, ret; + + err =compat_get_timex (&txc, utp); +if (err) +return err; + + ret =do_adjtimex (&txc); + + err =compat_put_timex (utp, &txc); +if (err) +return err; + +return ret; +} +#endif +/* * Convert jiffies to milliseconds and back. *
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] ntp: Move adjtimex related compat syscalls to native counterparts
ntp: Move adjtimex related compat syscalls to native counterparts
Commit-ID: 3a4d44b6162555070194e486ff6b3799a8d323a2 Gitweb: http://git.kernel.org/tip/3a4d44b6162555070194e486ff6b3799a8d323a2 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:34 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:43 +0200
ntp: Move adjtimex related compat syscalls to native counterparts
Get rid of set_fs() mess and sanitize compat_{get,put}_timex(), while we are at it.
--- include/linux/compat.h | 4 ++ kernel/compat.c | 141 +++++++++++++++++---------------------------- kernel/time/posix-stubs.c | 2 + kernel/time/posix-timers.c | 27 +++++++++ kernel/time/time.c | 24 +++++++- 5 files changed, 108 insertions(+), 90 deletions(-)
include/linux/compat.h +4 -0
@@ -128,6 +128,10 @@ struct compat_timex { compat_int_t:32 ; compat_int_t:32 ; compat_int_t:32 ; }; +struct timex ; +int compat_get_timex (struct timex *,const struct compat_timex __user *); +int compat_put_timex (struct compat_timex __user *,const struct timex *); +#define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) typedef struct {
kernel/compat.c +52 -89
165 lines not on this page · raw message
kernel/time/posix-stubs.c +2 -0
@@ -28,6 +28,7 @@ asmlinkage long sys_ni_posix_timers(void) }#define SYS_NI (name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers) +#define COMPAT_SYS_NI (name) SYSCALL_ALIAS(compat_sys_##name, sys_ni_posix_timers)SYS_NI (timer_create);SYS_NI (timer_gettime);
@@ -40,6 +41,7 @@ SYS_NI(setitimer);#ifdef __ARCH_WANT_SYS_ALARMSYS_NI (alarm);#endif +COMPAT_SYS_NI (clock_adjtime);/* * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
kernel/time/posix-timers.c +27 -0
@@ -1018,6 +1018,33 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,return err; } +#ifdef CONFIG_COMPAT + +COMPAT_SYSCALL_DEFINE2 (clock_adjtime, clockid_t, which_clock, + struct compat_timex __user *, utp) +{ +const struct k_clock *kc =clockid_to_kclock (which_clock); +struct timex ktx; +int err; + +if (!kc) +return -EINVAL ; +if (!kc->clock_adj) +return -EOPNOTSUPP ; + + err =compat_get_timex (&ktx, utp); +if (err) +return err; + + err = kc->clock_adj (which_clock, &ktx); + +if (err >=0 ) + err =compat_put_timex (utp, &ktx); + +return err; +} +#endif + SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) {
kernel/time/time.c +23 -1
@@ -39,6 +39,7 @@#include <linux/ptrace.h> #include <linux/uaccess.h> +#include <linux/compat.h> #include <asm/unistd.h> #include <generated/timeconst.h>
@@ -224,12 +225,33 @@ SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p)* structure. But bear in mind that the structures * may change */ -if (copy_from_user (&txc, txc_p,sizeof (struct timex ))) +if (copy_from_user (&txc, txc_p,sizeof (struct timex )))return -EFAULT ; ret =do_adjtimex (&txc);return copy_to_user (txc_p, &txc,sizeof (struct timex )) ? -EFAULT : ret; } +#ifdef CONFIG_COMPAT + +COMPAT_SYSCALL_DEFINE1(adjtimex, struct compat_timex __user *, utp) +{ +struct timex txc; +int err, ret; + + err =compat_get_timex (&txc, utp); +if (err) +return err; + + ret =do_adjtimex (&txc); + + err =compat_put_timex (utp, &txc); +if (err) +return err; + +return ret; +} +#endif +/* * Convert jiffies to milliseconds and back. *
PATCH 10/16 take compat timer_settime(2) to native one
In reply to Al ViroFrom: Al Viro <[email protected]>
... and get rid of set_fs() in there
--- kernel/compat.c | 23 ------------- kernel/time/posix-stubs.c | 1 + kernel/time/posix-timers.c | 83 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 62 insertions(+), 45 deletions(-)
kernel/compat.c +0 -23
@@ -635,29 +635,6 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,return sys_timer_create (which_clock, event, created_timer_id); } -COMPAT_SYSCALL_DEFINE4 (timer_settime, timer_t, timer_id, int, flags, - struct compat_itimerspec __user *, new, - struct compat_itimerspec __user *, old) -{ -long err; -mm_segment_t oldfs; -struct itimerspec newts, oldts; - -if (!new) -return -EINVAL ; -if (get_compat_itimerspec (&newts, new)) -return -EFAULT ; - oldfs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_timer_settime (timer_id, flags, - (struct itimerspec __user *) &newts, - (struct itimerspec __user *) &oldts); -set_fs (oldfs); -if (!err && old &&put_compat_itimerspec (old, &oldts)) -return -EFAULT ; -return err; -} -COMPAT_SYSCALL_DEFINE2 (timer_gettime, timer_t, timer_id, struct compat_itimerspec __user *, setting) {
kernel/time/posix-stubs.c +1 -0
@@ -42,6 +42,7 @@ SYS_NI(setitimer);SYS_NI (alarm);#endif COMPAT_SYS_NI (clock_adjtime); +COMPAT_SYS_NI (timer_settime);/* * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
kernel/time/posix-timers.c +61 -22
111 lines not on this page · raw message
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] posix-timers: Take compat timer_settime(2) to native one
posix-timers: Take compat timer_settime(2) to native one
Commit-ID: 1acbe7708b0313b33287bb4ffcbf26462ea3c588 Gitweb: http://git.kernel.org/tip/1acbe7708b0313b33287bb4ffcbf26462ea3c588 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:35 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:43 +0200
posix-timers: Take compat timer_settime(2) to native one
... and get rid of set_fs() in there
--- kernel/compat.c | 23 ------------ kernel/time/posix-stubs.c | 1 + kernel/time/posix-timers.c | 87 +++++++++++++++++++++++++++++++++------------- 3 files changed, 64 insertions(+), 47 deletions(-)
kernel/compat.c +0 -23
@@ -635,29 +635,6 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,return sys_timer_create (which_clock, event, created_timer_id); } -COMPAT_SYSCALL_DEFINE4 (timer_settime, timer_t, timer_id, int, flags, - struct compat_itimerspec __user *, new, - struct compat_itimerspec __user *, old) -{ -long err; -mm_segment_t oldfs; -struct itimerspec newts, oldts; - -if (!new) -return -EINVAL ; -if (get_compat_itimerspec (&newts, new)) -return -EFAULT ; - oldfs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_timer_settime (timer_id, flags, - (struct itimerspec __user *) &newts, - (struct itimerspec __user *) &oldts); -set_fs (oldfs); -if (!err && old &&put_compat_itimerspec (old, &oldts)) -return -EFAULT ; -return err; -} -COMPAT_SYSCALL_DEFINE2 (timer_gettime, timer_t, timer_id, struct compat_itimerspec __user *, setting) {
kernel/time/posix-stubs.c +1 -0
@@ -42,6 +42,7 @@ SYS_NI(setitimer);SYS_NI (alarm);#endif COMPAT_SYS_NI (clock_adjtime); +COMPAT_SYS_NI (timer_settime);/* * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
kernel/time/posix-timers.c +63 -24
116 lines not on this page · raw message
PATCH 11/16 take compat timer_gettime(2) to native one
In reply to Al ViroFrom: Al Viro <[email protected]>
... and get rid of set_fs() in there
--- kernel/compat.c | 17 ----------------- kernel/time/posix-stubs.c | 1 + kernel/time/posix-timers.c | 44 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 36 insertions(+), 26 deletions(-)
kernel/compat.c +0 -17
@@ -635,23 +635,6 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,return sys_timer_create (which_clock, event, created_timer_id); } -COMPAT_SYSCALL_DEFINE2 (timer_gettime, timer_t, timer_id, - struct compat_itimerspec __user *, setting) -{ -long err; -mm_segment_t oldfs; -struct itimerspec ts; - - oldfs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_timer_gettime (timer_id, - (struct itimerspec __user *) &ts); -set_fs (oldfs); -if (!err &&put_compat_itimerspec (setting, &ts)) -return -EFAULT ; -return err; -} -COMPAT_SYSCALL_DEFINE2 (clock_settime, clockid_t, which_clock, struct compat_timespec __user *, tp) {
kernel/time/posix-stubs.c +1 -0
@@ -43,6 +43,7 @@ SYS_NI(alarm);#endif COMPAT_SYS_NI (clock_adjtime);COMPAT_SYS_NI (timer_settime); +COMPAT_SYS_NI (timer_gettime);/* * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
kernel/time/posix-timers.c +35 -9
67 lines not on this page · raw message
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] posix-timers: Take compat timer_gettime(2) to native one
posix-timers: Take compat timer_gettime(2) to native one
Commit-ID: b0dc12426ec404de99d7e75a12a22d9201d90914 Gitweb: http://git.kernel.org/tip/b0dc12426ec404de99d7e75a12a22d9201d90914 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:36 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:43 +0200
posix-timers: Take compat timer_gettime(2) to native one
... and get rid of set_fs() in there
--- kernel/compat.c | 17 ----------------- kernel/time/posix-stubs.c | 1 + kernel/time/posix-timers.c | 43 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 35 insertions(+), 26 deletions(-)
kernel/compat.c +0 -17
@@ -635,23 +635,6 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,return sys_timer_create (which_clock, event, created_timer_id); } -COMPAT_SYSCALL_DEFINE2 (timer_gettime, timer_t, timer_id, - struct compat_itimerspec __user *, setting) -{ -long err; -mm_segment_t oldfs; -struct itimerspec ts; - - oldfs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_timer_gettime (timer_id, - (struct itimerspec __user *) &ts); -set_fs (oldfs); -if (!err &&put_compat_itimerspec (setting, &ts)) -return -EFAULT ; -return err; -} -COMPAT_SYSCALL_DEFINE2 (clock_settime, clockid_t, which_clock, struct compat_timespec __user *, tp) {
kernel/time/posix-stubs.c +1 -0
@@ -43,6 +43,7 @@ SYS_NI(alarm);#endif COMPAT_SYS_NI (clock_adjtime);COMPAT_SYS_NI (timer_settime); +COMPAT_SYS_NI (timer_gettime);/* * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
kernel/time/posix-timers.c +34 -9
66 lines not on this page · raw message
PATCH 12/16 move compat itimer syscalls to native ones
In reply to Al ViroFrom: Al Viro <[email protected]>
get rid of set_fs(), sanitize compat copyin/copyout.
--- include/linux/compat.h | 4 +++ kernel/compat.c | 71 +++++++++++------------------------------------ kernel/time/itimer.c | 36 ++++++++++++++++++++++++ kernel/time/posix-stubs.c | 2 ++ 4 files changed, 58 insertions(+), 55 deletions(-)
include/linux/compat.h +4 -0
@@ -94,6 +94,10 @@ struct compat_itimerval {struct compat_timeval it_value; }; +struct itimerval ; +int get_compat_itimerval (struct itimerval *,const struct compat_itimerval __user *); +int put_compat_itimerval (struct compat_itimerval __user *,const struct itimerval *); +struct compat_tms {compat_clock_t tms_utime;compat_clock_t tms_stime;
kernel/compat.c +16 -55
81 lines not on this page · raw message
kernel/time/itimer.c +36 -0
@@ -15,6 +15,7 @@#include <linux/posix-timers.h> #include <linux/hrtimer.h> #include <trace/events/timer.h> +#include <linux/compat.h> #include <linux/uaccess.h>
@@ -116,6 +117,18 @@ SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value)return error; } +#ifdef CONFIG_COMPAT +COMPAT_SYSCALL_DEFINE2 (getitimer, int, which, + struct compat_itimerval __user *, it) +{ +struct itimerval kit; +int error =do_getitimer (which, &kit); +if (!error &&put_compat_itimerval (it, &kit)) + error = -EFAULT ; +return error; +} +#endif +/* * The timer is automagically restarted, when interval != 0
@@ -294,3 +307,26 @@ SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,return -EFAULT ;return 0 ; } + +#ifdef CONFIG_COMPAT +COMPAT_SYSCALL_DEFINE3 (setitimer, int, which, + struct compat_itimerval __user *, in, + struct compat_itimerval __user *, out) +{ +struct itimerval kin, kout; +int error; + +if (in) { +if (get_compat_itimerval (&kin, in)) +return -EFAULT ; + }else +memset (&kin,0 ,sizeof (kin)); + + error =do_setitimer (which, &kin, out ? &kout :NULL ); +if (error || !out) +return error; +if (put_compat_itimerval (out, &kout)) +return -EFAULT ; +return 0 ; +} +#endif
kernel/time/posix-stubs.c +2 -0
@@ -44,6 +44,8 @@ SYS_NI(alarm);COMPAT_SYS_NI (clock_adjtime);COMPAT_SYS_NI (timer_settime);COMPAT_SYS_NI (timer_gettime); +COMPAT_SYS_NI (getitimer); +COMPAT_SYS_NI (setitimer);/* * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] itimers: Move compat itimer syscalls to native ones
itimers: Move compat itimer syscalls to native ones
Commit-ID: 54ad9c46c262ce4a603dc7887e37956896a0211d Gitweb: http://git.kernel.org/tip/54ad9c46c262ce4a603dc7887e37956896a0211d Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:37 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:44 +0200
itimers: Move compat itimer syscalls to native ones
get rid of set_fs(), sanitize compat copyin/copyout.
--- include/linux/compat.h | 4 +++ kernel/compat.c | 69 +++++++++++------------------------------------ kernel/time/itimer.c | 38 ++++++++++++++++++++++++++ kernel/time/posix-stubs.c | 2 ++ 4 files changed, 60 insertions(+), 53 deletions(-)
include/linux/compat.h +4 -0
@@ -94,6 +94,10 @@ struct compat_itimerval {struct compat_timeval it_value; }; +struct itimerval ; +int get_compat_itimerval (struct itimerval *,const struct compat_itimerval __user *); +int put_compat_itimerval (struct compat_itimerval __user *,const struct itimerval *); +struct compat_tms {compat_clock_t tms_utime;compat_clock_t tms_stime;
kernel/compat.c +16 -53
81 lines not on this page · raw message
kernel/time/itimer.c +38 -0
@@ -15,6 +15,7 @@#include <linux/posix-timers.h> #include <linux/hrtimer.h> #include <trace/events/timer.h> +#include <linux/compat.h> #include <linux/uaccess.h>
@@ -116,6 +117,19 @@ SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value)return error; } +#ifdef CONFIG_COMPAT +COMPAT_SYSCALL_DEFINE2 (getitimer, int, which, + struct compat_itimerval __user *, it) +{ +struct itimerval kit; +int error =do_getitimer (which, &kit); + +if (!error &&put_compat_itimerval (it, &kit)) + error = -EFAULT ; +return error; +} +#endif +/* * The timer is automagically restarted, when interval != 0
@@ -294,3 +308,27 @@ SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,return -EFAULT ;return 0 ; } + +#ifdef CONFIG_COMPAT +COMPAT_SYSCALL_DEFINE3 (setitimer, int, which, + struct compat_itimerval __user *, in, + struct compat_itimerval __user *, out) +{ +struct itimerval kin, kout; +int error; + +if (in) { +if (get_compat_itimerval (&kin, in)) +return -EFAULT ; + }else { +memset (&kin,0 ,sizeof (kin)); + } + + error =do_setitimer (which, &kin, out ? &kout :NULL ); +if (error || !out) +return error; +if (put_compat_itimerval (out, &kout)) +return -EFAULT ; +return 0 ; +} +#endif
kernel/time/posix-stubs.c +2 -0
@@ -44,6 +44,8 @@ SYS_NI(alarm);COMPAT_SYS_NI (clock_adjtime);COMPAT_SYS_NI (timer_settime);COMPAT_SYS_NI (timer_gettime); +COMPAT_SYS_NI (getitimer); +COMPAT_SYS_NI (setitimer);/* * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC
PATCH 13/16 clock_gettime/clock_settime/clock_getres: move to native syscalls
In reply to Al ViroFrom: Al Viro <[email protected]>
--- kernel/compat.c | 51 ----------------------------------- kernel/time/posix-stubs.c | 52 ++++++++++++++++++++++++++++++++++++ kernel/time/posix-timers.c | 66 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 114 insertions(+), 55 deletions(-)
kernel/compat.c +0 -51
@@ -596,57 +596,6 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,return sys_timer_create (which_clock, event, created_timer_id); } -COMPAT_SYSCALL_DEFINE2 (clock_settime, clockid_t, which_clock, - struct compat_timespec __user *, tp) -{ -long err; -mm_segment_t oldfs; -struct timespec ts; - -if (compat_get_timespec (&ts, tp)) -return -EFAULT ; - oldfs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_clock_settime (which_clock, - (struct timespec __user *) &ts); -set_fs (oldfs); -return err; -} - -COMPAT_SYSCALL_DEFINE2 (clock_gettime, clockid_t, which_clock, - struct compat_timespec __user *, tp) -{ -long err; -mm_segment_t oldfs; -struct timespec ts; - - oldfs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_clock_gettime (which_clock, - (struct timespec __user *) &ts); -set_fs (oldfs); -if (!err &&compat_put_timespec (&ts, tp)) -return -EFAULT ; -return err; -} - -COMPAT_SYSCALL_DEFINE2 (clock_getres, clockid_t, which_clock, - struct compat_timespec __user *, tp) -{ -long err; -mm_segment_t oldfs; -struct timespec ts; - - oldfs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_clock_getres (which_clock, - (struct timespec __user *) &ts); -set_fs (oldfs); -if (!err && tp &&compat_put_timespec (&ts, tp)) -return -EFAULT ; -return err; -} -/* * We currently only need the following fields from the sigevent * structure: sigev_value, sigev_signo, sig_notify and (sometimes
kernel/time/posix-stubs.c +52 -0
58 lines not on this page · raw message
kernel/time/posix-timers.c +62 -4
91 lines not on this page · raw message
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] posix-timers: Move compat versions of clock_gettime/settime/getres
posix-timers: Move compat versions of clock_gettime/settime/getres
Commit-ID: d822cdcce43f9d4dcddbf9c68f9537d542ccc3c3 Gitweb: http://git.kernel.org/tip/d822cdcce43f9d4dcddbf9c68f9537d542ccc3c3 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:38 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:44 +0200
posix-timers: Move compat versions of clock_gettime/settime/getres
Move them to the native implementations and get rid of the set_fs() hackery.
--- kernel/compat.c | 51 ----------------------------------- kernel/time/posix-stubs.c | 53 +++++++++++++++++++++++++++++++++++++ kernel/time/posix-timers.c | 66 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 115 insertions(+), 55 deletions(-)
kernel/compat.c +0 -51
@@ -598,57 +598,6 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock,return sys_timer_create (which_clock, event, created_timer_id); } -COMPAT_SYSCALL_DEFINE2 (clock_settime, clockid_t, which_clock, - struct compat_timespec __user *, tp) -{ -long err; -mm_segment_t oldfs; -struct timespec ts; - -if (compat_get_timespec (&ts, tp)) -return -EFAULT ; - oldfs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_clock_settime (which_clock, - (struct timespec __user *) &ts); -set_fs (oldfs); -return err; -} - -COMPAT_SYSCALL_DEFINE2 (clock_gettime, clockid_t, which_clock, - struct compat_timespec __user *, tp) -{ -long err; -mm_segment_t oldfs; -struct timespec ts; - - oldfs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_clock_gettime (which_clock, - (struct timespec __user *) &ts); -set_fs (oldfs); -if (!err &&compat_put_timespec (&ts, tp)) -return -EFAULT ; -return err; -} - -COMPAT_SYSCALL_DEFINE2 (clock_getres, clockid_t, which_clock, - struct compat_timespec __user *, tp) -{ -long err; -mm_segment_t oldfs; -struct timespec ts; - - oldfs =get_fs (); -set_fs (KERNEL_DS ); - err =sys_clock_getres (which_clock, - (struct timespec __user *) &ts); -set_fs (oldfs); -if (!err && tp &&compat_put_timespec (&ts, tp)) -return -EFAULT ; -return err; -} -/* * We currently only need the following fields from the sigevent * structure: sigev_value, sigev_signo, sig_notify and (sometimes
kernel/time/posix-stubs.c +53 -0
59 lines not on this page · raw message
kernel/time/posix-timers.c +62 -4
91 lines not on this page · raw message
PATCH 14/16 timer_create(): move compat to native, get rid of set_fs()
In reply to Al ViroFrom: Al Viro <[email protected]>
--- kernel/compat.c | 18 --------------- kernel/time/posix-stubs.c | 1 + kernel/time/posix-timers.c | 57 ++++++++++++++++++++++++++++++++-------------- 3 files changed, 41 insertions(+), 35 deletions(-)
kernel/compat.c +0 -18
@@ -578,24 +578,6 @@ int put_compat_itimerspec(struct compat_itimerspec __user *dst,return 0 ; } -COMPAT_SYSCALL_DEFINE3 (timer_create, clockid_t, which_clock, - struct compat_sigevent __user *, timer_event_spec, - timer_t __user *, created_timer_id) -{ -struct sigevent __user *event =NULL ; - -if (timer_event_spec) { -struct sigevent kevent; - - event =compat_alloc_user_space (sizeof (*event)); -if (get_compat_sigevent (&kevent, timer_event_spec) || -copy_to_user (event, &kevent,sizeof (*event))) -return -EFAULT ; - } - -return sys_timer_create (which_clock, event, created_timer_id); -} -/* * We currently only need the following fields from the sigevent * structure: sigev_value, sigev_signo, sig_notify and (sometimes
kernel/time/posix-stubs.c +1 -0
@@ -41,6 +41,7 @@ SYS_NI(setitimer);#ifdef __ARCH_WANT_SYS_ALARMSYS_NI (alarm);#endif +COMPAT_SYS_NI (timer_create);COMPAT_SYS_NI (clock_adjtime);COMPAT_SYS_NI (timer_settime);COMPAT_SYS_NI (timer_gettime);
kernel/time/posix-timers.c +40 -17
89 lines not on this page · raw message
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] posix-timers: Move compat_timer_create() to native, get rid of set_fs()
posix-timers: Move compat_timer_create() to native, get rid of set_fs()
Commit-ID: 2482097c6c0f01ad74c9b2cff120a519ac59846e Gitweb: http://git.kernel.org/tip/2482097c6c0f01ad74c9b2cff120a519ac59846e Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:39 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:45 +0200
posix-timers: Move compat_timer_create() to native, get rid of set_fs()
--- kernel/compat.c | 18 -------------- kernel/time/posix-stubs.c | 1 + kernel/time/posix-timers.c | 59 ++++++++++++++++++++++++++++++++-------------- 3 files changed, 42 insertions(+), 36 deletions(-)
kernel/compat.c +0 -18
@@ -580,24 +580,6 @@ int put_compat_itimerspec(struct compat_itimerspec __user *dst,return 0 ; } -COMPAT_SYSCALL_DEFINE3 (timer_create, clockid_t, which_clock, - struct compat_sigevent __user *, timer_event_spec, - timer_t __user *, created_timer_id) -{ -struct sigevent __user *event =NULL ; - -if (timer_event_spec) { -struct sigevent kevent; - - event =compat_alloc_user_space (sizeof (*event)); -if (get_compat_sigevent (&kevent, timer_event_spec) || -copy_to_user (event, &kevent,sizeof (*event))) -return -EFAULT ; - } - -return sys_timer_create (which_clock, event, created_timer_id); -} -/* * We currently only need the following fields from the sigevent * structure: sigev_value, sigev_signo, sig_notify and (sometimes
kernel/time/posix-stubs.c +1 -0
@@ -41,6 +41,7 @@ SYS_NI(setitimer);#ifdef __ARCH_WANT_SYS_ALARMSYS_NI (alarm);#endif +COMPAT_SYS_NI (timer_create);COMPAT_SYS_NI (clock_adjtime);COMPAT_SYS_NI (timer_settime);COMPAT_SYS_NI (timer_gettime);
kernel/time/posix-timers.c +41 -18
91 lines not on this page · raw message
PATCH 15/16 time()/stime(): move compat to native
In reply to Al ViroFrom: Al Viro <[email protected]>
--- kernel/compat.c | 40 ---------------------------------------- kernel/time/time.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 40 deletions(-)
kernel/compat.c +0 -40
@@ -737,46 +737,6 @@ COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,return ret; } -#ifdef __ARCH_WANT_COMPAT_SYS_TIME - -/* compat_time_t is a 32 bit "long" and needs to get converted. */ - -COMPAT_SYSCALL_DEFINE1(time, compat_time_t __user *, tloc) -{ -compat_time_t i; -struct timeval tv; - -do_gettimeofday (&tv); - i = tv.tv_sec; - -if (tloc) { -if (put_user (i,tloc)) -return -EFAULT ; - } -force_successful_syscall_return (); -return i; -} - -COMPAT_SYSCALL_DEFINE1(stime, compat_time_t __user *, tptr) -{ -struct timespec tv; -int err; - -if (get_user (tv.tv_sec, tptr)) -return -EFAULT ; - - tv.tv_nsec =0 ; - - err =security_settime (&tv,NULL ); -if (err) -return err; - -do_settimeofday (&tv); -return 0 ; -} - -#endif /* __ARCH_WANT_COMPAT_SYS_TIME */ -#ifdef CONFIG_NUMA COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages, compat_uptr_t __user *, pages32,
kernel/time/time.c +42 -0
48 lines not on this page · raw message
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] time: Move compat_time()/stime() to native
time: Move compat_time()/stime() to native
Commit-ID: b180db2c8ca6692a10b79631cadc18d03303d494 Gitweb: http://git.kernel.org/tip/b180db2c8ca6692a10b79631cadc18d03303d494 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:40 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:45 +0200
time: Move compat_time()/stime() to native
--- kernel/compat.c | 40 ---------------------------------------- kernel/time/time.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 40 deletions(-)
kernel/compat.c +0 -40
@@ -739,46 +739,6 @@ COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,return ret; } -#ifdef __ARCH_WANT_COMPAT_SYS_TIME - -/* compat_time_t is a 32 bit "long" and needs to get converted. */ - -COMPAT_SYSCALL_DEFINE1(time, compat_time_t __user *, tloc) -{ -compat_time_t i; -struct timeval tv; - -do_gettimeofday (&tv); - i = tv.tv_sec; - -if (tloc) { -if (put_user (i,tloc)) -return -EFAULT ; - } -force_successful_syscall_return (); -return i; -} - -COMPAT_SYSCALL_DEFINE1(stime, compat_time_t __user *, tptr) -{ -struct timespec tv; -int err; - -if (get_user (tv.tv_sec, tptr)) -return -EFAULT ; - - tv.tv_nsec =0 ; - - err =security_settime (&tv,NULL ); -if (err) -return err; - -do_settimeofday (&tv); -return 0 ; -} - -#endif /* __ARCH_WANT_COMPAT_SYS_TIME */ -#ifdef CONFIG_NUMA COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages, compat_uptr_t __user *, pages32,
kernel/time/time.c +41 -0
47 lines not on this page · raw message
PATCH 16/16 gettimeofday()/settimeofday(): move compat to native
In reply to Al ViroFrom: Al Viro <[email protected]>
--- kernel/compat.c | 38 -------------------------------------- kernel/time/time.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 38 deletions(-)
kernel/compat.c +0 -38
@@ -92,44 +92,6 @@ int compat_put_timex(struct compat_timex __user *utp, const struct timex *txc)return 0 ; } -COMPAT_SYSCALL_DEFINE2(gettimeofday, struct compat_timeval __user *, tv, - struct timezone __user *, tz) -{ -if (tv) { -struct timeval ktv; -do_gettimeofday (&ktv); -if (compat_put_timeval (&ktv, tv)) -return -EFAULT ; - } -if (tz) { -if (copy_to_user (tz, &sys_tz,sizeof (sys_tz))) -return -EFAULT ; - } - -return 0 ; -} - -COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv, - struct timezone __user *, tz) -{ -struct timespec64 new_ts; -struct timeval user_tv; -struct timezone new_tz; - -if (tv) { -if (compat_get_timeval (&user_tv, tv)) -return -EFAULT ; - new_ts.tv_sec = user_tv.tv_sec; - new_ts.tv_nsec = user_tv.tv_usec *NSEC_PER_USEC ; - } -if (tz) { -if (copy_from_user (&new_tz, tz,sizeof (*tz))) -return -EFAULT ; - } - -return do_sys_settimeofday64 (tv ? &new_ts :NULL , tz ? &new_tz :NULL ); -} -static int __compat_get_timeval (struct timeval *tv,const struct compat_timeval __user *ctv) { return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) ||
kernel/time/time.c +40 -0
@@ -258,6 +258,46 @@ SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv,return do_sys_settimeofday64 (tv ? &new_ts :NULL , tz ? &new_tz :NULL ); } +#ifdef CONFIG_COMPAT +COMPAT_SYSCALL_DEFINE2(gettimeofday, struct compat_timeval __user *, tv, + struct timezone __user *, tz) +{ +if (tv) { +struct timeval ktv; +do_gettimeofday (&ktv); +if (compat_put_timeval (&ktv, tv)) +return -EFAULT ; + } +if (tz) { +if (copy_to_user (tz, &sys_tz,sizeof (sys_tz))) +return -EFAULT ; + } + +return 0 ; +} + +COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv, + struct timezone __user *, tz) +{ +struct timespec64 new_ts; +struct timeval user_tv; +struct timezone new_tz; + +if (tv) { +if (compat_get_timeval (&user_tv, tv)) +return -EFAULT ; + new_ts.tv_sec = user_tv.tv_sec; + new_ts.tv_nsec = user_tv.tv_usec *NSEC_PER_USEC ; + } +if (tz) { +if (copy_from_user (&new_tz, tz,sizeof (*tz))) +return -EFAULT ; + } + +return do_sys_settimeofday64 (tv ? &new_ts :NULL , tz ? &new_tz :NULL ); +} +#endif + SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p) {struct timex txc;/* Local copy of parameter */
Signature · 1 line
2.11.0
tip-bot for Al Viro
merge bot[tip:timers/core] time: Move compat_gettimeofday()/settimeofday() to native
time: Move compat_gettimeofday()/settimeofday() to native
Commit-ID: 2b2d02856b3176701c91d723356f766d6ee27853 Gitweb: http://git.kernel.org/tip/2b2d02856b3176701c91d723356f766d6ee27853 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:41 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:46 +0200
time: Move compat_gettimeofday()/settimeofday() to native
--- kernel/compat.c | 38 -------------------------------------- kernel/time/time.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 38 deletions(-)
kernel/compat.c +0 -38
@@ -92,44 +92,6 @@ int compat_put_timex(struct compat_timex __user *utp, const struct timex *txc)return 0 ; } -COMPAT_SYSCALL_DEFINE2(gettimeofday, struct compat_timeval __user *, tv, - struct timezone __user *, tz) -{ -if (tv) { -struct timeval ktv; -do_gettimeofday (&ktv); -if (compat_put_timeval (&ktv, tv)) -return -EFAULT ; - } -if (tz) { -if (copy_to_user (tz, &sys_tz,sizeof (sys_tz))) -return -EFAULT ; - } - -return 0 ; -} - -COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv, - struct timezone __user *, tz) -{ -struct timespec64 new_ts; -struct timeval user_tv; -struct timezone new_tz; - -if (tv) { -if (compat_get_timeval (&user_tv, tv)) -return -EFAULT ; - new_ts.tv_sec = user_tv.tv_sec; - new_ts.tv_nsec = user_tv.tv_usec *NSEC_PER_USEC ; - } -if (tz) { -if (copy_from_user (&new_tz, tz,sizeof (*tz))) -return -EFAULT ; - } - -return do_sys_settimeofday64 (tv ? &new_ts :NULL , tz ? &new_tz :NULL ); -} -static int __compat_get_timeval (struct timeval *tv,const struct compat_timeval __user *ctv) { return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) ||
kernel/time/time.c +41 -0
47 lines not on this page · raw message
Re: [PATCH 01/16] move copyout of timespec into do_cpu_nanosleep()
In reply to Al ViroQuoted 4 lines · Al Viro
kernel/time/posix-cpu-timers.c +1
-0@@ -1242,12 +1243,14 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, error = -ERESTART_RESTARTBLOCK ; +/*
kernel/time/posix-cpu-timers.c static int do_cpu_nanosleep(const clockid_t which_clock, int flags, · line 1255
Quoted 10 lines
kernel/time/posix-cpu-timers.c +10
-0+* Report back to the user the time still remaining. +*/ + rmtp = restart->nanosleep.rmtp; +if (rmtp) { +struct timespec ts; + ts =timespec64_to_timespec (it.it_value); +if (copy_to_user (rmtp, &ts,sizeof (*rmtp))) +return -EFAULT ; + } + restart->nanosleep.expires =timespec64_to_ns (rqtp);
Hmm, this looks wrong. But that was wrong before this patch already.
The restart code needs the absolute expiry time of the timer, but in case of flags != ABSTIME rqtp contains the relative expiry time.
So that want's to be fixed first. Need to figure out what's the least ugly way to do that. I'll have a look tomorrow.
Thanks,
tglx
Re: [PATCH 01/16] move copyout of timespec into do_cpu_nanosleep()
Quoted 18 lines · Thomas Gleixner
Quoted 4 lines · Al Viro
kernel/time/posix-cpu-timers.c +1
-0@@ -1242,12 +1243,14 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, error = -ERESTART_RESTARTBLOCK ; +/* kernel/time/posix-cpu-timers.c static int do_cpu_nanosleep(const clockid_t which_clock, int flags, · line 1255
Quoted 10 lines
kernel/time/posix-cpu-timers.c +10
-0+* Report back to the user the time still remaining. +*/ + rmtp = restart->nanosleep.rmtp; +if (rmtp) { +struct timespec ts; + ts =timespec64_to_timespec (it.it_value); +if (copy_to_user (rmtp, &ts,sizeof (*rmtp))) +return -EFAULT ; + } + restart->nanosleep.expires =timespec64_to_ns (rqtp);Hmm, this looks wrong. But that was wrong before this patch already.
Quoted 5 lines
The restart code needs the absolute expiry time of the timer, but in case of flags != ABSTIME rqtp contains the relative expiry time.
So that want's to be fixed first. Need to figure out what's the least ugly way to do that. I'll have a look tomorrow.
Misread the code. rqtp is updated with the absolute expiry time when a signal hits. Though with your changes we can simplify that further and avoid the whole back and forth timespec conversion.
Thanks,
tglx
tip-bot for Al Viro
merge bot[tip:timers/core] posix-cpu-timers: Move copyout of timespec into do_cpu_nanosleep()
In reply to Al Viroposix-cpu-timers: Move copyout of timespec into do_cpu_nanosleep()
Commit-ID: 86a9c446c13ecd8793ea8599761322aed125d542 Gitweb: http://git.kernel.org/tip/86a9c446c13ecd8793ea8599761322aed125d542 Author: Al Viro <[email protected]> AuthorDate: Wed, 7 Jun 2017 09:42:26 +0100 Committer: Thomas Gleixner <[email protected]> CommitDate: Wed, 14 Jun 2017 00:00:40 +0200
posix-cpu-timers: Move copyout of timespec into do_cpu_nanosleep()
The posix-cpu-timer nanosleep() implementation can be simplified by moving the copy out of the remaining time to do_cpu_nanosleep() which is shared between the real nanosleep function and the restart function.
The pointer to the timespec64 which is updated has to be stored in the restart block anyway. Instead of storing it only in the restart case, store it before calling do_cpu_nanosleep() and copy the remaining time in the signal exit path.
[ tglx: Added changelog ]
--- kernel/time/posix-cpu-timers.c | 63 +++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 35 deletions(-)
kernel/time/posix-cpu-timers.c +28 -35
@@ -1226,9 +1226,10 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx, }static int do_cpu_nanosleep (const clockid_t which_clock,int flags, -struct timespec64 *rqtp,struct itimerspec64 *it) +struct timespec64 *rqtp) {struct k_itimer timer; +struct itimerspec64 it;int error;/*
@@ -1242,12 +1243,14 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, timer.it_process = current;if (!error) {static struct itimerspec64 zero_it; +struct restart_block *restart = ¤t->restart_block; +struct timespec __user *rmtp; -memset (it,0 ,sizeof *it); - it->it_value = *rqtp; +memset (&it,0 ,sizeof it); + it.it_value = *rqtp;spin_lock_irq (&timer.it_lock); - error =posix_cpu_timer_set (&timer, flags, it,NULL ); + error =posix_cpu_timer_set (&timer, flags, &it,NULL );if (error) {spin_unlock_irq (&timer.it_lock);return error;
@@ -1277,7 +1280,7 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,* We were interrupted by a signal. */ *rqtp =ns_to_timespec64 (timer.it.cpu.expires); - error =posix_cpu_timer_set (&timer,0 , &zero_it, it); + error =posix_cpu_timer_set (&timer,0 , &zero_it, &it);if (!error) {/* * Timer is now unarmed, deletion can not fail.
@@ -1297,7 +1300,7 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,spin_unlock_irq (&timer.it_lock); } -if ((it->it_value.tv_sec | it->it_value.tv_nsec) ==0 ) { +if ((it.it_value.tv_sec | it.it_value.tv_nsec) ==0 ) {/* * It actually did fire already. */
@@ -1305,6 +1308,18 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, } error = -ERESTART_RESTARTBLOCK ; +/* +* Report back to the user the time still remaining. +*/ + rmtp = restart->nanosleep.rmtp; +if (rmtp) { +struct timespec ts; + + ts =timespec64_to_timespec (it.it_value); +if (copy_to_user (rmtp, &ts,sizeof (*rmtp))) +return -EFAULT ; + } + restart->nanosleep.expires =timespec64_to_ns (rqtp); }return error;
@@ -1316,10 +1331,13 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags, struct timespec64 *rqtp, struct timespec __user *rmtp) { struct restart_block *restart_block = ¤t->restart_block; -struct itimerspec64 it; -struct timespec ts;int error; +if (flags &TIMER_ABSTIME ) + rmtp =NULL ; + + restart_block->nanosleep.rmtp = rmtp; +/* * Diagnose required errors first. */
@@ -1328,23 +1346,15 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags, CPUCLOCK_PID(which_clock) == task_pid_vnr(current))) return -EINVAL; - error =do_cpu_nanosleep (which_clock, flags, rqtp, &it); + error =do_cpu_nanosleep (which_clock, flags, rqtp);if (error == -ERESTART_RESTARTBLOCK ) {if (flags &TIMER_ABSTIME )return -ERESTARTNOHAND ; -/* -* Report back to the user the time still remaining. -*/ - ts =timespec64_to_timespec (it.it_value); -if (rmtp &©_to_user (rmtp, &ts,sizeof (*rmtp))) -return -EFAULT ; restart_block->fn = posix_cpu_nsleep_restart; restart_block->nanosleep.clockid = which_clock; - restart_block->nanosleep.rmtp = rmtp; - restart_block->nanosleep.expires =timespec64_to_ns (rqtp); }return error; }
@@ -1352,28 +1362,11 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags,static long posix_cpu_nsleep_restart (struct restart_block *restart_block) {clockid_t which_clock = restart_block->nanosleep.clockid; -struct itimerspec64 it;struct timespec64 t; -struct timespec tmp; -int error; t =ns_to_timespec64 (restart_block->nanosleep.expires); - error =do_cpu_nanosleep (which_clock,TIMER_ABSTIME , &t, &it); - -if (error == -ERESTART_RESTARTBLOCK ) { -struct timespec __user *rmtp = restart_block->nanosleep.rmtp; -/* -* Report back to the user the time still remaining. -*/ - tmp =timespec64_to_timespec (it.it_value); -if (rmtp &©_to_user (rmtp, &tmp,sizeof (*rmtp))) -return -EFAULT ; - - restart_block->nanosleep.expires =timespec64_to_ns (&t); - } -return error; - +return do_cpu_nanosleep (which_clock,TIMER_ABSTIME , &t); }#define PROCESS_CLOCK MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED)