Skip to content

Commit

Permalink
Squashed Commits
Browse files Browse the repository at this point in the history
Update deprecated Alarm driver users to upstream Alarmtimer driver.
----------------------------------

timerfd: Protect the might cancel mechanism proper

commit 1e38da300e1e395a15048b0af1e5305bd91402f6 upstream.

The handling of the might_cancel queueing is not properly protected, so
parallel operations on the file descriptor can race with each other and
lead to list corruptions or use after free.

Protect the context for these operations with a seperate lock.

The wait queue lock cannot be reused for this because that would create
a lock inversion scenario vs. the cancel lock. Replacing might_cancel
with an atomic (atomic_t or atomic bit) does not help either because it
still can race vs. the actual list operation.

Bug: 36266767

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: "linux-fsdevel@vger.kernel.org"
Cc: syzkaller <syzkaller@googlegroups.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1701311521430.3457@nanos
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Siqi Lin <siqilin@google.com>
Change-Id: I122753e0920e51757d3012cd1a133e823719be51
----------------------------------

zcache, zram: use lzo instead of lz4 compression.
----------------------------------

Cleanup sound_control_3_gpl driver.
----------------------------------

rtc: alarm: Change wake-up source

Currently, RTC_ALARM is used to wake-up target from
suspend state and is also used for power-off alarm
feature. This patch uses qtimer to wake-up from
suspend state.

Change-Id: Ia42cfecd573309be2f03c18b4f1c321be8202d7d
Signed-off-by: Mohit Aggarwal <maggarwa@codeaurora.org>

Signed-off-by: Gobinda Joy <gobinda.joy@gmail.com>

# Conflicts:
#	drivers/battery/sec_battery.c
#	drivers/sensorhub/stm32f/ssp.h
#	drivers/sensorhub/stm32f/ssp_dev.c
#	drivers/staging/android/alarm-dev.c
#	fs/timerfd.c
#	include/linux/battery/sec_battery.h
  • Loading branch information
gj86 committed Sep 3, 2017
1 parent 74325c9 commit 0e21bc2
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 60 deletions.
1 change: 1 addition & 0 deletions arch/arm/mach-msm/include/mach/cpuidle.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct msm_cpuidle_state {

#ifdef CONFIG_PM
s32 msm_cpuidle_get_deep_idle_latency(void);
void lpm_suspend_wake_time(uint64_t wakeup_time);
#else
static inline s32 msm_cpuidle_get_deep_idle_latency(void) { return 0; }
#endif
Expand Down
27 changes: 23 additions & 4 deletions arch/arm/mach-msm/lpm_levels.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ static int msm_pm_sleep_time_override;
module_param_named(sleep_time_override,
msm_pm_sleep_time_override, int, S_IRUGO | S_IWUSR | S_IWGRP);

static uint64_t suspend_wake_time;

static int msm_pm_sleep_sec_debug;
module_param_named(secdebug,
msm_pm_sleep_sec_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
Expand Down Expand Up @@ -395,8 +397,11 @@ static void lpm_system_prepare(struct lpm_system_state *system_state,
}


if (!suspend_wake_time)
suspend_wake_time = msm_pm_sleep_time_override;

if (!from_idle)
us = USEC_PER_SEC * msm_pm_sleep_time_override;
us = USEC_PER_SEC * suspend_wake_time;

do_div(us, USEC_PER_SEC/SCLK_HZ);
sclk = (uint32_t)us;
Expand Down Expand Up @@ -474,6 +479,21 @@ s32 msm_cpuidle_get_deep_idle_latency(void)
return level->pwr.latency_us;
}

void lpm_suspend_wake_time(uint64_t wakeup_time)
{
if (wakeup_time <= 0) {
suspend_wake_time = msm_pm_sleep_time_override;
return;
}

if (msm_pm_sleep_time_override &&
(msm_pm_sleep_time_override < wakeup_time))
suspend_wake_time = msm_pm_sleep_time_override;
else
suspend_wake_time = wakeup_time;
}
EXPORT_SYMBOL(lpm_suspend_wake_time);

static int lpm_cpu_callback(struct notifier_block *cpu_nb,
unsigned long action, void *hcpu)
{
Expand Down Expand Up @@ -525,8 +545,7 @@ static noinline int lpm_cpu_power_select(struct cpuidle_device *dev, int *index)
if (!sys_state.cpu_level)
return -EINVAL;

if (!dev->cpu)
next_event_us = (uint32_t)(ktime_to_us(get_next_event_time()));
next_event_us = (uint32_t)(ktime_to_us(get_next_event_time(dev->cpu)));

for (i = 0; i < sys_state.num_cpu_levels; i++) {
struct lpm_cpu_level *level = &sys_state.cpu_level[i];
Expand Down Expand Up @@ -587,7 +606,7 @@ static noinline int lpm_cpu_power_select(struct cpuidle_device *dev, int *index)
}
}

if (modified_time_us && !dev->cpu)
if (modified_time_us)
msm_pm_set_timer(modified_time_us);

return best_level;
Expand Down
35 changes: 29 additions & 6 deletions drivers/staging/android/alarm-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ do { \

#define ANDROID_ALARM_WAKEUP_MASK ( \
ANDROID_ALARM_RTC_WAKEUP_MASK | \
ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK | \
ANDROID_ALARM_RTC_POWEROFF_WAKEUP_MASK)

static int alarm_opened;
static DEFINE_SPINLOCK(alarm_slock);
static DEFINE_MUTEX(alarm_mutex);
static struct wakeup_source alarm_wake_lock;
static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue);
static uint32_t alarm_pending;
Expand All @@ -65,7 +67,8 @@ static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT];
static int is_wakeup(enum android_alarm_type type)
{
return (type == ANDROID_ALARM_RTC_WAKEUP ||
type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP);
type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP ||
type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP);
}


Expand Down Expand Up @@ -93,11 +96,12 @@ static void devalarm_cancel(struct devalarm *alrm)
hrtimer_cancel(&alrm->u.hrt);
}

static void alarm_clear(enum android_alarm_type alarm_type)
static void alarm_clear(enum android_alarm_type alarm_type, struct timespec *ts)
{
uint32_t alarm_type_mask = 1U << alarm_type;
unsigned long flags;

mutex_lock(&alarm_mutex);
spin_lock_irqsave(&alarm_slock, flags);
alarm_dbg(IO, "alarm %d clear\n", alarm_type);
devalarm_try_to_cancel(&alarms[alarm_type]);
Expand All @@ -109,6 +113,11 @@ static void alarm_clear(enum android_alarm_type alarm_type)
alarm_enabled &= ~alarm_type_mask;
spin_unlock_irqrestore(&alarm_slock, flags);

#if 0
if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP)
set_power_on_alarm(ts->tv_sec, 0);
#endif
mutex_unlock(&alarm_mutex);
}

static void alarm_set(enum android_alarm_type alarm_type,
Expand All @@ -117,12 +126,19 @@ static void alarm_set(enum android_alarm_type alarm_type,
uint32_t alarm_type_mask = 1U << alarm_type;
unsigned long flags;

mutex_lock(&alarm_mutex);
spin_lock_irqsave(&alarm_slock, flags);
alarm_dbg(IO, "alarm %d set %ld.%09ld\n",
alarm_type, ts->tv_sec, ts->tv_nsec);
alarm_enabled |= alarm_type_mask;
devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts));
spin_unlock_irqrestore(&alarm_slock, flags);

#if 0
if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP)
set_power_on_alarm(ts->tv_sec, 1);
#endif
mutex_unlock(&alarm_mutex);
}

static int alarm_wait(void)
Expand Down Expand Up @@ -182,6 +198,7 @@ static int alarm_get_time(enum android_alarm_type alarm_type,
switch (alarm_type) {
case ANDROID_ALARM_RTC_WAKEUP:
case ANDROID_ALARM_RTC:
case ANDROID_ALARM_RTC_POWEROFF_WAKEUP:
getnstimeofday(ts);
break;
case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
Expand Down Expand Up @@ -225,7 +242,7 @@ static long alarm_do_ioctl(struct file *file, unsigned int cmd,

switch (ANDROID_ALARM_BASE_CMD(cmd)) {
case ANDROID_ALARM_CLEAR(0):
alarm_clear(alarm_type);
alarm_clear(alarm_type, ts);
break;
case ANDROID_ALARM_SET(0):
alarm_set(alarm_type, ts);
Expand Down Expand Up @@ -259,6 +276,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case ANDROID_ALARM_SET_AND_WAIT(0):
case ANDROID_ALARM_SET(0):
case ANDROID_ALARM_SET_RTC:
case ANDROID_ALARM_CLEAR(0):
if (copy_from_user(&ts, (void __user *)arg, sizeof(ts)))
return -EFAULT;
break;
Expand Down Expand Up @@ -298,6 +316,8 @@ static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
}

rv = alarm_do_ioctl(file, cmd, &ts);
if (rv)
return rv;

switch (ANDROID_ALARM_BASE_CMD(cmd)) {
case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */
Expand All @@ -306,7 +326,7 @@ static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
break;
}

return rv;
return 0;
}
#endif

Expand Down Expand Up @@ -420,6 +440,8 @@ static int __init alarm_dev_init(void)
CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt,
CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
alarm_init(&alarms[ANDROID_ALARM_RTC_POWEROFF_WAKEUP].u.alrm,
ALARM_REALTIME, devalarm_alarmhandler);

for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
alarms[i].type = i;
Expand All @@ -428,6 +450,8 @@ static int __init alarm_dev_init(void)
}

wakeup_source_init(&alarm_wake_lock, "alarm");

power_on_alarm_init();
return 0;
}

Expand All @@ -439,4 +463,3 @@ static void __exit alarm_dev_exit(void)

module_init(alarm_dev_init);
module_exit(alarm_dev_exit);

3 changes: 3 additions & 0 deletions drivers/staging/android/android_alarm.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum android_alarm_type {
ANDROID_ALARM_RTC,
ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
ANDROID_ALARM_ELAPSED_REALTIME,
ANDROID_ALARM_RTC_POWEROFF_WAKEUP,
ANDROID_ALARM_SYSTEMTIME,

ANDROID_ALARM_TYPE_COUNT,
Expand All @@ -41,6 +42,8 @@ enum android_alarm_return_flags {
1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
ANDROID_ALARM_ELAPSED_REALTIME_MASK =
1U << ANDROID_ALARM_ELAPSED_REALTIME,
ANDROID_ALARM_RTC_POWEROFF_WAKEUP_MASK =
1U << ANDROID_ALARM_RTC_POWEROFF_WAKEUP,
ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
};
Expand Down
3 changes: 2 additions & 1 deletion include/linux/clockchips.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ extern void clockevents_notify(unsigned long reason, void *arg);

#else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */

#define clockevents_notify(reason, arg) do { } while (0)
static inline int clockevents_notify(unsigned long reason, void *arg) { return 0; }
static inline void tick_setup_hrtimer_broadcast(void) {};

#endif

Expand Down
6 changes: 3 additions & 3 deletions kernel/time/clocksource.c
Original file line number Diff line number Diff line change
Expand Up @@ -622,8 +622,8 @@ static inline void clocksource_select(void) { }
* clocksource_done_booting - Called near the end of core bootup
*
* Hack to avoid lots of clocksource churn at boot time.
* We use fs_initcall because we want this to start before
* device_initcall but after subsys_initcall.
* We use arch_initcall because we want this to start before
* device_initcall but after SMP init.
*/
static int __init clocksource_done_booting(void)
{
Expand All @@ -643,7 +643,7 @@ static int __init clocksource_done_booting(void)
mutex_unlock(&clocksource_mutex);
return 0;
}
fs_initcall(clocksource_done_booting);
arch_initcall(clocksource_done_booting);

/*
* Enqueue the clocksource sorted by rating
Expand Down
Loading

0 comments on commit 0e21bc2

Please sign in to comment.