From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751490AbdFGKH3 (ORCPT ); Wed, 7 Jun 2017 06:07:29 -0400 Received: from merlin.infradead.org ([205.233.59.134]:46076 "EHLO merlin.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751008AbdFGKH1 (ORCPT ); Wed, 7 Jun 2017 06:07:27 -0400 Date: Wed, 7 Jun 2017 12:07:19 +0200 From: Peter Zijlstra To: Al Viro Cc: linux-kernel@vger.kernel.org, Thomas Gleixner Subject: Re: [PATCH 06/16] nanosleep/clock_nanosleep: teach to do compat copyouts Message-ID: <20170607100719.tz5sskknvzi2kdyg@hirez.programming.kicks-ass.net> References: <20170607084106.GV6365@ZenIV.linux.org.uk> <20170607084241.28657-1-viro@ZenIV.linux.org.uk> <20170607084241.28657-6-viro@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20170607084241.28657-6-viro@ZenIV.linux.org.uk> User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Jun 07, 2017 at 09:42:31AM +0100, Al Viro wrote: > From: Al Viro > > 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(-) diff --git a/include/linux/restart_block.h b/include/linux/restart_block.h index 4509944bd953..0834e4a8ce69 100644 --- a/include/linux/restart_block.h +++ b/include/linux/restart_block.h @@ -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 diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 80154e795535..734920be9d4b 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -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; diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 5dd4b3a34495..e1e06a8b6c43 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -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 mod return 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); } diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index f6c5f77b944d..929499e6b4ac 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -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); diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c index c0c18701a4da..4b54dcf8d517 100644 --- a/kernel/time/posix-stubs.c +++ b/kernel/time/posix-stubs.c @@ -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, diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 014e6ff8982e..3c85d6762690 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -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);