Skip to content

Commit

Permalink
time: Change k_clock timer_set() and timer_get() to use timespec64
Browse files Browse the repository at this point in the history
struct timespec is not y2038 safe on 32 bit machines.  Replace uses of
struct timespec with struct timespec64 in the kernel.

struct itimerspec internally uses struct timespec.  Use struct itimerspec64
which uses struct timespec64.

The syscall interfaces themselves will be changed in a separate series.

Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: y2038@lists.linaro.org
Cc: john.stultz@linaro.org
Cc: arnd@arndb.de
Link: http://lkml.kernel.org/r/1490555058-4603-7-git-send-email-deepa.kernel@gmail.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
deepa-hub authored and KAGA-KOKO committed Apr 14, 2017
1 parent 0fe6afe commit 5f252b3
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 65 deletions.
20 changes: 10 additions & 10 deletions drivers/char/mmtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ static int sgi_timer_del(struct k_itimer *timr)
}

/* Assumption: it_lock is already held with irq's disabled */
static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
static void sgi_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
{

if (timr->it.mmtimer.clock == TIMER_OFF) {
Expand All @@ -668,14 +668,14 @@ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
return;
}

cur_setting->it_interval = ns_to_timespec(timr->it.mmtimer.incr * sgi_clock_period);
cur_setting->it_value = ns_to_timespec((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period);
cur_setting->it_interval = ns_to_timespec64(timr->it.mmtimer.incr * sgi_clock_period);
cur_setting->it_value = ns_to_timespec64((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period);
}


static int sgi_timer_set(struct k_itimer *timr, int flags,
struct itimerspec * new_setting,
struct itimerspec * old_setting)
struct itimerspec64 *new_setting,
struct itimerspec64 *old_setting)
{
unsigned long when, period, irqflags;
int err = 0;
Expand All @@ -687,8 +687,8 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
sgi_timer_get(timr, old_setting);

sgi_timer_del(timr);
when = timespec_to_ns(&new_setting->it_value);
period = timespec_to_ns(&new_setting->it_interval);
when = timespec64_to_ns(&new_setting->it_value);
period = timespec64_to_ns(&new_setting->it_interval);

if (when == 0)
/* Clear timer */
Expand All @@ -699,11 +699,11 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
return -ENOMEM;

if (flags & TIMER_ABSTIME) {
struct timespec n;
struct timespec64 n;
unsigned long now;

getnstimeofday(&n);
now = timespec_to_ns(&n);
getnstimeofday64(&n);
now = timespec64_to_ns(&n);
if (when > now)
when -= now;
else
Expand Down
12 changes: 6 additions & 6 deletions include/linux/posix-timers.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ struct k_clock {
int (*nsleep) (const clockid_t which_clock, int flags,
struct timespec *, struct timespec __user *);
long (*nsleep_restart) (struct restart_block *restart_block);
int (*timer_set) (struct k_itimer * timr, int flags,
struct itimerspec * new_setting,
struct itimerspec * old_setting);
int (*timer_del) (struct k_itimer * timr);
int (*timer_set) (struct k_itimer *timr, int flags,
struct itimerspec64 *new_setting,
struct itimerspec64 *old_setting);
int (*timer_del) (struct k_itimer *timr);
#define TIMER_RETRY 1
void (*timer_get) (struct k_itimer * timr,
struct itimerspec * cur_setting);
void (*timer_get) (struct k_itimer *timr,
struct itimerspec64 *cur_setting);
};

extern struct k_clock clock_posix_cpu;
Expand Down
14 changes: 7 additions & 7 deletions kernel/time/alarmtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,19 +598,19 @@ static int alarm_timer_create(struct k_itimer *new_timer)
* Copies out the current itimerspec data
*/
static void alarm_timer_get(struct k_itimer *timr,
struct itimerspec *cur_setting)
struct itimerspec64 *cur_setting)
{
ktime_t relative_expiry_time =
alarm_expires_remaining(&(timr->it.alarm.alarmtimer));

if (ktime_to_ns(relative_expiry_time) > 0) {
cur_setting->it_value = ktime_to_timespec(relative_expiry_time);
cur_setting->it_value = ktime_to_timespec64(relative_expiry_time);
} else {
cur_setting->it_value.tv_sec = 0;
cur_setting->it_value.tv_nsec = 0;
}

cur_setting->it_interval = ktime_to_timespec(timr->it.alarm.interval);
cur_setting->it_interval = ktime_to_timespec64(timr->it.alarm.interval);
}

/**
Expand Down Expand Up @@ -640,8 +640,8 @@ static int alarm_timer_del(struct k_itimer *timr)
* Sets the timer to new_setting, and starts the timer.
*/
static int alarm_timer_set(struct k_itimer *timr, int flags,
struct itimerspec *new_setting,
struct itimerspec *old_setting)
struct itimerspec64 *new_setting,
struct itimerspec64 *old_setting)
{
ktime_t exp;

Expand All @@ -659,8 +659,8 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
return TIMER_RETRY;

/* start the timer */
timr->it.alarm.interval = timespec_to_ktime(new_setting->it_interval);
exp = timespec_to_ktime(new_setting->it_value);
timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval);
exp = timespec64_to_ktime(new_setting->it_value);
/* Convert (if necessary) to absolute time */
if (flags != TIMER_ABSTIME) {
ktime_t now;
Expand Down
21 changes: 7 additions & 14 deletions kernel/time/posix-clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,40 +399,33 @@ static int pc_timer_delete(struct k_itimer *kit)
return err;
}

static void pc_timer_gettime(struct k_itimer *kit, struct itimerspec *ts)
static void pc_timer_gettime(struct k_itimer *kit, struct itimerspec64 *ts)
{
clockid_t id = kit->it_clock;
struct posix_clock_desc cd;
struct itimerspec64 ts64;

if (get_clock_desc(id, &cd))
return;

if (cd.clk->ops.timer_gettime) {
cd.clk->ops.timer_gettime(cd.clk, kit, &ts64);
*ts = itimerspec64_to_itimerspec(&ts64);
}
if (cd.clk->ops.timer_gettime)
cd.clk->ops.timer_gettime(cd.clk, kit, ts);

put_clock_desc(&cd);
}

static int pc_timer_settime(struct k_itimer *kit, int flags,
struct itimerspec *ts, struct itimerspec *old)
struct itimerspec64 *ts, struct itimerspec64 *old)
{
struct itimerspec64 ts64 = itimerspec_to_itimerspec64(ts);
clockid_t id = kit->it_clock;
struct posix_clock_desc cd;
struct itimerspec64 old64;
int err;

err = get_clock_desc(id, &cd);
if (err)
return err;

if (cd.clk->ops.timer_settime) {
err = cd.clk->ops.timer_settime(cd.clk, kit, flags, &ts64, &old64);
if (old)
*old = itimerspec64_to_itimerspec(&old64);
}
if (cd.clk->ops.timer_settime)
err = cd.clk->ops.timer_settime(cd.clk, kit, flags, ts, old);
else
err = -EOPNOTSUPP;

Expand Down
28 changes: 16 additions & 12 deletions kernel/time/posix-cpu-timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ static int cpu_timer_sample_group(const clockid_t which_clock,
* and try again. (This happens when the timer is in the middle of firing.)
*/
static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
struct itimerspec *new, struct itimerspec *old)
struct itimerspec64 *new, struct itimerspec64 *old)
{
unsigned long flags;
struct sighand_struct *sighand;
Expand All @@ -572,7 +572,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,

WARN_ON_ONCE(p == NULL);

new_expires = timespec_to_ns(&new->it_value);
new_expires = timespec64_to_ns(&new->it_value);

/*
* Protect against sighand release/switch in exit/exec and p->cpu_timers
Expand Down Expand Up @@ -633,7 +633,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
bump_cpu_timer(timer, val);
if (val < timer->it.cpu.expires) {
old_expires = timer->it.cpu.expires - val;
old->it_value = ns_to_timespec(old_expires);
old->it_value = ns_to_timespec64(old_expires);
} else {
old->it_value.tv_nsec = 1;
old->it_value.tv_sec = 0;
Expand Down Expand Up @@ -671,7 +671,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
* Install the new reload setting, and
* set up the signal and overrun bookkeeping.
*/
timer->it.cpu.incr = timespec_to_ns(&new->it_interval);
timer->it.cpu.incr = timespec64_to_ns(&new->it_interval);

/*
* This acts as a modification timestamp for the timer,
Expand All @@ -695,12 +695,12 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
ret = 0;
out:
if (old)
old->it_interval = ns_to_timespec(old_incr);
old->it_interval = ns_to_timespec64(old_incr);

return ret;
}

static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec64 *itp)
{
u64 now;
struct task_struct *p = timer->it.cpu.task;
Expand All @@ -710,7 +710,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
/*
* Easy part: convert the reload time.
*/
itp->it_interval = ns_to_timespec(timer->it.cpu.incr);
itp->it_interval = ns_to_timespec64(timer->it.cpu.incr);

if (timer->it.cpu.expires == 0) { /* Timer not armed at all. */
itp->it_value.tv_sec = itp->it_value.tv_nsec = 0;
Expand Down Expand Up @@ -739,7 +739,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
* Call the timer disarmed, nothing else to do.
*/
timer->it.cpu.expires = 0;
itp->it_value = ns_to_timespec(timer->it.cpu.expires);
itp->it_value = ns_to_timespec64(timer->it.cpu.expires);
return;
} else {
cpu_timer_sample_group(timer->it_clock, p, &now);
Expand All @@ -748,7 +748,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
}

if (now < timer->it.cpu.expires) {
itp->it_value = ns_to_timespec(timer->it.cpu.expires - now);
itp->it_value = ns_to_timespec64(timer->it.cpu.expires - now);
} else {
/*
* The timer should have expired already, but the firing
Expand Down Expand Up @@ -1221,6 +1221,7 @@ 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 timespec *rqtp, struct itimerspec *it)
{
struct itimerspec64 it64;
struct k_itimer timer;
int error;

Expand All @@ -1234,13 +1235,14 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
error = posix_cpu_timer_create(&timer);
timer.it_process = current;
if (!error) {
static struct itimerspec zero_it;
static struct itimerspec64 zero_it;

memset(it, 0, sizeof *it);
it->it_value = *rqtp;

spin_lock_irq(&timer.it_lock);
error = posix_cpu_timer_set(&timer, flags, it, NULL);
it64 = itimerspec_to_itimerspec64(it);
error = posix_cpu_timer_set(&timer, flags, &it64, NULL);
if (error) {
spin_unlock_irq(&timer.it_lock);
return error;
Expand Down Expand Up @@ -1270,7 +1272,9 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
* We were interrupted by a signal.
*/
*rqtp = ns_to_timespec(timer.it.cpu.expires);
error = posix_cpu_timer_set(&timer, 0, &zero_it, it);
it64 = itimerspec_to_itimerspec64(it);
error = posix_cpu_timer_set(&timer, 0, &zero_it, &it64);
*it = itimerspec64_to_itimerspec(&it64);
if (!error) {
/*
* Timer is now unarmed, deletion can not fail.
Expand Down
Loading

0 comments on commit 5f252b3

Please sign in to comment.