diff --git a/arch/arm64/configs/marlin_defconfig b/arch/arm64/configs/marlin_defconfig index f79b2e48003136be79e23eb0b6fbd5185d964746..a80f7b684cbc942af0879904b8b17ef7f47e23b4 100644 --- a/arch/arm64/configs/marlin_defconfig +++ b/arch/arm64/configs/marlin_defconfig @@ -220,12 +220,6 @@ CONFIG_RMNET_DATA_FC=y CONFIG_RMNET_DATA_DEBUG_PKT=y CONFIG_SOCKEV_NLMCAST=y CONFIG_BT=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=y CONFIG_BT_BDA=y CONFIG_MSM_BT_POWER=y CONFIG_CFG80211=y diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 7cff572082d0ee52354d48406b5fd4416b1a9ee1..f1d9b6261f55427513ad341a745e50017aced278 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -134,6 +134,46 @@ #define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT) #define ESR_ELx_WFx_ISS_WFE (UL(1) << 0) +/* ISS field definitions for System instruction traps */ +#define ESR_ELx_SYS64_ISS_RES0_SHIFT 22 +#define ESR_ELx_SYS64_ISS_RES0_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_RES0_SHIFT) +#define ESR_ELx_SYS64_ISS_DIR_MASK 0x1 +#define ESR_ELx_SYS64_ISS_DIR_READ 0x1 +#define ESR_ELx_SYS64_ISS_DIR_WRITE 0x0 + +#define ESR_ELx_SYS64_ISS_RT_SHIFT 5 +#define ESR_ELx_SYS64_ISS_RT_MASK (UL(0x1f) << ESR_ELx_SYS64_ISS_RT_SHIFT) +#define ESR_ELx_SYS64_ISS_CRM_SHIFT 1 +#define ESR_ELx_SYS64_ISS_CRM_MASK (UL(0xf) << ESR_ELx_SYS64_ISS_CRM_SHIFT) +#define ESR_ELx_SYS64_ISS_CRN_SHIFT 10 +#define ESR_ELx_SYS64_ISS_CRN_MASK (UL(0xf) << ESR_ELx_SYS64_ISS_CRN_SHIFT) +#define ESR_ELx_SYS64_ISS_OP1_SHIFT 14 +#define ESR_ELx_SYS64_ISS_OP1_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_OP1_SHIFT) +#define ESR_ELx_SYS64_ISS_OP2_SHIFT 17 +#define ESR_ELx_SYS64_ISS_OP2_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_OP2_SHIFT) +#define ESR_ELx_SYS64_ISS_OP0_SHIFT 20 +#define ESR_ELx_SYS64_ISS_OP0_MASK (UL(0x3) << ESR_ELx_SYS64_ISS_OP0_SHIFT) +#define ESR_ELx_SYS64_ISS_SYS_MASK (ESR_ELx_SYS64_ISS_OP0_MASK | \ + ESR_ELx_SYS64_ISS_OP1_MASK | \ + ESR_ELx_SYS64_ISS_OP2_MASK | \ + ESR_ELx_SYS64_ISS_CRN_MASK | \ + ESR_ELx_SYS64_ISS_CRM_MASK) +#define ESR_ELx_SYS64_ISS_SYS_VAL(op0, op1, op2, crn, crm) \ + (((op0) << ESR_ELx_SYS64_ISS_OP0_SHIFT) | \ + ((op1) << ESR_ELx_SYS64_ISS_OP1_SHIFT) | \ + ((op2) << ESR_ELx_SYS64_ISS_OP2_SHIFT) | \ + ((crn) << ESR_ELx_SYS64_ISS_CRN_SHIFT) | \ + ((crm) << ESR_ELx_SYS64_ISS_CRM_SHIFT)) + +#define ESR_ELx_SYS64_ISS_SYS_OP_MASK (ESR_ELx_SYS64_ISS_SYS_MASK | \ + ESR_ELx_SYS64_ISS_DIR_MASK) + +#define ESR_ELx_SYS64_ISS_SYS_CNTVCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \ + ESR_ELx_SYS64_ISS_DIR_READ) + +#define ESR_ELx_SYS64_ISS_SYS_CNTFRQ (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 0, 14, 0) | \ + ESR_ELx_SYS64_ISS_DIR_READ) + #ifndef __ASSEMBLY__ #include <asm/types.h> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index ea6cb1326b455c64dcfaf2e14063dbe83ec9d700..35cf3ad495ead124d4ec1329ebf35d1c8cdc90be 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -481,7 +481,7 @@ el0_sync: cmp x24, #ESR_ELx_EC_FP_EXC64 // FP/ASIMD exception b.eq el0_fpsimd_exc cmp x24, #ESR_ELx_EC_SYS64 // configurable trap - b.eq el0_undef + b.eq el0_sys cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception b.eq el0_sp_pc cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception @@ -618,6 +618,16 @@ el0_undef: mov x0, sp bl do_undefinstr b ret_to_user +el0_sys: + /* + * System instructions, for trapped cache maintenance instructions + */ + enable_dbg_and_irq + ct_user_exit + mov x0, x25 + mov x1, sp + bl do_sysinstr + b ret_to_user el0_dbg: /* * Debug exception handling diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 737ec185bfff983c1a1f99540779ea37f576ed47..eb27080806e3321592869ff1d92c1a5282186026 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -32,6 +32,7 @@ #include <linux/syscalls.h> #include <asm/atomic.h> +#include <asm/barrier.h> #include <asm/debug-monitors.h> #include <asm/esr.h> #include <asm/traps.h> @@ -408,6 +409,54 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) arm64_notify_die("Oops - undefined instruction", regs, &info, 0); } +static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs) +{ + int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; + + isb(); + if (rt != 31) + regs->regs[rt] = arch_counter_get_cntvct(); + regs->pc += 4; +} + +static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs) +{ + int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; + + if (rt != 31) + regs->regs[rt] = read_sysreg(cntfrq_el0); + regs->pc += 4; +} + +static void cntpct_read_handler(unsigned int esr, struct pt_regs *regs) +{ + int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; + + isb(); + if (rt != 31) + regs->regs[rt] = arch_counter_get_cntpct(); + regs->pc += 4; +} + +#define ESR_ELx_SYS64_ISS_SYS_CNTPCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 1, 14, 0) | \ + ESR_ELx_SYS64_ISS_DIR_READ) + +asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs) +{ + if ((esr & ESR_ELx_SYS64_ISS_SYS_OP_MASK) == ESR_ELx_SYS64_ISS_SYS_CNTVCT) { + cntvct_read_handler(esr, regs); + return; + } else if ((esr & ESR_ELx_SYS64_ISS_SYS_OP_MASK) == ESR_ELx_SYS64_ISS_SYS_CNTFRQ) { + cntfrq_read_handler(esr, regs); + return; + } else if ((esr & ESR_ELx_SYS64_ISS_SYS_OP_MASK) == ESR_ELx_SYS64_ISS_SYS_CNTPCT) { + cntpct_read_handler(esr, regs); + return; + } + + do_undefinstr(regs); +} + long compat_arm_syscall(struct pt_regs *regs); asmlinkage long do_ni_syscall(struct pt_regs *regs) diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index d2cacc7f079f87e0a3653747670b232c22e65b66..00f963bd92858f6baa7d2a080c224ede3db229a2 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -446,13 +446,6 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, char __user *from = iov->iov_base; while (seglen) { - sgl = list_first_entry(&ctx->tsgl, - struct skcipher_sg_list, list); - sg = sgl->sg; - - while (!sg->length) - sg++; - used = ctx->used; if (!used) { err = skcipher_wait_for_data(sk, flags); @@ -474,6 +467,13 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, if (!used) goto free; + sgl = list_first_entry(&ctx->tsgl, + struct skcipher_sg_list, list); + sg = sgl->sg; + + while (!sg->length) + sg++; + ablkcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used, ctx->iv); diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index ba88fe2b2adaccc168d492d94045caae440c4614..3cf23cd502c28a7b3e698c6162f6a8d031cee00a 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -2081,6 +2081,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, case FASTRPC_IOCTL_INIT: VERIFY(err, 0 == copy_from_user(&p.init, param, sizeof(p.init))); + if (err) + goto bail; + VERIFY(err, p.init.filelen >= 0 && p.init.memlen >= 0); if (err) goto bail; VERIFY(err, 0 == fastrpc_init_process(fl, &p.init)); diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 90420600e1eb1d6668d78eb6eb809e218d25673f..497b2f5434a1e29120ace79f1ff505b402141fde 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -110,6 +110,14 @@ config ARM_ARCH_TIMER_EVTSTREAM This must be disabled for hardware validation purposes to detect any hardware anomalies of missing events. +config ARM_ARCH_TIMER_VCT_ACCESS + bool "Support for ARM architected timer virtual counter access in userspace" + default n + depends on ARM_ARCH_TIMER + help + This option enables support for reading the ARM architected timer's + virtual counter in userspace. + config ARM_GLOBAL_TIMER bool select CLKSRC_OF if OF diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 0f69d44258c8ba7ccf0f42c5bb97ee558abfe68f..1c3d0c5971367406999c59051a962603ae1b4754 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -334,14 +334,18 @@ static void arch_counter_set_user_access(void) { u32 cntkctl = arch_timer_get_cntkctl(); - /* Disable user access to the timers */ + /* Disable user access to the timers and the physical counter */ /* Also disable virtual event stream */ cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN - | ARCH_TIMER_VIRT_EVT_EN); + | ARCH_TIMER_USR_VT_ACCESS_EN + | ARCH_TIMER_VIRT_EVT_EN + | ARCH_TIMER_USR_PCT_ACCESS_EN); - /* Enable user access to the virtual and physical counters */ - cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN | ARCH_TIMER_USR_PCT_ACCESS_EN - | ARCH_TIMER_USR_VT_ACCESS_EN; + /* Enable user access to the virtual counter */ + if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS)) + cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; + else + cntkctl &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; arch_timer_set_cntkctl(cntkctl); } diff --git a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_rmi_dev.c b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_rmi_dev.c index 7f1ed83830740abdd4404d084198454460d54db7..362de01ea7c10b8a7b99aa147567f428d77f66eb 100644 --- a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_rmi_dev.c +++ b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_rmi_dev.c @@ -134,7 +134,7 @@ static struct device_attribute attrs[] = { __ATTR(attn_state, S_IRUGO, rmidev_sysfs_attn_state_show, NULL), - __ATTR(pid, S_IRUGO | S_IRUGO | S_IWUSR | S_IWGRP, + __ATTR(pid, S_IRUGO | S_IRUGO | S_IWUSR, rmidev_sysfs_pid_show, rmidev_sysfs_pid_store), __ATTR(term, S_IWUSR, diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c index 4cead8fb38cd32ecf16a72b670e9f9e28cb4b8a8..d57f804b3a3ae578c50026a9619e51e052d68768 100644 --- a/drivers/mfd/wcd9xxx-core.c +++ b/drivers/mfd/wcd9xxx-core.c @@ -3107,19 +3107,19 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) ("wcd9xxx_core", 0); if (!IS_ERR(debugfs_wcd9xxx_dent)) { debugfs_peek = debugfs_create_file("slimslave_peek", - S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent, + S_IFREG | S_IRUSR, debugfs_wcd9xxx_dent, (void *) "slimslave_peek", &codec_debug_ops); debugfs_poke = debugfs_create_file("slimslave_poke", - S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent, + S_IFREG | S_IRUSR, debugfs_wcd9xxx_dent, (void *) "slimslave_poke", &codec_debug_ops); debugfs_power_state = debugfs_create_file("power_state", - S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent, + S_IFREG | S_IRUSR, debugfs_wcd9xxx_dent, (void *) "power_state", &codec_debug_ops); debugfs_reg_dump = debugfs_create_file("slimslave_reg_dump", - S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent, + S_IFREG | S_IRUSR, debugfs_wcd9xxx_dent, (void *) "slimslave_reg_dump", &codec_debug_ops); } #endif diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c index a5e17991f122e69f292b7313ce5cc864fa9e10cb..f0769c456055a501c783fed31d3f84b5bee6e184 100644 --- a/drivers/soc/qcom/spcom.c +++ b/drivers/soc/qcom/spcom.c @@ -236,7 +236,7 @@ struct spcom_device { int channel_count; /* private */ - struct mutex lock; + struct mutex cmd_lock; /* Link state */ struct completion link_state_changed; @@ -1634,6 +1634,8 @@ static int spcom_handle_write(struct spcom_channel *ch, swap_id = htonl(cmd->cmd_id); memcpy(cmd_name, &swap_id, sizeof(int)); + mutex_lock(&spcom_dev->cmd_lock); + pr_debug("cmd_id [0x%x] cmd_name [%s].\n", cmd_id, cmd_name); switch (cmd_id) { @@ -1657,9 +1659,11 @@ static int spcom_handle_write(struct spcom_channel *ch, break; default: pr_err("Invalid Command Id [0x%x].\n", (int) cmd->cmd_id); - return -EINVAL; + ret = -EINVAL; } + mutex_unlock(&spcom_dev->cmd_lock); + return ret; } @@ -2310,7 +2314,7 @@ static int spcom_probe(struct platform_device *pdev) return -ENOMEM; spcom_dev = dev; - mutex_init(&dev->lock); + mutex_init(&spcom_dev->cmd_lock); init_completion(&dev->link_state_changed); spcom_dev->link_state = GLINK_LINK_STATE_DOWN; diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 63f43c21c187b583a8cff0892cce7c4367e91fb5..ea356c961b425d0468419a6b820468fa181d7091 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -758,10 +758,12 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; case ASHMEM_SET_SIZE: ret = -EINVAL; + mutex_lock(&ashmem_mutex); if (!asma->file) { ret = 0; asma->size = (size_t) arg; } + mutex_unlock(&ashmem_mutex); break; case ASHMEM_GET_SIZE: ret = asma->size; diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c index 5c296e56d9990624e52bfe5ef2327c0fd33b5dcd..4d65c27f295b7d13f7879f17d099f23d3abc9464 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_main.c @@ -1317,7 +1317,7 @@ static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable) return 0; } - sscanf(inPtr, "%32s ", buf); + sscanf(inPtr, "%31s ", buf); v = kstrtos32(buf, 10, &tempInt); if ( v < 0) { @@ -1361,7 +1361,7 @@ static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue, return 0; } - sscanf(inPtr, "%32s ", buf); + sscanf(inPtr, "%31s ", buf); v = kstrtos32(buf, 10, &tempInt); if ( v < 0) { diff --git a/drivers/video/msm/mdss/mdss_mdp_pp_v1_7.c b/drivers/video/msm/mdss/mdss_mdp_pp_v1_7.c index 1e4adc9848022de27b8a6c18ce1c7ff3084cafe9..ff71481b33165894fbec297f99fb1a0a11fbf05b 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp_v1_7.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp_v1_7.c @@ -1946,20 +1946,24 @@ static int pp_pgc_get_config(char __iomem *base_addr, void *cfg_data, u32 *c0_data = NULL, *c1_data = NULL, *c2_data = NULL; u32 val = 0, i = 0, sz = 0; struct mdp_pgc_lut_data *pgc_data = NULL; - struct mdp_pgc_lut_data_v1_7 *pgc_data_v17 = NULL; + struct mdp_pgc_lut_data_v1_7 pgc_lut_data_v17; + struct mdp_pgc_lut_data_v1_7 *pgc_data_v17 = &pgc_lut_data_v17; if (!base_addr || !cfg_data) { pr_err("invalid params base_addr %pK cfg_data %pK block_type %d\n", base_addr, cfg_data, block_type); return -EINVAL; } pgc_data = (struct mdp_pgc_lut_data *) cfg_data; - pgc_data_v17 = (struct mdp_pgc_lut_data_v1_7 *) - pgc_data->cfg_payload; - if (pgc_data->version != mdp_pgc_v1_7 || !pgc_data_v17) { + if (pgc_data->version != mdp_pgc_v1_7 || !pgc_data->cfg_payload) { pr_err("invalid pgc version %d payload %pK\n", - pgc_data->version, pgc_data_v17); + pgc_data->version, pgc_data->cfg_payload); return -EINVAL; } + if (copy_from_user(pgc_data_v17, (void __user *) pgc_data->cfg_payload, + sizeof(*pgc_data_v17))) { + pr_err("copy from user failed for pgc lut data\n"); + return -EFAULT; + } if (!(pgc_data->flags & MDP_PP_OPS_READ)) { pr_info("read ops is not set %d", pgc_data->flags); return -EINVAL; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6a25aa14d0673b6d1bbd38424e7b927f0689e02a..32a43e2f60989cff31e01ac1f37e0d11a4cacb6b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4731,16 +4731,19 @@ find_min_capacity(struct energy_env *eenv) static int find_new_capacity(struct energy_env *eenv) { const struct sched_group_energy const *sge = eenv->sg->sge; + int idx, max_idx = sge->nr_cap_states - 1; unsigned long util = group_max_util(eenv); - int idx; + + /* default is max_cap if we don't find a match */ + eenv->cap_idx = max_idx; for (idx = 0; idx < sge->nr_cap_states; idx++) { - if (sge->cap_states[idx].cap >= util) + if (sge->cap_states[idx].cap >= util) { + /* Keep track of SG's capacity index */ + eenv->cap_idx = idx; break; + } } - /* Keep track of SG's capacity index */ - eenv->cap_idx = idx; - /* Update SG's capacity based on boost value of the current task */ eenv->cap_idx = find_min_capacity(eenv);