diff --git a/arch/arm/boot/dts/qcom/msm8992-camera.dtsi b/arch/arm/boot/dts/qcom/msm8992-camera.dtsi index c5513bac2ecb60a217b1a7ca7dfbba6e4f0189e2..a14a4d803ec8cf6c89ee4f9fa6327b4240be1655 100644 --- a/arch/arm/boot/dts/qcom/msm8992-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msm8992-camera.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2015, 2017 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 @@ -26,6 +26,9 @@ reg-names = "csiphy", "csiphy_clk_mux"; interrupts = <0 78 0>; interrupt-names = "csiphy"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; clocks = <&clock_mmss clk_camss_top_ahb_clk>, <&clock_mmss clk_camss_ispif_ahb_clk>, <&clock_mmss clk_csi0_clk_src>, @@ -48,6 +51,9 @@ reg-names = "csiphy", "csiphy_clk_mux"; interrupts = <0 79 0>; interrupt-names = "csiphy"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; clocks = <&clock_mmss clk_camss_top_ahb_clk>, <&clock_mmss clk_camss_ispif_ahb_clk>, <&clock_mmss clk_csi1_clk_src>, @@ -70,6 +76,9 @@ reg-names = "csiphy", "csiphy_clk_mux"; interrupts = <0 80 0>; interrupt-names = "csiphy"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; clocks = <&clock_mmss clk_camss_top_ahb_clk>, <&clock_mmss clk_camss_ispif_ahb_clk>, <&clock_mmss clk_csi2_clk_src>, diff --git a/arch/arm/boot/dts/qcom/msm8994-camera.dtsi b/arch/arm/boot/dts/qcom/msm8994-camera.dtsi index 1239c7277001cb426a06da61f930d579fdb187cd..8c1f58d6c67bc47cbc138a15cd0883d45c21d717 100644 --- a/arch/arm/boot/dts/qcom/msm8994-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msm8994-camera.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2015, 2017 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 @@ -26,6 +26,9 @@ reg-names = "csiphy", "csiphy_clk_mux"; interrupts = <0 78 0>; interrupt-names = "csiphy"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; clocks = <&clock_mmss clk_camss_top_ahb_clk>, <&clock_mmss clk_camss_ispif_ahb_clk>, <&clock_mmss clk_csi0_clk_src>, @@ -48,6 +51,9 @@ reg-names = "csiphy", "csiphy_clk_mux"; interrupts = <0 79 0>; interrupt-names = "csiphy"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; clocks = <&clock_mmss clk_camss_top_ahb_clk>, <&clock_mmss clk_camss_ispif_ahb_clk>, <&clock_mmss clk_csi1_clk_src>, @@ -70,6 +76,9 @@ reg-names = "csiphy", "csiphy_clk_mux"; interrupts = <0 80 0>; interrupt-names = "csiphy"; + qcom,csi-vdd-voltage = <1250000>; + qcom,mipi-csi-vdd-supply = <&pm8994_l2>; + qcom,gdscr-vdd-supply = <&gdsc_camss_top>; clocks = <&clock_mmss clk_camss_top_ahb_clk>, <&clock_mmss clk_camss_ispif_ahb_clk>, <&clock_mmss clk_csi2_clk_src>, diff --git a/arch/arm64/configs/bullhead_defconfig b/arch/arm64/configs/bullhead_defconfig index 129c135d980c379249a6f71f3f54405b6738e124..0ae9ab042d3adc7938345f0d2b4991d2095a92ad 100644 --- a/arch/arm64/configs/bullhead_defconfig +++ b/arch/arm64/configs/bullhead_defconfig @@ -314,6 +314,7 @@ CONFIG_SERIAL_MSM_HSL=y CONFIG_SERIAL_MSM_HSL_CONSOLE=y CONFIG_SERIAL_MSM_SMD=y CONFIG_HW_RANDOM_MSM=y +# CONFIG_DEVPORT is not set CONFIG_MSM_SMD_PKT=y CONFIG_MSM_ADSPRPC=y CONFIG_I2C=y diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 4e9262a1b7c05b9e0c21a41d25c2b6632f66eecf..5d93ca305cf8b9925c649d9b6c2e107f8d144e60 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -594,10 +594,12 @@ config TELCLOCK controlling the behavior of this hardware. config DEVPORT - bool - depends on !M68K + bool "/dev/port character device" depends on ISA || PCI default y + help + Say Y here if you want to support the /dev/port device. The + /dev/port device is similar to /dev/mem, but for I/O ports. source "drivers/s390/char/Kconfig" diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 4383e77776163be066cb7704dc7bdc6c0e7f71b7..dbca5c79b8b175a1856be4648cc23891446fe4b3 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2017, 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 @@ -209,8 +209,11 @@ kgsl_mem_entry_create(void) { struct kgsl_mem_entry *entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (entry) + if (entry) { kref_init(&entry->refcount); + /* put this ref in the caller functions after init */ + kref_get(&entry->refcount); + } return entry; } @@ -3269,6 +3272,9 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv, trace_kgsl_mem_map(entry, param->fd); kgsl_mem_entry_commit_process(private, entry); + + /* put the extra refcount for kgsl_mem_entry_create() */ + kgsl_mem_entry_put(entry); return result; error_attach: @@ -3625,6 +3631,9 @@ long kgsl_ioctl_gpumem_alloc(struct kgsl_device_private *dev_priv, param->flags = entry->memdesc.flags; kgsl_mem_entry_commit_process(private, entry); + + /* put the extra refcount for kgsl_mem_entry_create() */ + kgsl_mem_entry_put(entry); return result; err: kgsl_sharedmem_free(&entry->memdesc); @@ -3672,6 +3681,9 @@ long kgsl_ioctl_gpumem_alloc_id(struct kgsl_device_private *dev_priv, param->gpuaddr = entry->memdesc.gpuaddr; kgsl_mem_entry_commit_process(private, entry); + + /* put the extra refcount for kgsl_mem_entry_create() */ + kgsl_mem_entry_put(entry); return result; err: if (entry) diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 2f1ddca6f2e0a3a4712bce434d5b29e1556e216c..700145b1508894f30a018aef278d15cfc458ef3a 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -516,13 +516,13 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, goto inval; } else if (uref->usage_index >= field->report_count) goto inval; - - else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) && - (uref_multi->num_values > HID_MAX_MULTI_USAGES || - uref->usage_index + uref_multi->num_values > field->report_count)) - goto inval; } + if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) && + (uref_multi->num_values > HID_MAX_MULTI_USAGES || + uref->usage_index + uref_multi->num_values > field->report_count)) + goto inval; + switch (cmd) { case HIDIOCGUSAGE: uref->value = field->value[uref->usage_index]; diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index fb1f93cd4c0bcd02ffdaa8e1d36ddb011407c412..6f5334abccc9d4cd72bea25f340f6f804355d64c 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -64,7 +64,7 @@ static void msm_ispif_io_dump_reg(struct ispif_device *ispif) static inline int msm_ispif_is_intf_valid(uint32_t csid_version, - uint8_t intf_type) + enum msm_ispif_vfe_intf intf_type) { return ((csid_version <= CSID_VERSION_V22 && intf_type != VFE0) || (intf_type >= VFE_MAX)) ? false : true; @@ -347,7 +347,7 @@ static int msm_ispif_subdev_g_chip_ident(struct v4l2_subdev *sd, } static void msm_ispif_sel_csid_core(struct ispif_device *ispif, - uint8_t intftype, uint8_t csid, uint8_t vfe_intf) + uint8_t intftype, uint8_t csid, enum msm_ispif_vfe_intf vfe_intf) { uint32_t data; @@ -387,8 +387,8 @@ static void msm_ispif_sel_csid_core(struct ispif_device *ispif, } static void msm_ispif_enable_crop(struct ispif_device *ispif, - uint8_t intftype, uint8_t vfe_intf, uint16_t start_pixel, - uint16_t end_pixel) + uint8_t intftype, enum msm_ispif_vfe_intf vfe_intf, + uint16_t start_pixel, uint16_t end_pixel) { uint32_t data; BUG_ON(!ispif); @@ -419,7 +419,8 @@ static void msm_ispif_enable_crop(struct ispif_device *ispif, } static void msm_ispif_enable_intf_cids(struct ispif_device *ispif, - uint8_t intftype, uint16_t cid_mask, uint8_t vfe_intf, uint8_t enable) + uint8_t intftype, uint16_t cid_mask, enum msm_ispif_vfe_intf vfe_intf, + uint8_t enable) { uint32_t intf_addr, data; @@ -461,7 +462,7 @@ static void msm_ispif_enable_intf_cids(struct ispif_device *ispif, } static int msm_ispif_validate_intf_status(struct ispif_device *ispif, - uint8_t intftype, uint8_t vfe_intf) + uint8_t intftype, enum msm_ispif_vfe_intf vfe_intf) { int rc = 0; uint32_t data = 0; @@ -501,7 +502,7 @@ static int msm_ispif_validate_intf_status(struct ispif_device *ispif, } static void msm_ispif_select_clk_mux(struct ispif_device *ispif, - uint8_t intftype, uint8_t csid, uint8_t vfe_intf) + uint8_t intftype, uint8_t csid, enum msm_ispif_vfe_intf vfe_intf) { uint32_t data = 0; diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index 11755c3f015f922ea07607b7c0603dfb1b5eaf8a..c396434fdccdc3636684d9512a665ebf8fc8c888 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -1893,9 +1893,29 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev, return -EINVAL; } - if (stripe_base == UINT_MAX || new_frame->num_strips > - (UINT_MAX - 1 - stripe_base) / stripe_size) { - pr_err("Invalid frame message,num_strips %d is large\n", + /* Stripe index starts at zero */ + if ((!new_frame->num_strips) || + (new_frame->first_stripe_index >= new_frame->num_strips) || + (new_frame->last_stripe_index >= new_frame->num_strips) || + (new_frame->first_stripe_index > + new_frame->last_stripe_index)) { + pr_err("Invalid frame message, #stripes=%d, stripe indices=[%d,%d]\n", + new_frame->num_strips, + new_frame->first_stripe_index, + new_frame->last_stripe_index); + return -EINVAL; + } + + if (!stripe_size) { + pr_err("Invalid frame message, invalid stripe_size (%d)!\n", + stripe_size); + return -EINVAL; + } + + if ((stripe_base == UINT_MAX) || + (new_frame->num_strips > + (UINT_MAX - 1 - stripe_base) / stripe_size)) { + pr_err("Invalid frame message, num_strips %d is large\n", new_frame->num_strips); return -EINVAL; } @@ -2164,9 +2184,12 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev, struct msm_camera_v4l2_ioctl_t *ioctl_ptr) { struct msm_cpp_frame_info_t *frame = NULL; - struct msm_cpp_frame_info_t *u_frame_info = - (struct msm_cpp_frame_info_t *)ioctl_ptr->ioctl_ptr; + struct msm_cpp_frame_info_t k_frame_info; int32_t rc = 0; + if (copy_from_user(&k_frame_info, + (void __user *)ioctl_ptr->ioctl_ptr, + sizeof(k_frame_info))) + return -EFAULT; frame = msm_cpp_get_frame(ioctl_ptr); if (!frame) { @@ -2178,7 +2201,7 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev, ioctl_ptr->trans_code = rc; - if (copy_to_user((void __user *)u_frame_info->status, &rc, + if (copy_to_user((void __user *)k_frame_info.status, &rc, sizeof(int32_t))) pr_err("error cannot copy error\n"); diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c index 0d472ea9aea3a00287044f3251130e2677582513..21e594ee57505aadda8985493bf93369c76b6dbf 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c @@ -359,10 +359,18 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd, enum cci_i2c_queue_t queue = QUEUE_1; struct cci_device *cci_dev = NULL; struct msm_camera_cci_i2c_read_cfg *read_cfg = NULL; + CDBG("%s line %d\n", __func__, __LINE__); cci_dev = v4l2_get_subdevdata(sd); master = c_ctrl->cci_info->cci_i2c_master; read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg; + + if (master >= MASTER_MAX || master < 0) { + pr_err("%s:%d Invalid I2C master %d\n", + __func__, __LINE__, master); + return -EINVAL; + } + mutex_lock(&cci_dev->cci_master_info[master].mutex); /* diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c index 9afa68fa17b15749fee76f616631e0cddf642053..2c17cca53a8034fb540fe89c5d1740bb8272523a 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c +++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2017 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 @@ -37,6 +37,10 @@ #define CLK_LANE_OFFSET 1 #define NUM_LANES_OFFSET 4 +static struct camera_vreg_t csiphy_vreg_info[] = { + {"qcom,mipi-csi-vdd", 0, 0, 12000}, +}; + #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) @@ -308,6 +312,35 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev) } CDBG("%s:%d called\n", __func__, __LINE__); + rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 1); + if (rc < 0) { + pr_err("%s: regulator config failed\n", __func__); + goto csiphy_vreg_config_fail; + } + rc = msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 1); + if (rc < 0) { + pr_err("%s: regulator enable failed\n", __func__); + goto csiphy_vreg_enable_fail; + } + + csiphy_dev->reg_ptr = regulator_get(&(csiphy_dev->pdev->dev), + "qcom,gdscr-vdd"); + if (IS_ERR_OR_NULL(csiphy_dev->reg_ptr)) { + pr_err(" %s: Failed in getting TOP gdscr regulator handle", + __func__); + } else { + rc = regulator_enable(csiphy_dev->reg_ptr); + if (rc) { + pr_err(" %s: regulator enable failed for GDSCR\n", + __func__); + goto csiphy_enable_regulator_gdscr_fail; + } + } + if (csiphy_dev->hw_dts_version < CSIPHY_VERSION_V30) { rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev, csiphy_clk_info, csiphy_dev->csiphy_clk, @@ -368,6 +401,20 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev) csiphy_dev->hw_version); csiphy_dev->csiphy_state = CSIPHY_POWER_UP; return 0; + +csiphy_enable_regulator_gdscr_fail: + rc = msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 0); +csiphy_vreg_enable_fail: + rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 0); +csiphy_vreg_config_fail: + iounmap(csiphy_dev->base); + csiphy_dev->base = NULL; + return rc; + } #else static int msm_csiphy_init(struct csiphy_device *csiphy_dev) @@ -403,6 +450,36 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev) rc = -ENOMEM; return rc; } + + rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 1); + if (rc < 0) { + pr_err("%s: regulator config failed\n", __func__); + goto csiphy_vreg_config_fail; + } + rc = msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 1); + if (rc < 0) { + pr_err("%s: regulator enable failed\n", __func__); + goto csiphy_vreg_enable_fail; + } + + csiphy_dev->reg_ptr = regulator_get(&(csiphy_dev->pdev->dev), + "qcom,gdscr-vdd"); + if (IS_ERR_OR_NULL(csiphy_dev->reg_ptr)) { + pr_err(" %s: Failed in getting TOP gdscr regulator handle", + __func__); + } else { + rc = regulator_enable(csiphy_dev->reg_ptr); + if (rc) { + pr_err(" %s: regulator enable failed for GDSCR\n", + __func__); + goto csiphy_enable_regulator_gdscr_fail; + } + } + if (csiphy_dev->hw_dts_version <= CSIPHY_VERSION_V22) { CDBG("%s:%d called\n", __func__, __LINE__); rc = msm_cam_clk_enable(&csiphy_dev->pdev->dev, @@ -461,6 +538,19 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev) csiphy_dev->hw_version); csiphy_dev->csiphy_state = CSIPHY_POWER_UP; return 0; + +csiphy_enable_regulator_gdscr_fail: + rc = msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 0); +csiphy_vreg_enable_fail: + rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 0); +csiphy_vreg_config_fail: + iounmap(csiphy_dev->base); + csiphy_dev->base = NULL; + return rc; } #endif @@ -548,6 +638,19 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg) csiphy_dev->num_clk, 0); iounmap(csiphy_dev->clk_mux_base); } + + msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 0); + msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 0); + + if (!IS_ERR_OR_NULL(csiphy_dev->reg_ptr)) { + regulator_disable(csiphy_dev->reg_ptr); + regulator_put(csiphy_dev->reg_ptr); + } + iounmap(csiphy_dev->base); csiphy_dev->base = NULL; csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN; @@ -636,6 +739,18 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg) iounmap(csiphy_dev->clk_mux_base); } + msm_camera_enable_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 0); + msm_camera_config_vreg(&csiphy_dev->pdev->dev, + csiphy_vreg_info, ARRAY_SIZE(csiphy_vreg_info), + NULL, 0, &csiphy_dev->csi_vdd, 0); + + if (!IS_ERR_OR_NULL(csiphy_dev->reg_ptr)) { + regulator_disable(csiphy_dev->reg_ptr); + regulator_put(csiphy_dev->reg_ptr); + } + iounmap(csiphy_dev->base); csiphy_dev->base = NULL; csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN; @@ -825,6 +940,7 @@ static int msm_csiphy_get_clk_info(struct csiphy_device *csiphy_dev, static int csiphy_probe(struct platform_device *pdev) { struct csiphy_device *new_csiphy_dev; + uint32_t csi_vdd_voltage = 0; int rc = 0; new_csiphy_dev = kzalloc(sizeof(struct csiphy_device), GFP_KERNEL); @@ -858,6 +974,19 @@ static int csiphy_probe(struct platform_device *pdev) return -EFAULT; } + rc = of_property_read_u32((&pdev->dev)->of_node, + "qcom,csi-vdd-voltage", &csi_vdd_voltage); + if (rc < 0) { + pr_err("%s:%d failed to read qcom,csi-vdd-voltage\n", + __func__, __LINE__); + return rc; + } + CDBG("%s:%d reading mipi_csi_vdd is %d\n", __func__, __LINE__, + csi_vdd_voltage); + + csiphy_vreg_info[0].min_voltage = csi_vdd_voltage; + csiphy_vreg_info[0].max_voltage = csi_vdd_voltage; + new_csiphy_dev->mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csiphy"); if (!new_csiphy_dev->mem) { diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h index 174afe1d7a3462a2a7381a88f78b06feb72b08ce..8ff3bfee96eddb169edaafc06501b2ca02381ce4 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h +++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2017 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 @@ -84,6 +84,8 @@ struct csiphy_device { uint32_t is_3_1_20nm_hw; uint32_t csiphy_clk_index; uint32_t csiphy_max_clk; + struct regulator *csi_vdd; + struct regulator *reg_ptr; }; #define VIDIOC_MSM_CSIPHY_RELEASE \ diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h index 931f2407cd2e7b5e067a7c3d8c4287304e786ef8..32833a93da74d444be815a7e589ed56283a2424b 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h @@ -43,6 +43,7 @@ #define DEFAULT_WIDTH 1920 #define MIN_SUPPORTED_WIDTH 32 #define MIN_SUPPORTED_HEIGHT 32 +#define MAX_SUPPORTED_INSTANCES_COUNT 16 /* Maintains the number of FTB's between each FBD over a window */ #define DCVS_FTB_WINDOW 32 diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 39261a10d991c1a29f72c80bc218643faf9e1598..f19bb5460c9b490121a15ff55f197b20fe79455b 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -926,16 +926,15 @@ static int venus_hfi_vote_active_buses(void *dev, } else if (!data) { dprintk(VIDC_ERR, "Invalid voting data\n"); return -EINVAL; + } else if (num_data > MAX_SUPPORTED_INSTANCES_COUNT) { + dprintk(VIDC_ERR, "Invalid number of instances.\n"); + return -EINVAL; } - /* (Re-)alloc memory to store the new votes (in case we internally - * re-vote after power collapse, which is transparent to client) */ - cached_vote_data = krealloc(device->bus_load.vote_data, num_data * - sizeof(*cached_vote_data), GFP_KERNEL); + cached_vote_data = device->bus_load.vote_data; if (!cached_vote_data) { - dprintk(VIDC_ERR, "Can't alloc memory to cache bus votes\n"); - rc = -ENOMEM; - goto err_no_mem; + dprintk(VIDC_ERR, "Invalid bus load vote data\n"); + return -EINVAL; } /* Alloc & init the load table */ @@ -3739,9 +3738,16 @@ static int venus_hfi_init_bus(struct venus_hfi_device *device) dprintk(VIDC_DBG, "Registered bus client %s\n", name); } - device->bus_load.vote_data = NULL; - device->bus_load.vote_data_count = 0; + device->bus_load.vote_data = (struct vidc_bus_vote_data *) + kzalloc(sizeof(struct vidc_bus_vote_data) * + MAX_SUPPORTED_INSTANCES_COUNT, GFP_KERNEL); + if (device->bus_load.vote_data == NULL) { + dprintk(VIDC_ERR, "Failed to allocate memory for vote_data\n"); + rc = -ENOMEM; + goto err_init_bus; + } + device->bus_load.vote_data_count = 0; return rc; err_init_bus: venus_hfi_deinit_bus(device); diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index eb81c98386b9d59a0bde9f828ee141b0c884bd2d..721d839d6c543c63b16797f015fe90dbe3ddf3d3 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1694,6 +1694,9 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd) md->from_user = 0; } + if (unlikely(iov_count > UIO_MAXIOV)) + return -EINVAL; + if (iov_count) { int len, size = sizeof(struct sg_iovec) * iov_count; struct iovec *iov; diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c index ea6e6b629aa0a20f65943586616ff6cc4ac3dc77..b7ce7787513ffafbe91e9111ba300207222abfde 100644 --- a/drivers/soc/qcom/pil-msa.c +++ b/drivers/soc/qcom/pil-msa.c @@ -469,15 +469,24 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) dev_info(pil->dev, "MBA: loading from %pa to %pa\n", &mba_phys, &mba_phys_end); - /* Load the MBA image into memory */ data = fw ? fw->data : NULL; if (!data) { dev_err(pil->dev, "MBA data is NULL\n"); ret = -ENOMEM; goto err_mss_reset; } + /* Load the MBA image into memory */ count = fw->size; + + if (count > SZ_1M) { + dev_err(pil->dev, "%s fw image loading into memory is failed due to fw size overflow\n", + __func__); + ret = -EINVAL; + goto err_mss_reset; + } + memcpy(mba_virt, data, count); + /* Ensure memcpy of the MBA memory is done before loading the DP */ wmb(); ret = pil_mss_reset(pil); diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index ee79ac8d90d645fd5b636c3aedf9d9d78d89ce8d..f13aab21da4a2533f7b7e534fa5f0000154e1d80 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -32,7 +32,6 @@ #include <linux/mutex.h> #include <linux/shmem_fs.h> #include <linux/ashmem.h> -#include <asm/cacheflush.h> #include "ashmem.h" @@ -659,37 +658,6 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, return ret; } -static int ashmem_cache_op(struct ashmem_area *asma, - void (*cache_func)(const void *vstart, const void *vend)) -{ - int ret = 0; - struct vm_area_struct *vma; - if (!asma->vm_start) - return -EINVAL; - - down_read(¤t->mm->mmap_sem); - vma = find_vma(current->mm, asma->vm_start); - if (!vma) { - ret = -EINVAL; - goto done; - } - if (vma->vm_file != asma->file) { - ret = -EINVAL; - goto done; - } - if ((asma->vm_start + asma->size) > vma->vm_end) { - ret = -EINVAL; - goto done; - } - cache_func((void *)asma->vm_start, - (void *)(asma->vm_start + asma->size)); -done: - up_read(¤t->mm->mmap_sem); - if (ret) - asma->vm_start = 0; - return ret; -} - static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct ashmem_area *asma = file->private_data; @@ -735,15 +703,6 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ashmem_shrink(&ashmem_shrinker, &sc); } break; - case ASHMEM_CACHE_FLUSH_RANGE: - ret = ashmem_cache_op(asma, &dmac_flush_range); - break; - case ASHMEM_CACHE_CLEAN_RANGE: - ret = ashmem_cache_op(asma, &dmac_clean_range); - break; - case ASHMEM_CACHE_INV_RANGE: - ret = ashmem_cache_op(asma, &dmac_inv_range); - break; } return ret; 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 1319c401c0b564fa01679cd2a0a9311a9fd8b414..2a2988556c0fcc4d372c0ae2ebdec2dd974632af 100755 --- 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 @@ -4598,6 +4598,8 @@ static int hdd_set_rx_filter(hdd_adapter_t *adapter, bool action, MAC_ADDR_ARRAY(filter->multicastAddr[j])); j++; } + if (j == SIR_MAX_NUM_MULTICAST_ADDRESS) + break; } filter->ulMulticastAddrCnt = j; /* Set rx filter */ diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c index 668922d70f69a841bbed42429637ed68b335a629..173ed4e8eec1a477f339b33cdbba204a8a35f84c 100644 --- a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c +++ b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c @@ -548,10 +548,12 @@ static void pktlog_detach(struct ol_softc *scn) pl_info = pl_dev->pl_info; remove_proc_entry(WLANDEV_BASENAME, g_pktlog_pde); pktlog_sysctl_unregister(pl_dev); - pktlog_cleanup(pl_info); + spin_lock_bh(&pl_info->log_lock); if (pl_info->buf) pktlog_release_buf(scn); + spin_unlock_bh(&pl_info->log_lock); + pktlog_cleanup(pl_info); if (pl_dev) { kfree(pl_info); @@ -601,12 +603,16 @@ pktlog_read_proc_entry(char *buf, size_t nbytes, loff_t *ppos, int rem_len; int start_offset, end_offset; int fold_offset, ppos_data, cur_rd_offset, cur_wr_offset; - struct ath_pktlog_buf *log_buf = pl_info->buf; + struct ath_pktlog_buf *log_buf; + + spin_lock_bh(&pl_info->log_lock); + log_buf = pl_info->buf; *read_complete = false; if (log_buf == NULL) { *read_complete = true; + spin_unlock_bh(&pl_info->log_lock); return 0; } @@ -709,7 +715,6 @@ rd_done: *ppos += ret_val; if (ret_val == 0) { - PKTLOG_LOCK(pl_info); /* Write pointer might have been updated during the read. * So, if some data is written into, lets not reset the pointers. * We can continue to read from the offset position @@ -723,9 +728,8 @@ rd_done: pl_info->buf->offset = PKTLOG_READ_OFFSET; *read_complete = true; } - PKTLOG_UNLOCK(pl_info); } - + spin_unlock_bh(&pl_info->log_lock); return ret_val; } @@ -745,10 +749,15 @@ pktlog_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) struct ath_pktlog_info *pl_info = (struct ath_pktlog_info *) proc_entry->data; #endif - struct ath_pktlog_buf *log_buf = pl_info->buf; + struct ath_pktlog_buf *log_buf; - if (log_buf == NULL) + spin_lock_bh(&pl_info->log_lock); + log_buf = pl_info->buf; + + if (log_buf == NULL) { + spin_unlock_bh(&pl_info->log_lock); return 0; + } if (*ppos == 0 && pl_info->log_state) { pl_info->saved_state = pl_info->log_state; @@ -763,11 +772,13 @@ pktlog_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) if (*ppos < bufhdr_size) { count = MIN((bufhdr_size - *ppos), rem_len); + spin_unlock_bh(&pl_info->log_lock); if (copy_to_user(buf, ((char *)&log_buf->bufhdr) + *ppos, count)) return -EFAULT; rem_len -= count; ret_val += count; + spin_lock_bh(&pl_info->log_lock); } start_offset = log_buf->rd_offset; @@ -809,21 +820,25 @@ pktlog_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) goto rd_done; count = MIN(rem_len, (end_offset - ppos_data + 1)); + spin_unlock_bh(&pl_info->log_lock); if (copy_to_user(buf + ret_val, log_buf->log_data + ppos_data, count)) return -EFAULT; ret_val += count; rem_len -= count; + spin_lock_bh(&pl_info->log_lock); } else { if (ppos_data <= fold_offset) { count = MIN(rem_len, (fold_offset - ppos_data + 1)); + spin_unlock_bh(&pl_info->log_lock); if (copy_to_user(buf + ret_val, log_buf->log_data + ppos_data, count)) return -EFAULT; ret_val += count; rem_len -= count; + spin_lock_bh(&pl_info->log_lock); } if (rem_len == 0) @@ -835,12 +850,14 @@ pktlog_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) if (ppos_data <= end_offset) { count = MIN(rem_len, (end_offset - ppos_data + 1)); + spin_unlock_bh(&pl_info->log_lock); if (copy_to_user(buf + ret_val, log_buf->log_data + ppos_data, count)) return -EFAULT; ret_val += count; rem_len -= count; + spin_lock_bh(&pl_info->log_lock); } } @@ -851,6 +868,7 @@ rd_done: } *ppos += ret_val; + spin_unlock_bh(&pl_info->log_lock); return ret_val; } diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_ac.c b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_ac.c index 3bc0ae1f422236032833ac748b8549d2d8bfa0de..3d38ca44617d6013f5ca402d09cce93102136d29 100644 --- a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_ac.c +++ b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/pktlog_ac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -349,6 +349,7 @@ pktlog_enable(struct ol_softc *scn, int32_t log_state) } } + spin_lock_bh(&pl_info->log_lock); pl_info->buf->bufhdr.version = CUR_PKTLOG_VER; pl_info->buf->bufhdr.magic_num = PKTLOG_MAGIC_NUM; pl_info->buf->wr_offset = 0; @@ -357,6 +358,7 @@ pktlog_enable(struct ol_softc *scn, int32_t log_state) pl_info->buf->bytes_written = 0; pl_info->buf->msg_index = 1; pl_info->buf->offset = PKTLOG_READ_OFFSET; + spin_unlock_bh(&pl_info->log_lock); pl_info->start_time_thruput = OS_GET_TIMESTAMP(); pl_info->start_time_per = pl_info->start_time_thruput; @@ -404,11 +406,13 @@ pktlog_setsize(struct ol_softc *scn, int32_t size) return -EINVAL; } + spin_lock_bh(&pl_info->log_lock); if (pl_info->buf != NULL) pktlog_release_buf(scn); if (size != 0) pl_info->buf_size = size; + spin_unlock_bh(&pl_info->log_lock); return 0; } diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index 759ed14339f1959350b3268adc9cba908318ad46..81b994065a65a00b89fa40fe9748574fe500d06b 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2009-2017, 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 @@ -38,6 +38,8 @@ #define PANEL_CMD_MIN_TX_COUNT 2 #define PANEL_DATA_NODE_LEN 80 +static DEFINE_MUTEX(mdss_debug_lock); + static char panel_reg[2] = {DEFAULT_READ_PANEL_POWER_MODE_REG, 0x00}; static int panel_debug_base_open(struct inode *inode, struct file *file) @@ -51,11 +53,13 @@ static int panel_debug_base_open(struct inode *inode, struct file *file) static int panel_debug_base_release(struct inode *inode, struct file *file) { struct mdss_debug_base *dbg = file->private_data; + mutex_lock(&mdss_debug_lock); if (dbg && dbg->buf) { kfree(dbg->buf); dbg->buf_len = 0; dbg->buf = NULL; } + mutex_unlock(&mdss_debug_lock); return 0; } @@ -87,8 +91,10 @@ static ssize_t panel_debug_base_offset_write(struct file *file, if (cnt > (dbg->max_offset - off)) cnt = dbg->max_offset - off; + mutex_lock(&mdss_debug_lock); dbg->off = off; dbg->cnt = cnt; + mutex_unlock(&mdss_debug_lock); pr_debug("offset=%x cnt=%x\n", off, cnt); @@ -108,15 +114,21 @@ static ssize_t panel_debug_base_offset_read(struct file *file, if (*ppos) return 0; /* the end */ + mutex_lock(&mdss_debug_lock); len = snprintf(buf, sizeof(buf), "0x%02zx %zx\n", dbg->off, dbg->cnt); - if (len < 0 || len >= sizeof(buf)) + if (len < 0 || len >= sizeof(buf)) { + mutex_unlock(&mdss_debug_lock); return 0; + } - if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) + if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) { + mutex_unlock(&mdss_debug_lock); return -EFAULT; + } *ppos += len; /* increase offset */ + mutex_unlock(&mdss_debug_lock); return len; } @@ -207,8 +219,16 @@ static ssize_t panel_debug_base_reg_read(struct file *file, if (!dbg) return -ENODEV; - if (*ppos) + mutex_lock(&mdss_debug_lock); + if (!dbg->cnt) { + mutex_unlock(&mdss_debug_lock); + return 0; + } + + if (*ppos) { + mutex_unlock(&mdss_debug_lock); return 0; /* the end */ + } if (mdata->debug_inf.debug_enable_clock) mdata->debug_inf.debug_enable_clock(1); @@ -233,14 +253,19 @@ static ssize_t panel_debug_base_reg_read(struct file *file, if (mdata->debug_inf.debug_enable_clock) mdata->debug_inf.debug_enable_clock(0); - if (len < 0 || len >= sizeof(to_user_buf)) + if (len < 0 || len >= sizeof(to_user_buf)) { + mutex_unlock(&mdss_debug_lock); return 0; + } if ((count < sizeof(to_user_buf)) - || copy_to_user(user_buf, to_user_buf, len)) + || copy_to_user(user_buf, to_user_buf, len)) { + mutex_unlock(&mdss_debug_lock); return -EFAULT; + } *ppos += len; /* increase offset */ + mutex_unlock(&mdss_debug_lock); return len; } @@ -323,11 +348,13 @@ static int mdss_debug_base_open(struct inode *inode, struct file *file) static int mdss_debug_base_release(struct inode *inode, struct file *file) { struct mdss_debug_base *dbg = file->private_data; + mutex_lock(&mdss_debug_lock); if (dbg && dbg->buf) { kfree(dbg->buf); dbg->buf_len = 0; dbg->buf = NULL; } + mutex_unlock(&mdss_debug_lock); return 0; } @@ -358,8 +385,10 @@ static ssize_t mdss_debug_base_offset_write(struct file *file, if (cnt > (dbg->max_offset - off)) cnt = dbg->max_offset - off; + mutex_lock(&mdss_debug_lock); dbg->off = off; dbg->cnt = cnt; + mutex_unlock(&mdss_debug_lock); pr_debug("offset=%x cnt=%x\n", off, cnt); @@ -379,15 +408,21 @@ static ssize_t mdss_debug_base_offset_read(struct file *file, if (*ppos) return 0; /* the end */ + mutex_lock(&mdss_debug_lock); len = snprintf(buf, sizeof(buf), "0x%08zx %zx\n", dbg->off, dbg->cnt); - if (len < 0 || len >= sizeof(buf)) + if (len < 0 || len >= sizeof(buf)) { + mutex_unlock(&mdss_debug_lock); return 0; + } - if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) + if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) { + mutex_unlock(&mdss_debug_lock); return -EFAULT; + } *ppos += len; /* increase offset */ + mutex_unlock(&mdss_debug_lock); return len; } @@ -444,6 +479,8 @@ static ssize_t mdss_debug_base_reg_read(struct file *file, return -ENODEV; } + mutex_lock(&mdss_debug_lock); + if (!dbg->buf) { char dump_buf[64]; char *ptr; @@ -455,6 +492,7 @@ static ssize_t mdss_debug_base_reg_read(struct file *file, if (!dbg->buf) { pr_err("not enough memory to hold reg dump\n"); + mutex_unlock(&mdss_debug_lock); return -ENOMEM; } @@ -485,17 +523,21 @@ static ssize_t mdss_debug_base_reg_read(struct file *file, dbg->buf_len = tot; } - if (*ppos >= dbg->buf_len) + if (*ppos >= dbg->buf_len) { + mutex_unlock(&mdss_debug_lock); return 0; /* done reading */ + } len = min(count, dbg->buf_len - (size_t) *ppos); if (copy_to_user(user_buf, dbg->buf + *ppos, len)) { pr_err("failed to copy to user\n"); + mutex_unlock(&mdss_debug_lock); return -EFAULT; } *ppos += len; /* increase offset */ + mutex_unlock(&mdss_debug_lock); return len; } diff --git a/fs/udf/dir.c b/fs/udf/dir.c index b3e93f5e17c367fcfd818a4e7a0a455929baf847..294c10c849225333517810c3f163515fd16b12da 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -163,7 +163,10 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, struct kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation); iblock = udf_get_lb_pblock(dir->i_sb, &tloc, 0); - flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); + flen = udf_get_filename(dir->i_sb, nameptr, lfi, fname, + UDF_NAME_LEN); + if (!flen) + continue; dt_type = DT_UNKNOWN; } diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 102c072c6bbfed3d76541b2c3766d89c9272d2ca..7bb813f25ad4edcadd5149ae166226c4636289b3 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -233,7 +233,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, if (!lfi) continue; - flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); + flen = udf_get_filename(dir->i_sb, nameptr, lfi, fname, + UDF_NAME_LEN); if (flen && udf_match(flen, fname, child->len, child->name)) goto out_ok; } diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index d89f324bc38797220f6afcd09962e63d2c70c1e4..2d0c3720e9afd3b066c8d27752c817b219bf5b04 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c @@ -30,13 +30,16 @@ #include <linux/buffer_head.h> #include "udf_i.h" -static void udf_pc_to_char(struct super_block *sb, unsigned char *from, - int fromlen, unsigned char *to) +static int udf_pc_to_char(struct super_block *sb, unsigned char *from, + int fromlen, unsigned char *to, int tolen) { struct pathComponent *pc; int elen = 0; + int comp_len; unsigned char *p = to; + /* Reserve one byte for terminating \0 */ + tolen--; while (elen < fromlen) { pc = (struct pathComponent *)(from + elen); switch (pc->componentType) { @@ -49,22 +52,37 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from, break; /* Fall through */ case 2: + if (tolen == 0) + return -ENAMETOOLONG; p = to; *p++ = '/'; + tolen--; break; case 3: + if (tolen < 3) + return -ENAMETOOLONG; memcpy(p, "../", 3); p += 3; + tolen -= 3; break; case 4: + if (tolen < 2) + return -ENAMETOOLONG; memcpy(p, "./", 2); p += 2; + tolen -= 2; /* that would be . - just ignore */ break; case 5: - p += udf_get_filename(sb, pc->componentIdent, p, - pc->lengthComponentIdent); + comp_len = udf_get_filename(sb, pc->componentIdent, + pc->lengthComponentIdent, + p, tolen); + p += comp_len; + tolen -= comp_len; + if (tolen == 0) + return -ENAMETOOLONG; *p++ = '/'; + tolen--; break; } elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; @@ -73,6 +91,7 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from, p[-1] = '\0'; else p[0] = '\0'; + return 0; } static int udf_symlink_filler(struct file *file, struct page *page) @@ -108,8 +127,10 @@ static int udf_symlink_filler(struct file *file, struct page *page) symlink = bh->b_data; } - udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); + err = udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p, PAGE_SIZE); brelse(bh); + if (err) + goto out_unlock_inode; up_read(&iinfo->i_data_sem); SetPageUptodate(page); diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index be7dabbbcb49ef171b33e0ec2bc4a672c073282d..55d1d194d4723df0ff4f8a9a984e953d2390717d 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -201,7 +201,8 @@ udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc, } /* unicode.c */ -extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int); +extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *, + int); extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, int); extern int udf_build_ustr(struct ustr *, dstring *, int); diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index 44b815e57f9439116199f91b67489a98272272bc..d29c06fbf4cec196ab271921fce17d7c730d2e3f 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -28,7 +28,8 @@ #include "udf_sb.h" -static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int); +static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *, + int); static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) { @@ -333,8 +334,8 @@ try_again: return u_len + 1; } -int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, - int flen) +int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, + uint8_t *dname, int dlen) { struct ustr *filename, *unifilename; int len = 0; @@ -347,7 +348,7 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, if (!unifilename) goto out1; - if (udf_build_ustr_exact(unifilename, sname, flen)) + if (udf_build_ustr_exact(unifilename, sname, slen)) goto out2; if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { @@ -366,7 +367,8 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, } else goto out2; - len = udf_translate_to_linux(dname, filename->u_name, filename->u_len, + len = udf_translate_to_linux(dname, dlen, + filename->u_name, filename->u_len, unifilename->u_name, unifilename->u_len); out2: kfree(unifilename); @@ -403,10 +405,12 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, #define EXT_MARK '.' #define CRC_MARK '#' #define EXT_SIZE 5 +/* Number of chars we need to store generated CRC to make filename unique */ +#define CRC_LEN 5 -static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, - int udfLen, uint8_t *fidName, - int fidNameLen) +static int udf_translate_to_linux(uint8_t *newName, int newLen, + uint8_t *udfName, int udfLen, + uint8_t *fidName, int fidNameLen) { int index, newIndex = 0, needsCRC = 0; int extIndex = 0, newExtIndex = 0, hasExt = 0; @@ -440,7 +444,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, newExtIndex = newIndex; } } - if (newIndex < 256) + if (newIndex < newLen) newName[newIndex++] = curr; else needsCRC = 1; @@ -468,13 +472,13 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, } ext[localExtIndex++] = curr; } - maxFilenameLen = 250 - localExtIndex; + maxFilenameLen = newLen - CRC_LEN - localExtIndex; if (newIndex > maxFilenameLen) newIndex = maxFilenameLen; else newIndex = newExtIndex; - } else if (newIndex > 250) - newIndex = 250; + } else if (newIndex > newLen - CRC_LEN) + newIndex = newLen - CRC_LEN; newName[newIndex++] = CRC_MARK; valueCRC = crc_itu_t(0, fidName, fidNameLen); newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12]; diff --git a/include/uapi/linux/ashmem.h b/include/uapi/linux/ashmem.h index 5abac76c0e02dc45ca642aa3b458396614ad3389..d14cfe39adeee8a99609d18eb7273b05f9a0f409 100644 --- a/include/uapi/linux/ashmem.h +++ b/include/uapi/linux/ashmem.h @@ -33,8 +33,5 @@ struct ashmem_pin { #define ASHMEM_UNPIN _IOW(__ASHMEMIOC, 8, struct ashmem_pin) #define ASHMEM_GET_PIN_STATUS _IO(__ASHMEMIOC, 9) #define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10) -#define ASHMEM_CACHE_FLUSH_RANGE _IO(__ASHMEMIOC, 11) -#define ASHMEM_CACHE_CLEAN_RANGE _IO(__ASHMEMIOC, 12) -#define ASHMEM_CACHE_INV_RANGE _IO(__ASHMEMIOC, 13) #endif /* _UAPI_LINUX_ASHMEM_H */ diff --git a/kernel/fork.c b/kernel/fork.c index ce5f1b7f8debca7f0dc11714383c6ac6e81a063e..75ff07e1c9917e4e4c32af694d589f87fa873c0a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -732,8 +732,7 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) mm = get_task_mm(task); if (mm && mm != current->mm && - !ptrace_may_access(task, mode) && - !capable(CAP_SYS_RESOURCE)) { + !ptrace_may_access(task, mode)) { mmput(mm); mm = ERR_PTR(-EACCES); } diff --git a/net/dccp/input.c b/net/dccp/input.c index 14cdafad7a90218d91ad135e3703c21401883e05..e511ccc74a0782fa26b8aa9a98de23931485c601 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -606,7 +606,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, if (inet_csk(sk)->icsk_af_ops->conn_request(sk, skb) < 0) return 1; - goto discard; + consume_skb(skb); + return 0; } if (dh->dccph_type == DCCP_PKT_RESET) goto discard; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index f6603142cb33c7c2e211414c4f193835297f9fe5..3d009e17416656159f13144bdec9ca18512165a8 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -1042,7 +1042,14 @@ void ipv4_pktinfo_prepare(struct sk_buff *skb) pktinfo->ipi_ifindex = 0; pktinfo->ipi_spec_dst.s_addr = 0; } - skb_dst_drop(skb); + /* We need to keep the dst for __ip_options_echo() + * We could restrict the test to opt.ts_needtime || opt.srr, + * but the following is good enough as IP options are not often used. + */ + if (unlikely(IPCB(skb)->opt.optlen)) + skb_dst_force(skb); + else + skb_dst_drop(skb); } int ip_setsockopt(struct sock *sk, int level, diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 45da34a871124ae83e8f6572f72303d25ca572da..2e87251cacd2b3b5c31278a346e83fd1a4b6d12f 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -3663,8 +3663,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, if (unlikely(req->tp_block_size & (PAGE_SIZE - 1))) goto out; if (po->tp_version >= TPACKET_V3 && - (int)(req->tp_block_size - - BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0) + req->tp_block_size <= + BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv)) goto out; if (unlikely(req->tp_frame_size < po->tp_hdrlen + po->tp_reserve)) diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index bc6f00f28f9001a8f8f95b99d37d3afb93922937..7a2a8a1cf0361547883a0945212c08c170d6f1bc 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 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 @@ -1161,6 +1161,7 @@ static int msm_compr_free(struct snd_compr_stream *cstream) kfree(pdata->dec_params[soc_prtd->dai_link->be_id]); pdata->dec_params[soc_prtd->dai_link->be_id] = NULL; kfree(prtd); + runtime->private_data = NULL; return 0; } diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c index 1eef030a9f5584933c5e4102fa168f4650ff47bb..c99512b40993bea564ab00fb77a80eab8827400e 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 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 @@ -499,6 +499,7 @@ done: mutex_unlock(&prtd->lock); prtd->prepared--; kfree(prtd); + runtime->private_data = NULL; return 0; } static int msm_afe_prepare(struct snd_pcm_substream *substream) diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c index 7d35c9d0b0b9237ea16d323528c076594e123000..7ff529bac83dd8d5bdb81ef48db027e5d8d3798c 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 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 @@ -497,6 +497,7 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) pr_debug("%s\n", __func__); kfree(prtd); + runtime->private_data = NULL; return 0; } diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c index 9806b70fb6d321b4c3ef4d494c9b0837d2c3b3d2..a5b733bd223762151b734ed0cc438cf4b4349899 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 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 @@ -698,6 +698,8 @@ static int msm_pcm_playback_close(struct snd_pcm_substream *substream) msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id, SNDRV_PCM_STREAM_PLAYBACK); kfree(prtd); + runtime->private_data = NULL; + return 0; } @@ -801,6 +803,7 @@ static int msm_pcm_capture_close(struct snd_pcm_substream *substream) msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id, SNDRV_PCM_STREAM_CAPTURE); kfree(prtd); + runtime->private_data = NULL; return 0; }