alarmtimer: Fix bug where relative alarm timers were treated as absolute
Sharvil noticed with the posix timer_settime interface, using the CLOCK_REALTIME_ALARM or CLOCK_BOOTTIME_ALARM clockid, if the users tried to specify a relative time timer, it would incorrectly be treated as absolute regardless of the state of the flags argument. This patch corrects this, properly checking the absolute/relative flag, as well as adds further error checking that no invalid flag bits are set. Reported-by: Sharvil Nanavati <sharvil@google.com> Signed-off-by: John Stultz <john.stultz@linaro.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@kernel.org> Cc: Prarit Bhargava <prarit@redhat.com> Cc: Sharvil Nanavati <sharvil@google.com> Cc: stable <stable@vger.kernel.org> #3.0+ Link: http://lkml.kernel.org/r/1404767171-6902-1-git-send-email-john.stultz@linaro.org Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
committed by
Thomas Gleixner
parent
e1a08b855f
commit
16927776ae
@@ -585,9 +585,14 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
|
|||||||
struct itimerspec *new_setting,
|
struct itimerspec *new_setting,
|
||||||
struct itimerspec *old_setting)
|
struct itimerspec *old_setting)
|
||||||
{
|
{
|
||||||
|
ktime_t exp;
|
||||||
|
|
||||||
if (!rtcdev)
|
if (!rtcdev)
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
if (flags & ~TIMER_ABSTIME)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (old_setting)
|
if (old_setting)
|
||||||
alarm_timer_get(timr, old_setting);
|
alarm_timer_get(timr, old_setting);
|
||||||
|
|
||||||
@@ -597,8 +602,16 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
|
|||||||
|
|
||||||
/* start the timer */
|
/* start the timer */
|
||||||
timr->it.alarm.interval = timespec_to_ktime(new_setting->it_interval);
|
timr->it.alarm.interval = timespec_to_ktime(new_setting->it_interval);
|
||||||
alarm_start(&timr->it.alarm.alarmtimer,
|
exp = timespec_to_ktime(new_setting->it_value);
|
||||||
timespec_to_ktime(new_setting->it_value));
|
/* Convert (if necessary) to absolute time */
|
||||||
|
if (flags != TIMER_ABSTIME) {
|
||||||
|
ktime_t now;
|
||||||
|
|
||||||
|
now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
|
||||||
|
exp = ktime_add(now, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
alarm_start(&timr->it.alarm.alarmtimer, exp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -730,6 +743,9 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags,
|
|||||||
if (!alarmtimer_get_rtcdev())
|
if (!alarmtimer_get_rtcdev())
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
if (flags & ~TIMER_ABSTIME)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (!capable(CAP_WAKE_ALARM))
|
if (!capable(CAP_WAKE_ALARM))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user