From 5e3a6df2d09e0649949b6f0a0271acca2c1dd79e Mon Sep 17 00:00:00 2001 From: Umang Agrawal Date: Wed, 3 Jan 2018 19:28:30 +0530 Subject: [PATCH 01/20] power: qpnp-charger: Fix null pointer dereference error Fix to prevent null pointer dereference error in the led brightness set function by an initial check to determine whether the power_supply structure is defined or not. CRs-Fixed: 2166164 Change-Id: Ifcd6e55aa78c4c4d4dc539ac6ffe67263d198b47 Signed-off-by: Umang Agrawal --- drivers/power/qpnp-smbcharger.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/power/qpnp-smbcharger.c b/drivers/power/qpnp-smbcharger.c index 328877a87951..8120fb1514d2 100644 --- a/drivers/power/qpnp-smbcharger.c +++ b/drivers/power/qpnp-smbcharger.c @@ -4243,10 +4243,12 @@ static void smbchg_chg_led_brightness_set(struct led_classdev *cdev, reg = (value > LED_OFF) ? CHG_LED_ON << CHG_LED_SHIFT : CHG_LED_OFF << CHG_LED_SHIFT; - if (value > LED_OFF) - power_supply_set_hi_power_state(chip->bms_psy, 1); - else - power_supply_set_hi_power_state(chip->bms_psy, 0); + if (chip->bms_psy) { + if (value > LED_OFF) + power_supply_set_hi_power_state(chip->bms_psy, 1); + else + power_supply_set_hi_power_state(chip->bms_psy, 0); + } pr_smb(PR_STATUS, "set the charger led brightness to value=%d\n", @@ -4289,11 +4291,16 @@ static void smbchg_chg_led_blink_set(struct smbchg_chip *chip, u8 reg; int rc; + if (chip->bms_psy) { + if (blinking == 0) + power_supply_set_hi_power_state(chip->bms_psy, 0); + else + power_supply_set_hi_power_state(chip->bms_psy, 1); + } + if (blinking == 0) { reg = CHG_LED_OFF << CHG_LED_SHIFT; - power_supply_set_hi_power_state(chip->bms_psy, 0); } else { - power_supply_set_hi_power_state(chip->bms_psy, 1); if (blinking == 1) reg = LED_BLINKING_PATTERN2 << CHG_LED_SHIFT; else if (blinking == 2) From 88de5f11d85da45d2a0a9588ac19665ecacdb3b5 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 15 Jan 2018 18:43:33 +0800 Subject: [PATCH 02/20] ASoC: msm: qdsp6v2: update backend name Some backend names are not there. Delete them from current be_name. When the return value of adm_populate_channel_weight is 0, it should keep running, not return error. Change-Id: I447b81d6edfc89db6cb3742c1719e745c6071c12 Signed-off-by: Meng Wang --- sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c | 58 ++++++++++------------ sound/soc/msm/qdsp6v2/q6adm.c | 4 +- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index 3b280cebe1ff..dd43b5c4c989 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2318,37 +2318,31 @@ static const char *const be_name[] = { "INT_FM_RX", "INT_FM_TX", "AFE_PCM_RX", "AFE_PCM_TX", "AUXPCM_RX", "AUXPCM_TX", "VOICE_PLAYBACK_TX", "VOICE2_PLAYBACK_TX", "INCALL_RECORD_RX", "INCALL_RECORD_TX", "MI2S_RX", "MI2S_TX", -"SEC_I2S_RX", "SLIM_1_RX", "SLIM_1_TX", "SLIM_2_RX", -"SLIM_2_TX", "SLIM_3_RX", "SLIM_3_TX", "SLIM_4_RX", -"SLIM_4_TX", "SLIM_5_RX", "SLIM_5_TX", "SLIM_6_RX", -"SLIM_6_TX", "SLIM_7_RX", "SLIM_7_TX", "SLIM_8_RX", -"SLIM_8_TX", "EXTPROC_RX", "EXTPROC_TX", "EXPROC_EC_TX", -"QUAT_MI2S_RX", "QUAT_MI2S_TX", "SECOND_MI2S_RX", "SECOND_MI2S_TX", -"PRI_MI2S_RX", "PRI_MI2S_TX", "TERT_MI2S_RX", "TERT_MI2S_TX", -"AUDIO_I2S_RX", "SEC_AUXPCM_RX", "SEC_AUXPCM_TX", "SPDIF_RX", -"SECOND_MI2S_RX_SD1", "QUIN_MI2S_RX", "QUIN_MI2S_TX", "SENARY_MI2S_TX", -"PRI_TDM_RX_0", "PRI_TDM_TX_0", "PRI_TDM_RX_1", "PRI_TDM_TX_1", -"PRI_TDM_RX_2", "PRI_TDM_TX_2", "PRI_TDM_RX_3", "PRI_TDM_TX_3", -"PRI_TDM_RX_4", "PRI_TDM_TX_4", "PRI_TDM_RX_5", "PRI_TDM_TX_5", -"PRI_TDM_RX_6", "PRI_TDM_TX_6", "PRI_TDM_RX_7", "PRI_TDM_TX_7", -"SEC_TDM_RX_0", "SEC_TDM_TX_0", "SEC_TDM_RX_1", "SEC_TDM_TX_1", -"SEC_TDM_RX_2", "SEC_TDM_TX_2", "SEC_TDM_RX_3", "SEC_TDM_TX_3", -"SEC_TDM_RX_4", "SEC_TDM_TX_4", "SEC_TDM_RX_5", "SEC_TDM_TX_5", -"SEC_TDM_RX_6", "SEC_TDM_TX_6", "SEC_TDM_RX_7", "SEC_TDM_TX_7", -"TERT_TDM_RX_0", "TERT_TDM_TX_0", "TERT_TDM_RX_1", "TERT_TDM_TX_1", -"TERT_TDM_RX_2", "TERT_TDM_TX_2", "TERT_TDM_RX_3", "TERT_TDM_TX_3", -"TERT_TDM_RX_4", "TERT_TDM_TX_4", "TERT_TDM_RX_5", "TERT_TDM_TX_5", -"TERT_TDM_RX_6", "TERT_TDM_TX_6", "TERT_TDM_RX_7", "TERT_TDM_TX_7", -"QUAT_TDM_RX_0", "QUAT_TDM_TX_0", "QUAT_TDM_RX_1", "QUAT_TDM_TX_1", -"QUAT_TDM_RX_2", "QUAT_TDM_TX_2", "QUAT_TDM_RX_3", "QUAT_TDM_TX_3", -"QUAT_TDM_RX_4", "QUAT_TDM_TX_4", "QUAT_TDM_RX_5", "QUAT_TDM_TX_5", -"QUAT_TDM_RX_6", "QUAT_TDM_TX_6", "QUAT_TDM_RX_7", "QUAT_TDM_TX_7", -"INT_BT_A2DP_RX", "USB_RX", "USB_TX", "DISPLAY_PORT_RX", -"TERT_AUXPCM_RX", "TERT_AUXPCM_TX", "QUAT_AUXPCM_RX", "QUAT_AUXPCM_TX", -"INT0_MI2S_RX", "INT0_MI2S_TX", "INT1_MI2S_RX", "INT1_MI2S_TX", -"INT2_MI2S_RX", "INT2_MI2S_TX", "INT3_MI2S_RX", "INT3_MI2S_TX", -"INT4_MI2S_RX", "INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX", -"INT6_MI2S_RX", "INT6_MI2S_TX" +"SEC_I2S_RX", "SLIM_1_RX", "SLIM_1_TX", "SLIM_4_RX", +"SLIM_4_TX", "SLIM_3_RX", "SLIM_3_TX", "SLIM_5_TX", +"EXTPROC_RX", "EXTPROC_TX", "EXPROC_EC_TX", "QUAT_MI2S_RX", +"QUAT_MI2S_TX", "SECOND_MI2S_RX", "SECOND_MI2S_TX", "PRI_MI2S_RX", +"PRI_MI2S_TX", "TERT_MI2S_RX", "TERT_MI2S_TX", "AUDIO_I2S_RX", +"SEC_AUXPCM_RX", "SEC_AUXPCM_TX", "SLIM_6_RX", "SLIM_6_TX", +"SPDIF_RX", "SECOND_MI2S_RX_SD1", "SLIM_5_RX", "QUIN_MI2S_RX", +"QUIN_MI2S_TX", "SENARY_MI2S_TX", "PRI_TDM_RX_0", "PRI_TDM_TX_0", +"PRI_TDM_RX_1", "PRI_TDM_TX_1", "PRI_TDM_RX_2", "PRI_TDM_TX_2", +"PRI_TDM_RX_3", "PRI_TDM_TX_3", "PRI_TDM_RX_4", "PRI_TDM_TX_4", +"PRI_TDM_RX_5", "PRI_TDM_TX_5", "PRI_TDM_RX_6", "PRI_TDM_TX_6", +"PRI_TDM_RX_7", "PRI_TDM_TX_7", "SEC_TDM_RX_0", "SEC_TDM_TX_0", +"SEC_TDM_RX_1", "SEC_TDM_TX_1", "SEC_TDM_RX_2", "SEC_TDM_TX_2", +"SEC_TDM_RX_3", "SEC_TDM_TX_3", "SEC_TDM_RX_4", "SEC_TDM_TX_4", +"SEC_TDM_RX_5", "SEC_TDM_TX_5", "SEC_TDM_RX_6", "SEC_TDM_TX_6", +"SEC_TDM_RX_7", "SEC_TDM_TX_7", "TERT_TDM_RX_0", "TERT_TDM_TX_0", +"TERT_TDM_RX_1", "TERT_TDM_TX_1", "TERT_TDM_RX_2", "TERT_TDM_TX_2", +"TERT_TDM_RX_3", "TERT_TDM_TX_3", "TERT_TDM_RX_4", "TERT_TDM_TX_4", +"TERT_TDM_RX_5", "TERT_TDM_TX_5", "TERT_TDM_RX_6", "TERT_TDM_TX_6", +"TERT_TDM_RX_7", "TERT_TDM_TX_7", "QUAT_TDM_RX_0", "QUAT_TDM_TX_0", +"QUAT_TDM_RX_1", "QUAT_TDM_TX_1", "QUAT_TDM_RX_2", "QUAT_TDM_TX_2", +"QUAT_TDM_RX_3", "QUAT_TDM_TX_3", "QUAT_TDM_RX_4", "QUAT_TDM_TX_4", +"QUAT_TDM_RX_5", "QUAT_TDM_TX_5", "QUAT_TDM_RX_6", "QUAT_TDM_TX_6", +"QUAT_TDM_RX_7", "QUAT_TDM_TX_7", "INT_BT_A2DP_RX", "SLIM_2_TX", +"AFE_LOOPBACK_TX" }; static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index f1917e703d89..6c31314bf548 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -721,7 +721,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, index = index + ch_mixer->input_channels[channel_index]; ret = adm_populate_channel_weight(&adm_pspd_params[index], ch_mixer, channel_index); - if (!ret) { + if (ret) { pr_err("%s: fail to get channel weight with error %d\n", __func__, ret); goto fail_cmd; From 58f27a4427fe658b12687a3f1796289575b3b2f1 Mon Sep 17 00:00:00 2001 From: Chetan C R Date: Wed, 25 Jul 2018 18:27:04 +0530 Subject: [PATCH 03/20] defconfig: msm: enable MSM_SYSMON_COMM for 8909 This option adds support for MSM System Monitor library, which provides an API that may be used for notifying subsystems within the SoC about other subsystems' power-up/down state-changes. Change-Id: If410422b4274545daf89613e58bc797064c5f7d4 Signed-off-by: Chetan C R --- arch/arm/configs/msm8909-perf_defconfig | 1 + arch/arm/configs/msm8909_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig index 2557519188a3..11fcf4afca8e 100644 --- a/arch/arm/configs/msm8909-perf_defconfig +++ b/arch/arm/configs/msm8909-perf_defconfig @@ -484,6 +484,7 @@ CONFIG_MSM_QMI_INTERFACE=y CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y CONFIG_MSM_EVENT_TIMER=y CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_SYSMON_COMM=y CONFIG_MSM_PIL=y CONFIG_MSM_PIL_SSR_GENERIC=y CONFIG_MSM_PIL_MSS_QDSP6V5=y diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig index de501ebb77c0..39e0c2c3b850 100644 --- a/arch/arm/configs/msm8909_defconfig +++ b/arch/arm/configs/msm8909_defconfig @@ -495,6 +495,7 @@ CONFIG_MSM_QMI_INTERFACE=y CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y CONFIG_MSM_EVENT_TIMER=y CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_SYSMON_COMM=y CONFIG_MSM_PIL=y CONFIG_MSM_PIL_SSR_GENERIC=y CONFIG_MSM_PIL_MSS_QDSP6V5=y From 5bd511a9a92d09aa6eac6cd231abdbb31a99f497 Mon Sep 17 00:00:00 2001 From: Animesh Kishore Date: Wed, 28 Mar 2018 00:53:31 +0530 Subject: [PATCH 04/20] mdss: mdp: Fix fudge factor overflow check Fudge adjustment is always 64 bit operation irrespective of underlying architecture is 32/64 bit. Fix max value to compare overflow against. Add warning if adjustments can't go through without overflow. Change-Id: I9c15ea8c1754c9ddb997546dc476bb6d45198524 Signed-off-by: Animesh Kishore --- drivers/video/msm/mdss/mdss_mdp_ctl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c index 8271e27bbad7..01d06f278579 100644 --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c @@ -76,13 +76,15 @@ static inline u64 fudge_factor(u64 val, u32 numer, u32 denom) u64 result = val; if (val) { - u64 temp = -1UL; + u64 temp = U64_MAX; do_div(temp, val); if (temp > numer) { /* no overflow, so we can do the operation*/ result = (val * (u64)numer); do_div(result, denom); + } else { + pr_warn("Overflow, skip fudge factor\n"); } } return result; From 57aa6092e499be16fd9583fc87615e8126b276f5 Mon Sep 17 00:00:00 2001 From: Deepak Shankar Date: Thu, 16 Aug 2018 14:59:17 +0530 Subject: [PATCH 05/20] msm: ais: Fix out-of-bounds read in string class name jpeg driver is calling class_create with stack variable, which can be overwritten by other stack variables. Change-Id: Ief49d44e25c70716dcb474b2635e42e0e8e9ca15 Signed-off-by: Deepak Shankar --- drivers/media/platform/msm/ais/jpeg_10/msm_jpeg_dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/ais/jpeg_10/msm_jpeg_dev.c b/drivers/media/platform/msm/ais/jpeg_10/msm_jpeg_dev.c index a0a6ffd0e69a..a2232e6cc731 100644 --- a/drivers/media/platform/msm/ais/jpeg_10/msm_jpeg_dev.c +++ b/drivers/media/platform/msm/ais/jpeg_10/msm_jpeg_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -32,6 +32,8 @@ #define MSM_JPEG_NAME "jpeg" #define DEV_NAME_LEN 10 +static char devname[DEV_NAME_LEN]; + static int msm_jpeg_open(struct inode *inode, struct file *filp) { int rc = 0; @@ -185,7 +187,6 @@ static int msm_jpeg_init_dev(struct platform_device *pdev) struct msm_jpeg_device *msm_jpeg_device_p; const struct of_device_id *device_id; const struct msm_jpeg_priv_data *priv_data; - char devname[DEV_NAME_LEN]; msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC); if (!msm_jpeg_device_p) { From 31b5a03c73a2fec6822dccc135a14645d573e304 Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Fri, 27 Oct 2017 11:15:55 +0800 Subject: [PATCH 06/20] Revert "rtc: alarm: Add power-on alarm feature" This reverts commit 2e1a4aefef66db901f9a906b79e30187f10dbecb. Power off alarm is not set via alarmtimer now. Remove the changes of power off alarm's previous design. CRs-Fixed: 2132189 Change-Id: I0f60bec0d94c93c4f2a89ae86a1b0a0d04aa9e48 Signed-off-by: Mao Jinlong --- fs/timerfd.c | 32 +++++------ include/linux/alarmtimer.h | 4 -- include/uapi/linux/time.h | 1 - kernel/time/alarmtimer.c | 114 +------------------------------------ 4 files changed, 15 insertions(+), 136 deletions(-) diff --git a/fs/timerfd.c b/fs/timerfd.c index 31374ec8f9bd..94de69ec6af6 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -50,8 +50,7 @@ static DEFINE_SPINLOCK(cancel_lock); static inline bool isalarm(struct timerfd_ctx *ctx) { return ctx->clockid == CLOCK_REALTIME_ALARM || - ctx->clockid == CLOCK_BOOTTIME_ALARM || - ctx->clockid == CLOCK_POWEROFF_ALARM; + ctx->clockid == CLOCK_BOOTTIME_ALARM; } /* @@ -143,8 +142,7 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) { spin_lock(&ctx->cancel_lock); if ((ctx->clockid == CLOCK_REALTIME || - ctx->clockid == CLOCK_REALTIME_ALARM || - ctx->clockid == CLOCK_POWEROFF_ALARM) && + ctx->clockid == CLOCK_REALTIME_ALARM) && (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) { if (!ctx->might_cancel) { ctx->might_cancel = true; @@ -176,7 +174,6 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags, enum hrtimer_mode htmode; ktime_t texp; int clockid = ctx->clockid; - enum alarmtimer_type type; htmode = (flags & TFD_TIMER_ABSTIME) ? HRTIMER_MODE_ABS: HRTIMER_MODE_REL; @@ -187,8 +184,10 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags, ctx->tintv = timespec_to_ktime(ktmr->it_interval); if (isalarm(ctx)) { - type = clock2alarm(ctx->clockid); - alarm_init(&ctx->t.alarm, type, timerfd_alarmproc); + alarm_init(&ctx->t.alarm, + ctx->clockid == CLOCK_REALTIME_ALARM ? + ALARM_REALTIME : ALARM_BOOTTIME, + timerfd_alarmproc); } else { hrtimer_init(&ctx->t.tmr, clockid, htmode); hrtimer_set_expires(&ctx->t.tmr, texp); @@ -387,7 +386,6 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) { int ufd; struct timerfd_ctx *ctx; - enum alarmtimer_type type; /* Check the TFD_* constants for consistency. */ BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC); @@ -398,8 +396,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) clockid != CLOCK_REALTIME && clockid != CLOCK_REALTIME_ALARM && clockid != CLOCK_BOOTTIME && - clockid != CLOCK_BOOTTIME_ALARM && - clockid != CLOCK_POWEROFF_ALARM)) + clockid != CLOCK_BOOTTIME_ALARM)) return -EINVAL; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); @@ -410,12 +407,13 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) spin_lock_init(&ctx->cancel_lock); ctx->clockid = clockid; - if (isalarm(ctx)) { - type = clock2alarm(ctx->clockid); - alarm_init(&ctx->t.alarm, type, timerfd_alarmproc); - } else { + if (isalarm(ctx)) + alarm_init(&ctx->t.alarm, + ctx->clockid == CLOCK_REALTIME_ALARM ? + ALARM_REALTIME : ALARM_BOOTTIME, + timerfd_alarmproc); + else hrtimer_init(&ctx->t.tmr, clockid, HRTIMER_MODE_ABS); - } ctx->moffs = ktime_mono_to_real((ktime_t){ .tv64 = 0 }); @@ -487,10 +485,6 @@ static int do_timerfd_settime(int ufd, int flags, ret = timerfd_setup(ctx, flags, new); spin_unlock_irq(&ctx->wqh.lock); - - if (ctx->clockid == CLOCK_POWEROFF_ALARM) - set_power_on_alarm(); - fdput(f); return ret; } diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h index 9657030eacee..9de8bdba63cd 100644 --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -5,12 +5,10 @@ #include #include #include -#include enum alarmtimer_type { ALARM_REALTIME, ALARM_BOOTTIME, - ALARM_POWEROFF_REALTIME, ALARM_NUMTYPE, }; @@ -50,8 +48,6 @@ int alarm_start_relative(struct alarm *alarm, ktime_t start); void alarm_restart(struct alarm *alarm); int alarm_try_to_cancel(struct alarm *alarm); int alarm_cancel(struct alarm *alarm); -void set_power_on_alarm(void); -enum alarmtimer_type clock2alarm(clockid_t clockid); u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval); u64 alarm_forward_now(struct alarm *alarm, ktime_t interval); diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h index ebc357119745..8f96bff58dee 100644 --- a/include/uapi/linux/time.h +++ b/include/uapi/linux/time.h @@ -60,7 +60,6 @@ struct itimerval { #define CLOCK_BOOTTIME_ALARM 9 #define CLOCK_SGI_CYCLE 10 /* Hardware specific */ #define CLOCK_TAI 11 -#define CLOCK_POWEROFF_ALARM 12 #define MAX_CLOCKS 16 #define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 0a359d67d927..58a0a755ae45 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -29,7 +29,6 @@ #ifdef CONFIG_MSM_PM #include "lpm-levels.h" #endif -#include /** * struct alarm_base - Alarm timer bases @@ -51,84 +50,12 @@ static ktime_t freezer_delta; static DEFINE_SPINLOCK(freezer_delta_lock); static struct wakeup_source *ws; -static struct delayed_work work; -static struct workqueue_struct *power_off_alarm_workqueue; #ifdef CONFIG_RTC_CLASS /* rtc timer and device for setting alarm wakeups at suspend */ static struct rtc_timer rtctimer; static struct rtc_device *rtcdev; static DEFINE_SPINLOCK(rtcdev_lock); -static struct mutex power_on_alarm_lock; - -/** - * set_power_on_alarm - set power on alarm value into rtc register - * - * Get the soonest power off alarm timer and set the alarm value into rtc - * register. - */ -void set_power_on_alarm(void) -{ - int rc; - struct timespec wall_time, alarm_ts; - long alarm_secs = 0l; - long rtc_secs, alarm_time, alarm_delta; - struct rtc_time rtc_time; - struct rtc_wkalrm alarm; - struct rtc_device *rtc; - struct timerqueue_node *next; - unsigned long flags; - struct alarm_base *base = &alarm_bases[ALARM_POWEROFF_REALTIME]; - - rc = mutex_lock_interruptible(&power_on_alarm_lock); - if (rc != 0) - return; - - spin_lock_irqsave(&base->lock, flags); - next = timerqueue_getnext(&base->timerqueue); - spin_unlock_irqrestore(&base->lock, flags); - - rtc = alarmtimer_get_rtcdev(); - if (!rtc) - goto exit; - - if (next) { - alarm_ts = ktime_to_timespec(next->expires); - alarm_secs = alarm_ts.tv_sec; - } - - if (!alarm_secs) - goto disable_alarm; - - getnstimeofday(&wall_time); - - /* - * alarm_secs have to be bigger than "wall_time +1". - * It is to make sure that alarm time will be always - * bigger than wall time. - */ - if (alarm_secs <= wall_time.tv_sec + 1) - goto disable_alarm; - - rtc_read_time(rtc, &rtc_time); - rtc_tm_to_time(&rtc_time, &rtc_secs); - alarm_delta = wall_time.tv_sec - rtc_secs; - alarm_time = alarm_secs - alarm_delta; - - rtc_time_to_tm(alarm_time, &alarm.time); - alarm.enabled = 1; - rc = rtc_set_alarm(rtc, &alarm); - if (rc) - goto disable_alarm; - - mutex_unlock(&power_on_alarm_lock); - return; - -disable_alarm: - rtc_timer_cancel(rtc, &rtc->aie_timer); -exit: - mutex_unlock(&power_on_alarm_lock); -} static void alarmtimer_triggered_func(void *p) { @@ -200,8 +127,6 @@ static void alarmtimer_rtc_remove_device(struct device *dev, static inline void alarmtimer_rtc_timer_init(void) { - mutex_init(&power_on_alarm_lock); - rtc_timer_init(&rtctimer, NULL, NULL); } @@ -228,14 +153,8 @@ struct rtc_device *alarmtimer_get_rtcdev(void) static inline int alarmtimer_rtc_interface_setup(void) { return 0; } static inline void alarmtimer_rtc_interface_remove(void) { } static inline void alarmtimer_rtc_timer_init(void) { } -void set_power_on_alarm(void) { } #endif -static void alarm_work_func(struct work_struct *unused) -{ - set_power_on_alarm(); -} - /** * alarmtimer_enqueue - Adds an alarm timer to an alarm_base timerqueue * @base: pointer to the base where the timer is being run @@ -305,10 +224,6 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) } spin_unlock_irqrestore(&base->lock, flags); - /* set next power off alarm */ - if (alarm->type == ALARM_POWEROFF_REALTIME) - queue_delayed_work(power_off_alarm_workqueue, &work, 0); - return ret; } @@ -341,8 +256,6 @@ static int alarmtimer_suspend(struct device *dev) int i; int ret = 0; - cancel_delayed_work_sync(&work); - spin_lock_irqsave(&freezer_delta_lock, flags); min = freezer_delta; freezer_delta = ktime_set(0, 0); @@ -406,8 +319,6 @@ static int alarmtimer_suspend(struct device *dev) int i; int ret; - cancel_delayed_work_sync(&work); - spin_lock_irqsave(&freezer_delta_lock, flags); min = freezer_delta; freezer_delta = ktime_set(0, 0); @@ -647,14 +558,12 @@ EXPORT_SYMBOL_GPL(alarm_forward_now); * clock2alarm - helper that converts from clockid to alarmtypes * @clockid: clockid. */ -enum alarmtimer_type clock2alarm(clockid_t clockid) +static enum alarmtimer_type clock2alarm(clockid_t clockid) { if (clockid == CLOCK_REALTIME_ALARM) return ALARM_REALTIME; if (clockid == CLOCK_BOOTTIME_ALARM) return ALARM_BOOTTIME; - if (clockid == CLOCK_POWEROFF_ALARM) - return ALARM_POWEROFF_REALTIME; return -1; } @@ -1050,13 +959,10 @@ static int __init alarmtimer_init(void) posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock); posix_timers_register_clock(CLOCK_BOOTTIME_ALARM, &alarm_clock); - posix_timers_register_clock(CLOCK_POWEROFF_ALARM, &alarm_clock); /* Initialize alarm bases */ alarm_bases[ALARM_REALTIME].base_clockid = CLOCK_REALTIME; alarm_bases[ALARM_REALTIME].gettime = &ktime_get_real; - alarm_bases[ALARM_POWEROFF_REALTIME].base_clockid = CLOCK_REALTIME; - alarm_bases[ALARM_POWEROFF_REALTIME].gettime = &ktime_get_real; alarm_bases[ALARM_BOOTTIME].base_clockid = CLOCK_BOOTTIME; alarm_bases[ALARM_BOOTTIME].gettime = &ktime_get_boottime; for (i = 0; i < ALARM_NUMTYPE; i++) { @@ -1078,24 +984,8 @@ static int __init alarmtimer_init(void) goto out_drv; } ws = wakeup_source_register("alarmtimer"); - if (!ws) { - error = -ENOMEM; - goto out_ws; - } - - INIT_DELAYED_WORK(&work, alarm_work_func); - power_off_alarm_workqueue = - create_singlethread_workqueue("power_off_alarm"); - if (!power_off_alarm_workqueue) { - error = -ENOMEM; - goto out_wq; - } - return 0; -out_wq: - wakeup_source_unregister(ws); -out_ws: - platform_device_unregister(pdev); + out_drv: platform_driver_unregister(&alarmtimer_driver); out_if: From 7a22262828748d8e0c00661b10bec54d7d11fac4 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Tue, 28 Aug 2018 15:15:27 +0530 Subject: [PATCH 07/20] diag: Prevent out of bound access while initializing msg mask Move the mask_info mutex initialization outside mask structure to facilitate prevention of out of bound access while initializing msg mask during md session creation. Use separate msg_mask_tbl_count for ODL session msg mask and regular msg mask to prevent out of bound access in a possible race condition of accessing mask ranges. The chances of accessing uninitialized mask is prevented by adding null pointer checks for the mask structure and its member pointer. Change-Id: I87497c67daff8cc1797a1266d50456bdbd3a9c23 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_masks.c | 105 +++++++++++++++++++++++------- drivers/char/diag/diag_masks.h | 7 +- drivers/char/diag/diagchar.h | 1 + drivers/char/diag/diagchar_core.c | 13 ++-- drivers/char/diag/diagfwd_cntl.c | 4 +- 5 files changed, 97 insertions(+), 33 deletions(-) diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index 4b24df4b6e4c..7c4ed8ebb09f 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -142,6 +142,9 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id) mutex_lock(&mask_info->lock); for (i = 0; i < MAX_EQUIP_ID; i++, mask++) { + if (!mask->ptr) + continue; + if (equip_id != i && equip_id != ALL_EQUIP_ID) continue; @@ -293,11 +296,12 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last) int temp_len = 0; uint8_t *buf = NULL; uint8_t *temp = NULL; + uint8_t msg_mask_tbl_count_local = 0; uint32_t mask_size = 0; struct diag_mask_info *mask_info = NULL; struct diag_msg_mask_t *mask = NULL; struct diag_ctrl_msg_mask header; - uint8_t msg_mask_tbl_count_local; + struct diag_md_session_t *md_session_info = NULL; if (peripheral >= NUM_PERIPHERALS) return; @@ -309,10 +313,11 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last) return; } - if (driver->md_session_mask != 0 && - (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral))) + if ((driver->md_session_mask != 0) && + (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral))) { + md_session_info = driver->md_session_map[peripheral]; mask_info = driver->md_session_map[peripheral]->msg_mask; - else + } else mask_info = &msg_mask; if (!mask_info) @@ -325,7 +330,10 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last) return; } buf = mask_info->update_buf; - msg_mask_tbl_count_local = driver->msg_mask_tbl_count; + if (md_session_info) + msg_mask_tbl_count_local = md_session_info->msg_mask_tbl_count; + else + msg_mask_tbl_count_local = driver->msg_mask_tbl_count; mutex_unlock(&driver->msg_mask_lock); mutex_lock(&mask_info->lock); switch (mask_info->status) { @@ -344,6 +352,8 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last) } for (i = 0; i < msg_mask_tbl_count_local; i++, mask++) { + if (!mask->ptr) + continue; mutex_lock(&driver->msg_mask_lock); if (((mask->ssid_first > first) || (mask->ssid_last_tools < last)) && first != ALL_SSID) { @@ -496,6 +506,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, { int i; int write_len = 0; + uint8_t msg_mask_tbl_count = 0; struct diag_msg_mask_t *mask_ptr = NULL; struct diag_msg_ssid_query_t rsp; struct diag_ssid_range_t ssid_range; @@ -525,15 +536,17 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, return 0; } mutex_lock(&driver->msg_mask_lock); + msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; rsp.cmd_code = DIAG_CMD_MSG_CONFIG; rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE; rsp.status = MSG_STATUS_SUCCESS; rsp.padding = 0; - rsp.count = driver->msg_mask_tbl_count; + rsp.count = msg_mask_tbl_count; memcpy(dest_buf, &rsp, sizeof(rsp)); write_len += sizeof(rsp); mask_ptr = (struct diag_msg_mask_t *)mask_info->ptr; - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask_ptr++) { + for (i = 0; i < msg_mask_tbl_count; i++, mask_ptr++) { if (write_len + sizeof(ssid_range) > dest_len) { pr_err("diag: In %s, Truncating response due to size limitations of rsp buffer\n", __func__); @@ -579,6 +592,8 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len, rsp.padding = 0; build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr; for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) { + if (!build_mask->ptr) + continue; if (build_mask->ssid_first != req->ssid_first) continue; num_entries = req->ssid_last - req->ssid_first + 1; @@ -610,6 +625,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, int i; int write_len = 0; uint32_t mask_size = 0; + uint8_t msg_mask_tbl_count = 0; struct diag_msg_mask_t *mask = NULL; struct diag_build_mask_req_t *req = NULL; struct diag_msg_build_mask_t rsp; @@ -640,6 +656,8 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, } mutex_lock(&driver->msg_mask_lock); + msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; req = (struct diag_build_mask_req_t *)src_buf; rsp.cmd_code = DIAG_CMD_MSG_CONFIG; rsp.sub_cmd = DIAG_CMD_OP_GET_MSG_MASK; @@ -655,7 +673,9 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&driver->md_session_lock); return -EINVAL; } - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + for (i = 0; i < msg_mask_tbl_count; i++, mask++) { + if (!mask->ptr) + continue; if ((req->ssid_first < mask->ssid_first) || (req->ssid_first > mask->ssid_last_tools)) { continue; @@ -692,6 +712,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_mask_t *mask_next = NULL; uint32_t *temp = NULL; struct diag_md_session_t *info = NULL; + uint8_t msg_mask_tbl_count = 0; mutex_lock(&driver->md_session_lock); info = diag_md_session_get_pid(pid); @@ -724,8 +745,12 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&driver->md_session_lock); return -EINVAL; } - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { - if (i < (driver->msg_mask_tbl_count - 1)) { + msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; + for (i = 0; i < msg_mask_tbl_count; i++, mask++) { + if (!mask->ptr) + continue; + if (i < (msg_mask_tbl_count - 1)) { mask_next = mask; mask_next++; } else @@ -827,6 +852,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, struct diag_msg_mask_t *mask = NULL; struct diag_mask_info *mask_info = NULL; struct diag_md_session_t *info = NULL; + uint8_t msg_mask_tbl_count = 0; mutex_lock(&driver->md_session_lock); info = diag_md_session_get_pid(pid); @@ -861,9 +887,11 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&driver->md_session_lock); return -EINVAL; } + msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED : DIAG_CTRL_MASK_ALL_DISABLED; - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + for (i = 0; i < msg_mask_tbl_count; i++, mask++) { if (mask && mask->ptr) { mutex_lock(&mask->lock); memset(mask->ptr, req->rt_mask, @@ -1451,7 +1479,8 @@ static int diag_create_msg_mask_table(void) mutex_lock(&msg_mask.lock); mutex_lock(&driver->msg_mask_lock); driver->msg_mask_tbl_count = MSG_MASK_TBL_CNT; - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + for (i = 0; (i < driver->msg_mask_tbl_count) && mask; + i++, mask++) { range.ssid_first = msg_mask_tbl[i].ssid_first; range.ssid_last = msg_mask_tbl[i].ssid_last; err = diag_create_msg_mask_table_entry(mask, &range); @@ -1476,7 +1505,8 @@ static int diag_create_build_time_mask(void) mutex_lock(&driver->msg_mask_lock); driver->bt_msg_mask_tbl_count = MSG_MASK_TBL_CNT; build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr; - for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) { + for (i = 0; (i < driver->bt_msg_mask_tbl_count) && build_mask; + i++, build_mask++) { range.ssid_first = msg_mask_tbl[i].ssid_first; range.ssid_last = msg_mask_tbl[i].ssid_last; err = diag_create_msg_mask_table_entry(build_mask, &range); @@ -1599,7 +1629,7 @@ static int diag_create_log_mask_table(void) mutex_lock(&log_mask.lock); mask = (struct diag_log_mask_t *)(log_mask.ptr); - for (i = 0; i < MAX_EQUIP_ID; i++, mask++) { + for (i = 0; (i < MAX_EQUIP_ID) && mask; i++, mask++) { mask->equip_id = i; mask->num_items = LOG_GET_ITEM_NUM(log_code_last_tbl[i]); mask->num_items_tools = mask->num_items; @@ -1643,7 +1673,6 @@ static int __diag_mask_init(struct diag_mask_info *mask_info, int mask_len, } kmemleak_not_leak(mask_info->update_buf); } - mutex_init(&mask_info->lock); return 0; } @@ -1667,9 +1696,10 @@ int diag_log_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src) struct diag_log_mask_t *src_mask = NULL; struct diag_log_mask_t *dest_mask = NULL; - if (!src) + if (!src || !dest) return -EINVAL; + mutex_init(&dest->lock); err = __diag_mask_init(dest, LOG_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; @@ -1732,9 +1762,11 @@ static int diag_msg_mask_init(void) int err = 0; int i; + mutex_init(&msg_mask.lock); err = __diag_mask_init(&msg_mask, MSG_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; + err = diag_create_msg_mask_table(); if (err) { pr_err("diag: Unable to create msg masks, err: %d\n", err); @@ -1749,7 +1781,8 @@ static int diag_msg_mask_init(void) return 0; } -int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src) +int diag_msg_mask_copy(struct diag_md_session_t *new_session, + struct diag_mask_info *dest, struct diag_mask_info *src) { int i; int err = 0; @@ -1760,17 +1793,25 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src) if (!src || !dest) return -EINVAL; - err = __diag_mask_init(dest, MSG_MASK_SIZE, APPS_BUF_SIZE); - if (err) - return err; + mutex_init(&dest->lock); mutex_lock(&dest->lock); mutex_lock(&driver->msg_mask_lock); + new_session->msg_mask_tbl_count = + driver->msg_mask_tbl_count; + err = __diag_mask_init(dest, + (new_session->msg_mask_tbl_count * + sizeof(struct diag_msg_mask_t)), APPS_BUF_SIZE); + if (err) { + mutex_unlock(&driver->msg_mask_lock); + mutex_unlock(&dest->lock); + return err; + } src_mask = (struct diag_msg_mask_t *)src->ptr; dest_mask = (struct diag_msg_mask_t *)dest->ptr; dest->mask_len = src->mask_len; dest->status = src->status; - for (i = 0; i < driver->msg_mask_tbl_count; i++) { + for (i = 0; i < new_session->msg_mask_tbl_count; i++) { range.ssid_first = src_mask->ssid_first; range.ssid_last = src_mask->ssid_last; err = diag_create_msg_mask_table_entry(dest_mask, &range); @@ -1786,10 +1827,12 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src) return err; } -void diag_msg_mask_free(struct diag_mask_info *mask_info) +void diag_msg_mask_free(struct diag_mask_info *mask_info, + struct diag_md_session_t *session_info) { int i; struct diag_msg_mask_t *mask = NULL; + uint8_t msg_mask_tbl_count = 0; if (!mask_info || !mask_info->ptr) return; @@ -1803,7 +1846,10 @@ void diag_msg_mask_free(struct diag_mask_info *mask_info) mutex_unlock(&mask_info->lock); return; } - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + msg_mask_tbl_count = (session_info) ? + session_info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; + for (i = 0; i < msg_mask_tbl_count; i++, mask++) { kfree(mask->ptr); mask->ptr = NULL; } @@ -1834,6 +1880,7 @@ static int diag_build_time_mask_init(void) int err = 0; /* There is no need for update buffer for Build Time masks */ + mutex_init(&msg_bt_mask.lock); err = __diag_mask_init(&msg_bt_mask, MSG_MASK_SIZE, 0); if (err) return err; @@ -1867,6 +1914,7 @@ static int diag_log_mask_init(void) int err = 0; int i; + mutex_init(&log_mask.lock); err = __diag_mask_init(&log_mask, LOG_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; @@ -1901,6 +1949,7 @@ static int diag_event_mask_init(void) int err = 0; int i; + mutex_init(&event_mask.lock); err = __diag_mask_init(&event_mask, EVENT_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; @@ -1922,6 +1971,7 @@ int diag_event_mask_copy(struct diag_mask_info *dest, if (!src || !dest) return -EINVAL; + mutex_init(&dest->lock); err = __diag_mask_init(dest, EVENT_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; @@ -1961,6 +2011,7 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, struct diag_mask_info *mask_info = NULL; struct diag_msg_mask_t *mask = NULL; unsigned char *ptr = NULL; + uint8_t msg_mask_tbl_count = 0; if (!buf || count == 0) return -EINVAL; @@ -1993,7 +2044,11 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, mutex_unlock(&mask_info->lock); return -EINVAL; } - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { + msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count : + driver->msg_mask_tbl_count; + for (i = 0; i < msg_mask_tbl_count; i++, mask++) { + if (!mask->ptr) + continue; ptr = mask_info->update_buf; len = 0; mutex_lock(&mask->lock); @@ -2068,6 +2123,8 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count, return -EINVAL; } for (i = 0; i < MAX_EQUIP_ID; i++, mask++) { + if (!mask->ptr) + continue; ptr = mask_info->update_buf; len = 0; mutex_lock(&mask->lock); diff --git a/drivers/char/diag/diag_masks.h b/drivers/char/diag/diag_masks.h index 6edeee954d74..a736ff269e8d 100644 --- a/drivers/char/diag/diag_masks.h +++ b/drivers/char/diag/diag_masks.h @@ -160,12 +160,13 @@ int diag_masks_init(void); void diag_masks_exit(void); int diag_log_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src); -int diag_msg_mask_copy(struct diag_mask_info *dest, - struct diag_mask_info *src); +int diag_msg_mask_copy(struct diag_md_session_t *new_session, + struct diag_mask_info *dest, struct diag_mask_info *src); int diag_event_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src); void diag_log_mask_free(struct diag_mask_info *mask_info); -void diag_msg_mask_free(struct diag_mask_info *mask_info); +void diag_msg_mask_free(struct diag_mask_info *mask_info, + struct diag_md_session_t *session_info); void diag_event_mask_free(struct diag_mask_info *mask_info); int diag_process_apps_masks(unsigned char *buf, int len, int pid); void diag_send_updates_peripheral(uint8_t peripheral); diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h index f265cc7f01b8..42c0d7ca94f7 100644 --- a/drivers/char/diag/diagchar.h +++ b/drivers/char/diag/diagchar.h @@ -406,6 +406,7 @@ struct diag_md_session_t { int pid; int peripheral_mask; uint8_t hdlc_disabled; + uint8_t msg_mask_tbl_count; struct timer_list hdlc_reset_timer; struct diag_mask_info *msg_mask; struct diag_mask_info *log_mask; diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index b686f5b79f7d..4a04fd58ed95 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1255,7 +1255,8 @@ static void diag_md_session_exit(void) diag_log_mask_free(session_info->log_mask); kfree(session_info->log_mask); session_info->log_mask = NULL; - diag_msg_mask_free(session_info->msg_mask); + diag_msg_mask_free(session_info->msg_mask, + session_info); kfree(session_info->msg_mask); session_info->msg_mask = NULL; diag_event_mask_free(session_info->event_mask); @@ -1328,7 +1329,9 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc) "return value of event copy. err %d\n", err); goto fail_peripheral; } - err = diag_msg_mask_copy(new_session->msg_mask, &msg_mask); + new_session->msg_mask_tbl_count = 0; + err = diag_msg_mask_copy(new_session, new_session->msg_mask, + &msg_mask); if (err) { DIAG_LOG(DIAG_DEBUG_USERSPACE, "return value of msg copy. err %d\n", err); @@ -1364,7 +1367,8 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc) diag_event_mask_free(new_session->event_mask); kfree(new_session->event_mask); new_session->event_mask = NULL; - diag_msg_mask_free(new_session->msg_mask); + diag_msg_mask_free(new_session->msg_mask, + new_session); kfree(new_session->msg_mask); new_session->msg_mask = NULL; kfree(new_session); @@ -1392,7 +1396,8 @@ static void diag_md_session_close(int pid) diag_log_mask_free(session_info->log_mask); kfree(session_info->log_mask); session_info->log_mask = NULL; - diag_msg_mask_free(session_info->msg_mask); + diag_msg_mask_free(session_info->msg_mask, + session_info); kfree(session_info->msg_mask); session_info->msg_mask = NULL; diag_event_mask_free(session_info->event_mask); diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c index e2b2343d988d..c8f3e8e9c08b 100644 --- a/drivers/char/diag/diagfwd_cntl.c +++ b/drivers/char/diag/diagfwd_cntl.c @@ -519,7 +519,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len, mask_ptr = (struct diag_msg_mask_t *)msg_mask.ptr; found = 0; for (j = 0; j < driver->msg_mask_tbl_count; j++, mask_ptr++) { - if (!mask_ptr || !ssid_range) { + if (!mask_ptr->ptr || !ssid_range) { found = 1; break; } @@ -591,7 +591,7 @@ static void diag_build_time_mask_update(uint8_t *buf, num_items = range->ssid_last - range->ssid_first + 1; for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) { - if (!build_mask) { + if (!build_mask->ptr) { found = 1; break; } From 56cf270b752118317481cd08bf340a7557cafb2c Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Fri, 8 Jun 2018 16:55:32 +0530 Subject: [PATCH 08/20] msm: ipa3: Add mutex to prevent race condition There is a race condition between ipa3_nat_init_cmd and ipa_read_nat4. The two thread will R/W the critical global variables. This will result in race conditions and possibly buffer overread/ overwrite issues. Add code to prevent this race condition. Change-Id: I6bf9a837ae941cf3ad9413da6e44821916acf196 Acked-by: Pooja Kumari Signed-off-by: Mohammed Javid --- drivers/platform/msm/ipa/ipa_v2/ipa_nat.c | 11 +++++++++++ drivers/platform/msm/ipa/ipa_v3/ipa_nat.c | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c index 1be68b31656b..56d699e3801c 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c @@ -344,6 +344,9 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("Detected overflow\n"); return -EPERM; } + + mutex_lock(&ipa_ctx->nat_mem.lock); + /* Check Table Entry offset is not beyond allocated size */ tmp = init->ipv4_rules_offset + @@ -353,6 +356,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->ipv4_rules_offset, (init->table_entries + 1), tmp, ipa_ctx->nat_mem.size); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } @@ -360,6 +364,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->expn_rules_offset > UINT_MAX - (TBL_ENTRY_SIZE * init->expn_table_entries)) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } /* Check Expn Table Entry offset is not @@ -371,6 +376,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->expn_rules_offset, init->expn_table_entries, tmp, ipa_ctx->nat_mem.size); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } @@ -378,6 +384,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->index_offset > UINT_MAX - (INDX_TBL_ENTRY_SIZE * (init->table_entries + 1))) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } /* Check Indx Table Entry offset is not @@ -389,6 +396,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->index_offset, (init->table_entries + 1), tmp, ipa_ctx->nat_mem.size); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } @@ -396,6 +404,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->index_expn_offset > (UINT_MAX - (INDX_TBL_ENTRY_SIZE * init->expn_table_entries))) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } /* Check Expn Table entry offset is not @@ -407,6 +416,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->index_expn_offset, init->expn_table_entries, tmp, ipa_ctx->nat_mem.size); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } @@ -555,6 +565,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) free_nop: kfree(reg_write_nop); bail: + mutex_unlock(&ipa_ctx->nat_mem.lock); return result; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c index 92cd32d6488a..e11b4280400f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c @@ -368,6 +368,8 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("Detected overflow\n"); return -EPERM; } + mutex_lock(&ipa3_ctx->nat_mem.lock); + /* Check Table Entry offset is not beyond allocated size */ tmp = init->ipv4_rules_offset + @@ -377,6 +379,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->ipv4_rules_offset, (init->table_entries + 1), tmp, ipa3_ctx->nat_mem.size); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } @@ -384,6 +387,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->expn_rules_offset > (UINT_MAX - (TBL_ENTRY_SIZE * init->expn_table_entries))) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } /* Check Expn Table Entry offset is not @@ -395,6 +399,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->expn_rules_offset, init->expn_table_entries, tmp, ipa3_ctx->nat_mem.size); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } @@ -402,6 +407,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->index_offset > UINT_MAX - (INDX_TBL_ENTRY_SIZE * (init->table_entries + 1))) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } /* Check Indx Table Entry offset is not @@ -413,6 +419,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->index_offset, (init->table_entries + 1), tmp, ipa3_ctx->nat_mem.size); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } @@ -420,6 +427,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->index_expn_offset > UINT_MAX - (INDX_TBL_ENTRY_SIZE * init->expn_table_entries)) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } /* Check Expn Table entry offset is not @@ -431,6 +439,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->index_expn_offset, init->expn_table_entries, tmp, ipa3_ctx->nat_mem.size); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } @@ -580,6 +589,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) free_nop: ipahal_destroy_imm_cmd(nop_cmd_pyld); bail: + mutex_unlock(&ipa3_ctx->nat_mem.lock); return result; } From a8434bcb8db69d62ef9f3f4b33feb99a59e3e8cb Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Mon, 27 Aug 2018 15:32:35 +0530 Subject: [PATCH 09/20] msm:ipa: Prevent NAT table deletion only if public ip is not assigned Currnetly NAT table is not deleted even if public ip is assigned to NAT table. Add check to prevent deletion only if public ip is not assigned. Change-Id: I4855b21472d3f6bf541d07733b18592e9e677ce6 Acked-by: Pooja Kumari Signed-off-by: Mohammed Javid --- drivers/platform/msm/ipa/ipa_v2/ipa_nat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c index 56d699e3801c..dda4c0f36be4 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c @@ -784,7 +784,7 @@ int ipa2_nat_del_cmd(struct ipa_ioc_v4_nat_del *del) return -EPERM; } - if (ipa_ctx->nat_mem.public_ip_addr) { + if (!ipa_ctx->nat_mem.public_ip_addr) { IPAERR_RL("Public IP addr not assigned and trying to delete\n"); return -EPERM; } From 41934b3bc98e535a55721e262bc5791e4199814c Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 30 Aug 2018 15:46:57 -0700 Subject: [PATCH 10/20] ARM: dts: msm: Invert interrupt polarity for K61 on mdm9650 CV2X Invert the interrupt to be on rising edge for K61 since the polarity has been reversed on the MCU firmware. Change-Id: Ibf75de531d8226731c8d49c39a36e559a155554b Signed-off-by: Gustavo Solaira --- arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi b/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi index 037ac98cdbd9..f0ee8b75c205 100644 --- a/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi +++ b/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi @@ -106,7 +106,7 @@ spi-max-frequency = <4800000>; reg = <0>; interrupt-parent = <&tlmm_pinmux>; - interrupts = <68 0>; + interrupts = <68 IRQ_TYPE_EDGE_RISING>; reset-gpio = <&tlmm_pinmux 89 GPIO_ACTIVE_LOW>; pinctrl-names = "active", "sleep"; pinctrl-0 = <&can_rst_on>; From d92b32df4979196d6ded6c130617b399a4f1ad36 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 19 Feb 2018 01:24:15 +0100 Subject: [PATCH 11/20] netfilter: ebtables: CONFIG_COMPAT: don't trust userland offsets We need to make sure the offsets are not out of range of the total size. Also check that they are in ascending order. The WARN_ON triggered by syzkaller (it sets panic_on_warn) is changed to also bail out, no point in continuing parsing. Briefly tested with simple ruleset of -A INPUT --limit 1/s' --log plus jump to custom chains using 32bit ebtables binary. Change-Id: Ic1b91b00521fb550f1774b916aa5b53c91940ed0 Reported-by: Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Git-commit: b71812168571fa55e44cdd0254471331b9c4c4c6 Signed-off-by: Dennis Cagle --- net/bridge/netfilter/ebtables.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index d9a8c05d995d..653d72979ee1 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -2019,7 +2019,9 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32, if (match_kern) match_kern->match_size = ret; - WARN_ON(type == EBT_COMPAT_TARGET && size_left); + if (WARN_ON(type == EBT_COMPAT_TARGET && size_left)) + return -EINVAL; + match32 = (struct compat_ebt_entry_mwt *) buf; } @@ -2076,6 +2078,15 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base, * * offsets are relative to beginning of struct ebt_entry (i.e., 0). */ + for (i = 0; i < 4 ; ++i) { + if (offsets[i] >= *total) + return -EINVAL; + if (i == 0) + continue; + if (offsets[i-1] > offsets[i]) + return -EINVAL; + } + for (i = 0, j = 1 ; j < 4 ; j++, i++) { struct compat_ebt_entry_mwt *match32; unsigned int size; From a8725b82e41c9dc0fb6fccd1039e1c964da9d408 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Tue, 19 Jun 2018 17:50:52 +0530 Subject: [PATCH 12/20] ASoC: msm: qdsp6v2: Fix rtac memory unmap issue in ASM driver During unmap of rtac block in ASM, mem_map_handle address is set to zero instead of the value. Set the map handle value to zero to avoid issue in freeing the ion memory. CRs-Fixed: 2254339 Change-Id: I6584be029d4c8dde235e722149c758df0db9916e Signed-off-by: Aditya Bavanari --- sound/soc/msm/qdsp6v2/q6asm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index c986db20c2d1..6718a3c39de1 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -900,7 +900,7 @@ int q6asm_unmap_rtac_block(uint32_t *mem_map_handle) __func__, result2); result = result2; } else { - mem_map_handle = 0; + *mem_map_handle = 0; } result2 = q6asm_mmap_apr_dereg(); From 1d5ccca47c3bd55070747795f8ef77daa69e8def Mon Sep 17 00:00:00 2001 From: Kaustubh Pandey Date: Tue, 12 Jun 2018 10:09:53 +0530 Subject: [PATCH 13/20] net: core: null pointer derefernce in sockev_client_cb sockev_client_cb creates a netlink message and populates the nlmsg_data using the socket->sock information. If socket is closed, while the nlmsg_data is being populated, a null pointer dereference occurs. BUG: KASAN: null-ptr-deref in sockev_client_cb+0x1e4/0x310 Read of size 2 at addr 0000000000000010 by task syz-executor/9398 CPU: 6 PID: 9398 Comm: syz-executor Tainted: G W O 4.9.92+ #1 Call trace: [] sockev_client_cb+0x1e4/0x310 [] notifier_call_chain+0x94/0xe0 [] __blocking_notifier_call_chain+0x6c/0xb8 [] blocking_notifier_call_chain+0x40/0x50 [] sockev_notify net/socket.c:180 [inline] [] SYSC_listen net/socket.c:1446 [inline] [] SyS_listen+0x1e0/0x1f8 [] el0_svc_naked+0x24/0x28 CR's Fixed: 2251042 Change-Id: Iad9eb58cd05fcdc0b5cc1ed24de56b69abb532b4 Signed-off-by: Sharath Chandra Vurukala Signed-off-by: Tejaswi Tanikella Signed-off-by: Kaustubh Pandey Acked-by: Chinmay Agarwal --- net/core/sockev_nlmcast.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/net/core/sockev_nlmcast.c b/net/core/sockev_nlmcast.c index 22148bf76e0a..1e92c5632b97 100644 --- a/net/core/sockev_nlmcast.c +++ b/net/core/sockev_nlmcast.c @@ -69,14 +69,17 @@ static int sockev_client_cb(struct notifier_block *nb, struct nlmsghdr *nlh; struct sknlsockevmsg *smsg; struct socket *sock; + struct sock *sk; sock = (struct socket *)data; - if (socknlmsgsk == 0) + if (!socknlmsgsk || !sock) goto done; - if ((socknlmsgsk == NULL) || (sock == NULL) || (sock->sk == NULL)) + + sk = sock->sk; + if (!sk) goto done; - if (sock->sk->sk_family != AF_INET && sock->sk->sk_family != AF_INET6) + if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6) goto done; if (event != SOCKEV_BIND && event != SOCKEV_LISTEN) @@ -98,12 +101,11 @@ static int sockev_client_cb(struct notifier_block *nb, memset(smsg, 0, sizeof(struct sknlsockevmsg)); smsg->pid = current->pid; _sockev_event(event, smsg->event, sizeof(smsg->event)); - smsg->skfamily = sock->sk->sk_family; - smsg->skstate = sock->sk->sk_state; - smsg->skprotocol = sock->sk->sk_protocol; - smsg->sktype = sock->sk->sk_type; - smsg->skflags = sock->sk->sk_flags; - + smsg->skfamily = sk->sk_family; + smsg->skstate = sk->sk_state; + smsg->skprotocol = sk->sk_protocol; + smsg->sktype = sk->sk_type; + smsg->skflags = sk->sk_flags; nlmsg_notify(socknlmsgsk, skb, 0, SKNLGRP_SOCKEV, 0, GFP_KERNEL); done: return 0; From 2a4d2c1bc2d6e0fddf0cb32b9fb727692ae0a592 Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Mon, 6 Aug 2018 12:58:30 +0530 Subject: [PATCH 14/20] msm: ipa: Validate routing rule id IPA driver expose routing rule id IOCTL's to user space. There is a chance of getting invalid routing rule-id. Validate it before committing it to IPA hardware. Change-Id: If80b94d3a055f9212d25aff9a57d1b45001ba586 Signed-off-by: Mohammed Javid --- drivers/platform/msm/ipa/ipa_v3/ipa_flt.c | 6 +++--- drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 4 ++++ drivers/platform/msm/ipa/ipa_v3/ipa_rt.c | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c index 3ba84463682d..cb9416e3ad8a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1099,8 +1099,8 @@ static int __ipa_validate_flt_rule(const struct ipa_flt_rule *rule, } if (rule->rule_id) { - if (rule->rule_id >= IPA_RULE_ID_MIN_VAL && - rule->rule_id <= IPA_RULE_ID_MAX_VAL) { + if (rule->rule_id < IPA_RULE_ID_MIN || + rule->rule_id >= IPA_RULE_ID_MAX) { IPAERR("invalid rule_id provided 0x%x\n" "rule_id 0x%x - 0x%x are auto generated\n", rule->rule_id, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 61e8d8a3dea1..7230e7a7a0d2 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -207,6 +207,10 @@ #define IPA_RULE_ID_MAX_VAL (0x1FF) #define IPA_RULE_ID_RULE_MISS (0x3FF) +#define IPA_RULE_ID_MIN (0x200) +#define IPA_RULE_ID_MAX ((IPA_RULE_ID_MIN << 1) - 1) + + #define IPA_HDR_PROC_CTX_TABLE_ALIGNMENT_BYTE 8 #define IPA_HDR_PROC_CTX_TABLE_ALIGNMENT(start_ofst) \ (((start_ofst) + IPA_HDR_PROC_CTX_TABLE_ALIGNMENT_BYTE - 1) & \ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c index 30a1546dcdb7..0ee3a37e3d9f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c @@ -1084,6 +1084,20 @@ static int __ipa_del_rt_tbl(struct ipa3_rt_tbl *entry) return 0; } +static int __ipa_rt_validate_rule_id(u16 rule_id) +{ + if (!rule_id) + return 0; + + if ((rule_id < IPA_RULE_ID_MIN) || + (rule_id >= IPA_RULE_ID_MAX)) { + IPAERR_RL("Invalid rule_id provided 0x%x\n", + rule_id); + return -EPERM; + } + + return 0; +} static int __ipa_rt_validate_hndls(const struct ipa_rt_rule *rule, struct ipa3_hdr_entry **hdr, struct ipa3_hdr_proc_ctx_entry **proc_ctx) @@ -1198,6 +1212,8 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name, if (__ipa_rt_validate_hndls(rule, &hdr, &proc_ctx)) goto error; + if (__ipa_rt_validate_rule_id(rule_id)) + goto error; tbl = __ipa_add_rt_tbl(ip, name); if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) { From 7cde623ae9bbcb43b92f108090d224571411fe75 Mon Sep 17 00:00:00 2001 From: Venkataraman Nerellapalli Date: Thu, 28 Jun 2018 19:34:15 +0530 Subject: [PATCH 15/20] ARM: dts: msm: Enable use-default-batt-values for apq8009-dragon Enable use-default-batt-values to return the default battery temperature which is 250. Change-Id: I4c3b3180fb1135a46db6f03c1e52395ea76329c2 Signed-off-by: c_vnerel --- arch/arm/boot/dts/qcom/apq8009-dragon.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi b/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi index e1bf02e7b5d2..7588da210b5a 100644 --- a/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi +++ b/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi @@ -245,3 +245,10 @@ status = "ok"; qcom,disable-bms; }; + +&pm8916_chg { + status = "ok"; + qcom,charging-disabled; + qcom,use-default-batt-values; +}; + From c30a6d5a94ce811a2e4a474cfb586ff5a06f6d70 Mon Sep 17 00:00:00 2001 From: Gustavo Solaira Date: Thu, 6 Sep 2018 16:04:39 -0700 Subject: [PATCH 16/20] ARM: dts: msm: Enable reset via PM_RESIN_N for mdm9650 CV2X Enable PMIC stage 2 reset for mdm9650 CV2X when the reset line is held low for 2 seconds. This is used by the PCIe RC host to force reset the MDM if it crashes or becomes unresponsive. Change-Id: Ie99cb0842b895bf474dd7dab8f78811834820ee0 Signed-off-by: Gustavo Solaira --- arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi b/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi index f0ee8b75c205..034e83ad5953 100644 --- a/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi +++ b/arch/arm/boot/dts/qcom/mdm9650-cv2x.dtsi @@ -330,3 +330,18 @@ qcom,vadc-thermal-node; }; }; + +&pmd9650_pon { + interrupts = <0x0 0x8 0x0>, <0x0 0x8 0x1>; + interrupt-names = "kpdpwr", "resin"; + qcom,s3-src = "resin"; + + qcom,pon_2 { + qcom,pon-type = <1>; + qcom,support-reset = <1>; + qcom,s1-timer = <0>; + qcom,s2-timer = <2000>; + qcom,s2-type = <7>; + qcom,pull-up = <1>; + }; +}; From 511af0973209195cc64271f6e77009741a351ae7 Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Thu, 19 Jul 2018 17:10:39 +0530 Subject: [PATCH 17/20] msm: kgsl: Add a property to find alignment of secure buffers Add a property to determine the hardware alignment constraint on secure buffers. XPUv2 and below have a minimum requirement of 1 MBytes alignment and hence driver should allocate memory with minimum alignment on size. Change-Id: Ie3ca5da489bc94ae57ddc6695e402463fd7a88c2 Signed-off-by: Sunil Khatri --- drivers/gpu/msm/kgsl.c | 22 ++++++++++++++++++++++ include/uapi/linux/msm_kgsl.h | 1 + 2 files changed, 23 insertions(+) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 510a5ef1d49d..c28009a33155 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1348,6 +1348,28 @@ long kgsl_ioctl_device_getproperty(struct kgsl_device_private *dev_priv, kgsl_context_put(context); break; } + case KGSL_PROP_SECURE_BUFFER_ALIGNMENT: + { + unsigned int align; + + if (param->sizebytes != sizeof(unsigned int)) { + result = -EINVAL; + break; + } + /* + * XPUv2 impose the constraint of 1MB memory alignment, + * on the other hand Hypervisor does not have such + * constraints. So driver should fulfill such + * requirements when allocating secure memory. + */ + align = MMU_FEATURE(&dev_priv->device->mmu, + KGSL_MMU_HYP_SECURE_ALLOC) ? PAGE_SIZE : SZ_1M; + + if (copy_to_user(param->value, &align, sizeof(align))) + result = -EFAULT; + + break; + } default: if (is_compat_task()) result = dev_priv->device->ftbl->getproperty_compat( diff --git a/include/uapi/linux/msm_kgsl.h b/include/uapi/linux/msm_kgsl.h index a7fe50f13b1b..c8ca62174f49 100644 --- a/include/uapi/linux/msm_kgsl.h +++ b/include/uapi/linux/msm_kgsl.h @@ -311,6 +311,7 @@ enum kgsl_timestamp_type { #define KGSL_PROP_HIGHEST_BANK_BIT 0x17 #define KGSL_PROP_DEVICE_BITNESS 0x18 #define KGSL_PROP_DEVICE_QDSS_STM 0x19 +#define KGSL_PROP_SECURE_BUFFER_ALIGNMENT 0x23 struct kgsl_shadowprop { unsigned long gpuaddr; From f9b13f4d437951064a029842b032d4e49fdd6849 Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Fri, 10 Aug 2018 11:46:58 +0530 Subject: [PATCH 18/20] msm: kgsl: Add a property to find if secure context is supported Add a property to determine if a target support secure context for use cases like CPZ. This property can be used by userspace application to create a secure context if its supported on the target. Change-Id: I1ccc824378fb8fbd2cfbc7b811c6c3fdcd17803e Signed-off-by: Sunil Khatri --- drivers/gpu/msm/kgsl.c | 17 +++++++++++++++++ include/uapi/linux/msm_kgsl.h | 1 + 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index c28009a33155..3d31622154d1 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1370,6 +1370,23 @@ long kgsl_ioctl_device_getproperty(struct kgsl_device_private *dev_priv, break; } + case KGSL_PROP_SECURE_CTXT_SUPPORT: + { + unsigned int secure_ctxt; + + if (param->sizebytes != sizeof(unsigned int)) { + result = -EINVAL; + break; + } + + secure_ctxt = dev_priv->device->mmu.secured ? 1 : 0; + + if (copy_to_user(param->value, &secure_ctxt, + sizeof(secure_ctxt))) + result = -EFAULT; + + break; + } default: if (is_compat_task()) result = dev_priv->device->ftbl->getproperty_compat( diff --git a/include/uapi/linux/msm_kgsl.h b/include/uapi/linux/msm_kgsl.h index c8ca62174f49..bc1624659396 100644 --- a/include/uapi/linux/msm_kgsl.h +++ b/include/uapi/linux/msm_kgsl.h @@ -312,6 +312,7 @@ enum kgsl_timestamp_type { #define KGSL_PROP_DEVICE_BITNESS 0x18 #define KGSL_PROP_DEVICE_QDSS_STM 0x19 #define KGSL_PROP_SECURE_BUFFER_ALIGNMENT 0x23 +#define KGSL_PROP_SECURE_CTXT_SUPPORT 0x24 struct kgsl_shadowprop { unsigned long gpuaddr; From 2f9e79e2c32a44104c24e6c58689f053608879f7 Mon Sep 17 00:00:00 2001 From: Ch Ganesh Kumar Date: Mon, 20 Aug 2018 13:35:37 +0530 Subject: [PATCH 19/20] msm: mdss: Fix Gamma LUT bounds condition Validate the Gamma correction feature with all bound condition. This change corrects the Gamma LUT block bound condition. Change-Id: I3fc460b6a6e2e76f7c07b649e1db1e01ce208476 Signed-off-by: Ch Ganesh Kumar --- drivers/video/msm/mdss/mdss_compat_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_compat_utils.c b/drivers/video/msm/mdss/mdss_compat_utils.c index 7a93d292a6da..b54ef434988b 100644 --- a/drivers/video/msm/mdss/mdss_compat_utils.c +++ b/drivers/video/msm/mdss/mdss_compat_utils.c @@ -1337,10 +1337,10 @@ static int __from_user_pgc_lut_data_legacy( return -EFAULT; if (num_r_stages > GC_LUT_SEGMENTS || num_b_stages > GC_LUT_SEGMENTS - || num_r_stages > GC_LUT_SEGMENTS || !num_r_stages || !num_b_stages + || num_g_stages > GC_LUT_SEGMENTS || !num_r_stages || !num_b_stages || !num_g_stages) { pr_err("invalid number of stages r_stages %d b_stages %d g_stages %d\n", - num_r_stages, num_b_stages, num_r_stages); + num_r_stages, num_b_stages, num_g_stages); return -EFAULT; } From ccdf226017148d7beb0b200d600046deff7b55a0 Mon Sep 17 00:00:00 2001 From: Yunfei Zhang Date: Thu, 21 Jun 2018 12:13:25 +0800 Subject: [PATCH 20/20] ASoC: msm: qdsp6v2: use correct stream id of next session Gapless playback can't work because incorrect stream id was used. Fix it by using correct stream id of next session. Change-Id: I938d62d0d563b9c5940ea88c96d9c256595a9d3c Signed-off-by: Yunfei Zhang --- sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index b7d0b663f890..1251f7a7bbd0 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -2388,13 +2388,13 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) case (Q6_SUBSYS_AVS2_7): rc = q6asm_stream_open_write_v3(ac, prtd->codec, bits_per_sample, - ac->stream_id, + stream_id, prtd->gapless_state.use_dsp_gapless_mode); break; case (Q6_SUBSYS_AVS2_8): rc = q6asm_stream_open_write_v4(ac, prtd->codec, bits_per_sample, - ac->stream_id, + stream_id, prtd->gapless_state.use_dsp_gapless_mode); break; case (Q6_SUBSYS_INVALID):