From a880c34a4198cb8a17367942752ebcc377152d4b Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Thu, 23 Jun 2016 15:38:05 +0530 Subject: [PATCH 01/48] regualtor: spm-regulator: Add additional settling delay for FTS2.5 SMPS Based on characterization add 70us settling delay on the voltage UP to account for warm-up time and ramp-up delays for 0-10% and 90-100% of the voltage value. On the voltage ramp-down side add the stepper slew-rate delay and and an additional 70us margin to avoid voltage updates while the stepper is in progress. This could lead to voltage over/undershoot due to buck-internal synchronization failure. CRs-Fixed: 1036738 Change-Id: Id4230be9c4c981758bbf6860bab1f487a3b57f85 Signed-off-by: Anirudh Ghayal --- drivers/regulator/spm-regulator.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/spm-regulator.c b/drivers/regulator/spm-regulator.c index be0ddc20b5a4..fb07e6ed7703 100644 --- a/drivers/regulator/spm-regulator.c +++ b/drivers/regulator/spm-regulator.c @@ -101,6 +101,12 @@ static const struct voltage_range ult_hf_range1 = {750000, 750000, 1525000, #define QPNP_FTS2_STEP_MARGIN_NUM 4 #define QPNP_FTS2_STEP_MARGIN_DEN 5 +/* + * Settling delay for FTS2.5 + * Warm-up=20uS, 0-10% & 90-100% non-linear V-ramp delay = 50uS + */ +#define FTS2P5_SETTLING_DELAY_US 70 + /* VSET value to decide the range of ULT SMPS */ #define ULT_SMPS_RANGE_SPLIT 0x60 @@ -141,6 +147,7 @@ static int _spm_regulator_set_voltage(struct regulator_dev *rdev) struct spm_vreg *vreg = rdev_get_drvdata(rdev); bool spm_failed = false; int rc = 0; + u32 slew_delay; u8 reg; if (vreg->vlevel == vreg->last_set_vlevel) @@ -181,8 +188,16 @@ static int _spm_regulator_set_voltage(struct regulator_dev *rdev) if (vreg->uV > vreg->last_set_uV) { /* Wait for voltage stepping to complete. */ - udelay(DIV_ROUND_UP(vreg->uV - vreg->last_set_uV, - vreg->step_rate)); + slew_delay = DIV_ROUND_UP(vreg->uV - vreg->last_set_uV, + vreg->step_rate); + if (vreg->regulator_type == QPNP_TYPE_FTS2p5) + slew_delay += FTS2P5_SETTLING_DELAY_US; + udelay(slew_delay); + } else if (vreg->regulator_type == QPNP_TYPE_FTS2p5) { + /* add the ramp-down delay */ + slew_delay = DIV_ROUND_UP(vreg->last_set_uV - vreg->uV, + vreg->step_rate) + FTS2P5_SETTLING_DELAY_US; + udelay(slew_delay); } if ((vreg->regulator_type == QPNP_TYPE_FTS2) From 642675c40ab41f1c6f3b4e4dc3fc39db36043692 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Fri, 27 May 2016 20:01:40 +0530 Subject: [PATCH 02/48] soc: qcom: spm: Poll for the PMIC_STATE after updating the VCTL register The PMIC_STATE is expected to move to idle after the VCTL register value is written to the PMIC. Also update the PMIC_STATE poll timeout to 500us for all the targets. CRs-Fixed: 1024714 Change-Id: If9d9875a967179c6ee5fced8f019c01f1a2f0583 Signed-off-by: Anirudh Ghayal Signed-off-by: Maulik Shah --- arch/arm/boot/dts/qcom/apq8084-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8226-v1-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8226-v2-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8610-v1-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8610-v2-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8909-pm8916-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8916-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8952-pm.dtsi | 2 +- arch/arm/boot/dts/qcom/msm8956-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8974-v1-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8974-v2-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8974pro-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8976-pm.dtsi | 4 ++-- arch/arm/boot/dts/qcom/msm8992-pm.dtsi | 6 +++--- arch/arm/boot/dts/qcom/msm8994-v1-pm.dtsi | 6 +++--- arch/arm/boot/dts/qcom/msm8994-v2-pm.dtsi | 6 +++--- drivers/soc/qcom/spm.c | 12 +++++++----- 17 files changed, 41 insertions(+), 39 deletions(-) diff --git a/arch/arm/boot/dts/qcom/apq8084-pm.dtsi b/arch/arm/boot/dts/qcom/apq8084-pm.dtsi index 69feaf8a5933..618f641353a8 100644 --- a/arch/arm/boot/dts/qcom/apq8084-pm.dtsi +++ b/arch/arm/boot/dts/qcom/apq8084-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 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 @@ -115,7 +115,7 @@ qcom,saw2-spm-ctl = <0x1>; qcom,saw2-pmic-data0 = <0x02030080>; qcom,saw2-pmic-data1 = <0x00030000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,pfm-port = <0x2>; diff --git a/arch/arm/boot/dts/qcom/msm8226-v1-pm.dtsi b/arch/arm/boot/dts/qcom/msm8226-v1-pm.dtsi index 8641200fa08d..93641ad50108 100644 --- a/arch/arm/boot/dts/qcom/msm8226-v1-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8226-v1-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 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 @@ -96,7 +96,7 @@ qcom,saw2-spm-ctl = <0x0>; qcom,saw2-pmic-data0 = <0x02030080>; qcom,saw2-pmic-data1 = <0x00030000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,pfm-port = <0x2>; diff --git a/arch/arm/boot/dts/qcom/msm8226-v2-pm.dtsi b/arch/arm/boot/dts/qcom/msm8226-v2-pm.dtsi index 6e7b98e85461..9836b885f31c 100644 --- a/arch/arm/boot/dts/qcom/msm8226-v2-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8226-v2-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 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 @@ -96,7 +96,7 @@ qcom,saw2-spm-ctl = <0x0>; qcom,saw2-pmic-data0 = <0x02030080>; qcom,saw2-pmic-data1 = <0x00030000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,pfm-port = <0x2>; diff --git a/arch/arm/boot/dts/qcom/msm8610-v1-pm.dtsi b/arch/arm/boot/dts/qcom/msm8610-v1-pm.dtsi index 83a6f3bed99b..389bcc158939 100644 --- a/arch/arm/boot/dts/qcom/msm8610-v1-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8610-v1-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 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 @@ -96,7 +96,7 @@ qcom,saw2-spm-ctl = <0x0>; qcom,saw2-pmic-data0 = <0x02030080>; qcom,saw2-pmic-data1 = <0x00030000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,pfm-port = <0x2>; diff --git a/arch/arm/boot/dts/qcom/msm8610-v2-pm.dtsi b/arch/arm/boot/dts/qcom/msm8610-v2-pm.dtsi index f29a83135b98..448c733eaec2 100644 --- a/arch/arm/boot/dts/qcom/msm8610-v2-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8610-v2-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 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 @@ -96,7 +96,7 @@ qcom,saw2-spm-ctl = <0x0>; qcom,saw2-pmic-data0 = <0x02030080>; qcom,saw2-pmic-data1 = <0x00030000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,pfm-port = <0x2>; diff --git a/arch/arm/boot/dts/qcom/msm8909-pm8916-pm.dtsi b/arch/arm/boot/dts/qcom/msm8909-pm8916-pm.dtsi index 1202ae2d3c65..b18b8a9d2daf 100644 --- a/arch/arm/boot/dts/qcom/msm8909-pm8916-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8909-pm8916-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 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 @@ -100,7 +100,7 @@ qcom,saw2-pmic-data1 = <0x00030000>; qcom,saw2-pmic-data4 = <0x00010080>; qcom,saw2-pmic-data5 = <0x00010000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,pfm-port = <0x2>; diff --git a/arch/arm/boot/dts/qcom/msm8916-pm.dtsi b/arch/arm/boot/dts/qcom/msm8916-pm.dtsi index c77d44bacceb..298fe12a9305 100644 --- a/arch/arm/boot/dts/qcom/msm8916-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8916-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 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 @@ -90,7 +90,7 @@ qcom,saw2-pmic-data1 = <0x00030000>; qcom,saw2-pmic-data4 = <0x00010080>; qcom,saw2-pmic-data5 = <0x00010000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,pfm-port = <0x2>; diff --git a/arch/arm/boot/dts/qcom/msm8952-pm.dtsi b/arch/arm/boot/dts/qcom/msm8952-pm.dtsi index 137042ddebaa..33c5c7dd10ba 100644 --- a/arch/arm/boot/dts/qcom/msm8952-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8952-pm.dtsi @@ -27,7 +27,7 @@ qcom,saw2-pmic-data1 = <0x00030000>; qcom,saw2-pmic-data4 = <0x00010080>; qcom,saw2-pmic-data5 = <0x00010000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,pfm-port = <0x2>; diff --git a/arch/arm/boot/dts/qcom/msm8956-pm.dtsi b/arch/arm/boot/dts/qcom/msm8956-pm.dtsi index 254c8200956f..5c05204a9d36 100644 --- a/arch/arm/boot/dts/qcom/msm8956-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8956-pm.dtsi @@ -22,7 +22,7 @@ qcom,saw2-spm-dly = <0X3c102800>; qcom,saw2-spm-ctl = <0x8>; qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,saw2-pmic-data0 = <0x03030080>; /* VDD_APC0 on */ @@ -42,7 +42,7 @@ qcom,saw2-spm-dly = <0x3c11840a>; qcom,saw2-spm-ctl = <0x8>; qcom,cpu-vctl-list = <&CPU4 &CPU5>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,saw2-pmic-data0 = <0x03030080>; /* VDD_APC1 on */ diff --git a/arch/arm/boot/dts/qcom/msm8974-v1-pm.dtsi b/arch/arm/boot/dts/qcom/msm8974-v1-pm.dtsi index 985dbac5ce4f..44fdfd0f1713 100644 --- a/arch/arm/boot/dts/qcom/msm8974-v1-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8974-v1-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016, 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 @@ -119,7 +119,7 @@ qcom,saw2-spm-ctl = <0x1>; qcom,saw2-pmic-data0 = <0x02030080>; qcom,saw2-pmic-data1 = <0x00030000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,cpu-vctl-mask = <0xf>; diff --git a/arch/arm/boot/dts/qcom/msm8974-v2-pm.dtsi b/arch/arm/boot/dts/qcom/msm8974-v2-pm.dtsi index b569ddedd71d..b9a495f8ccf2 100644 --- a/arch/arm/boot/dts/qcom/msm8974-v2-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8974-v2-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2016, 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 @@ -120,7 +120,7 @@ qcom,saw2-spm-ctl = <0x1>; qcom,saw2-pmic-data0 = <0x02030080>; qcom,saw2-pmic-data1 = <0x00030000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,pfm-port = <0x2>; diff --git a/arch/arm/boot/dts/qcom/msm8974pro-pm.dtsi b/arch/arm/boot/dts/qcom/msm8974pro-pm.dtsi index f833e2464c03..ee6eae7b4ef4 100644 --- a/arch/arm/boot/dts/qcom/msm8974pro-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8974pro-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2016, 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 @@ -124,7 +124,7 @@ qcom,saw2-spm-ctl = <0x1>; qcom,saw2-pmic-data0 = <0x02030080>; qcom,saw2-pmic-data1 = <0x00030000>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,pfm-port = <0x2>; diff --git a/arch/arm/boot/dts/qcom/msm8976-pm.dtsi b/arch/arm/boot/dts/qcom/msm8976-pm.dtsi index 457905905a71..2ee863378a55 100644 --- a/arch/arm/boot/dts/qcom/msm8976-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8976-pm.dtsi @@ -22,7 +22,7 @@ qcom,saw2-spm-dly = <0X3c102800>; qcom,saw2-spm-ctl = <0x8>; qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,saw2-pmic-data0 = <0x03030080>; /* VDD_APC0 on */ @@ -42,7 +42,7 @@ qcom,saw2-spm-dly = <0x3c11840a>; qcom,saw2-spm-ctl = <0x8>; qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,saw2-pmic-data0 = <0x03030080>; /* VDD_APC1 on */ diff --git a/arch/arm/boot/dts/qcom/msm8992-pm.dtsi b/arch/arm/boot/dts/qcom/msm8992-pm.dtsi index bc888fc28b23..383fef7383ac 100644 --- a/arch/arm/boot/dts/qcom/msm8992-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8992-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 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 @@ -22,7 +22,7 @@ qcom,saw2-spm-dly = <0X3c100c00>; qcom,saw2-spm-ctl = <0x0>; qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,supports-rpm-hs; @@ -65,7 +65,7 @@ qcom,saw2-spm-dly = <0x3c100c30>; qcom,saw2-spm-ctl = <0x8>; qcom,cpu-vctl-list = <&CPU4 &CPU5>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ diff --git a/arch/arm/boot/dts/qcom/msm8994-v1-pm.dtsi b/arch/arm/boot/dts/qcom/msm8994-v1-pm.dtsi index 8d3010462e6f..1bbd424bf282 100644 --- a/arch/arm/boot/dts/qcom/msm8994-v1-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8994-v1-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 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 @@ -22,7 +22,7 @@ qcom,saw2-spm-dly = <0X3c100c00>; qcom,saw2-spm-ctl = <0x0>; qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,supports-rpm-hs; @@ -65,7 +65,7 @@ qcom,saw2-spm-dly = <0x3c100c30>; qcom,saw2-spm-ctl = <0x0>; qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ diff --git a/arch/arm/boot/dts/qcom/msm8994-v2-pm.dtsi b/arch/arm/boot/dts/qcom/msm8994-v2-pm.dtsi index c09a1d546fc4..2c0434f9779d 100644 --- a/arch/arm/boot/dts/qcom/msm8994-v2-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8994-v2-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 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 @@ -22,7 +22,7 @@ qcom,saw2-spm-dly = <0X3c100c00>; qcom,saw2-spm-ctl = <0x0>; qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,supports-rpm-hs; @@ -65,7 +65,7 @@ qcom,saw2-spm-dly = <0x3c100c30>; qcom,saw2-spm-ctl = <0x8>; qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>; - qcom,vctl-timeout-us = <50>; + qcom,vctl-timeout-us = <500>; qcom,vctl-port = <0x0>; qcom,phase-port = <0x1>; qcom,saw2-pmic-data0 = <0x00030000>; /* VDD_APC1 off */ diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c index e3d729397a8d..56cb53916c64 100644 --- a/drivers/soc/qcom/spm.c +++ b/drivers/soc/qcom/spm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2016, 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 @@ -232,7 +232,7 @@ uint32_t msm_spm_drv_get_sts_curr_pmic_data( struct msm_spm_driver_data *dev) { msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW_PMIC_STS); - return dev->reg_shadow[MSM_SPM_REG_SAW_PMIC_STS] & 0xFF; + return dev->reg_shadow[MSM_SPM_REG_SAW_PMIC_STS] & 0x300FF; } static inline void msm_spm_drv_get_saw2_ver(struct msm_spm_driver_data *dev, @@ -425,10 +425,12 @@ int msm_spm_drv_set_vdd(struct msm_spm_driver_data *dev, unsigned int vlevel) timeout_us = dev->vctl_timeout_us; /* Confirm the voltage we set was what hardware sent */ do { - new_level = msm_spm_drv_get_sts_curr_pmic_data(dev); - if (new_level == vlevel) - break; udelay(1); + new_level = msm_spm_drv_get_sts_curr_pmic_data(dev); + /* FSM is idle */ + if (((new_level & 0x30000) == 0) && + ((new_level & 0xFF) == vlevel)) + break; } while (--timeout_us); if (!timeout_us) { pr_info("Wrong level %#x\n", new_level); From e3fc5443e202667982a7e29a004b428658f5fbb9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 19 Feb 2016 17:36:21 -0800 Subject: [PATCH 03/48] AIO: properly check iovec sizes In Linus's tree, the iovec code has been reworked massively, but in older kernels the AIO layer should be checking this before passing the request on to other layers. Many thanks to Ben Hawkes of Google Project Zero for pointing out the issue. Change-Id: I625e1b4376bb2342d6c5f88eb3f202e99a0c5b07 Reported-by: Ben Hawkes Acked-by: Benjamin LaHaise Tested-by: Willy Tarreau [backported to 3.10 - willy] Signed-off-by: Greg Kroah-Hartman Git-commit: 8a5e5e02fc83aaf67053ab53b359af08c6c49aaf Git-repo: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Signed-off-by: Ravi Kumar Siddojigari --- fs/aio.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index ded94c4fa30d..9798d4edfd8f 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -977,12 +977,17 @@ static ssize_t aio_setup_vectored_rw(int rw, struct kiocb *kiocb, bool compat) static ssize_t aio_setup_single_vector(int rw, struct kiocb *kiocb) { - if (unlikely(!access_ok(!rw, kiocb->ki_buf, kiocb->ki_nbytes))) - return -EFAULT; + size_t len = kiocb->ki_nbytes; + + if (len > MAX_RW_COUNT) + len = MAX_RW_COUNT; + + if (unlikely(!access_ok(!rw, kiocb->ki_buf, len))) + return -EFAULT; kiocb->ki_iovec = &kiocb->ki_inline_vec; kiocb->ki_iovec->iov_base = kiocb->ki_buf; - kiocb->ki_iovec->iov_len = kiocb->ki_nbytes; + kiocb->ki_iovec->iov_len = len; kiocb->ki_nr_segs = 1; return 0; } From e65b239f208a303bdffae4c03d44e82fcc51e88a Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Fri, 11 Dec 2015 14:22:28 -0800 Subject: [PATCH 04/48] msm: mdss: reset intf_stopped flag for sctl when exiting LP states When exiting low power state (LP1 of LP2), ensure that the intf_stopped flag is reset for the secondary ctl as well, otherwise it may result in the display corruption for that ctl path. Change-Id: I2ac9cff00e25a3cae6999e33c9f5a7a959413277 Signed-off-by: Veera Sundaram Sankaran --- drivers/video/msm/mdss/mdss_mdp_intf_cmd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c index 7a0f064a69e1..8116815c6480 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c @@ -925,6 +925,8 @@ static int mdss_mdp_cmd_panel_on(struct mdss_mdp_ctl *ctl, (void *)&ctx->intf_mdp_callback); ctx->intf_stopped = 0; + if (sctx) + sctx->intf_stopped = 0; } else { pr_err("%s: Panel already on\n", __func__); } @@ -1290,6 +1292,7 @@ static int mdss_mdp_cmd_stop_sub(struct mdss_mdp_ctl *ctl, int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state) { struct mdss_mdp_cmd_ctx *ctx = ctl->intf_ctx[MASTER_CTX]; + struct mdss_mdp_cmd_ctx *sctx; struct mdss_mdp_ctl *sctl = mdss_mdp_get_split_ctl(ctl); bool panel_off = false; bool turn_off_clocks = false; @@ -1316,6 +1319,9 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state) pr_debug("%s: transition from %d --> %d\n", __func__, ctx->panel_power_state, panel_power_state); + if (sctl) + sctx = (struct mdss_mdp_cmd_ctx *) sctl->intf_ctx[MASTER_CTX]; + if (ctl->cmd_autorefresh_en) { int pre_suspend = ctx->autorefresh_pending_frame_cnt; mdss_mdp_cmd_enable_cmd_autorefresh(ctl, 0); @@ -1360,6 +1366,9 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state) MDSS_EVENT_REGISTER_MDP_CALLBACK, (void *)&ctx->intf_mdp_callback); ctx->intf_stopped = 0; + if (sctx) + sctx->intf_stopped = 0; + goto end; } } From 0c71f45747e886d024e3d2c27b0f18ed41ab249c Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Fri, 19 Feb 2016 12:30:45 -0800 Subject: [PATCH 05/48] msm: mdss: dsi: ensure clocks are off when setting their source When DSI panel in unblanked, the driver configures the sources for all the DSI branch clocks based on the current HW configuration. This assumes that the clocks would be off when the panel is unblanked. This may not be true when transitioning to ON state from any of the panel low power states (LP1 or LP2). This can lead to warnings when trying to set the clock source while the clock is enabled. Fix this by ensuring that the clock source is configured only if the panel is not on. Change-Id: I97f40eaedad203c5aaa0c645105bea2ff962e81d CRs-Fixed: 975819 Signed-off-by: Aravind Venkateswaran --- drivers/video/msm/mdss/mdss_dsi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c index f8d6bfe53665..088f21aed555 100644 --- a/drivers/video/msm/mdss/mdss_dsi.c +++ b/drivers/video/msm/mdss/mdss_dsi.c @@ -1268,14 +1268,14 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) goto end; } - ret = mdss_dsi_set_clk_src(ctrl_pdata); - if (ret) { - pr_err("%s: failed to set clk src. rc=%d\n", __func__, ret); + if (mdss_panel_is_power_on(cur_power_state)) { + pr_debug("%s: dsi_on from panel low power state\n", __func__); goto end; } - if (mdss_panel_is_power_on(cur_power_state)) { - pr_debug("%s: dsi_on from panel low power state\n", __func__); + ret = mdss_dsi_set_clk_src(ctrl_pdata); + if (ret) { + pr_err("%s: failed to set clk src. rc=%d\n", __func__, ret); goto end; } From bb858bb24bf67d614ca869d1e25865811e96de47 Mon Sep 17 00:00:00 2001 From: Adrian Salido-Moreno Date: Wed, 10 Jun 2015 18:50:40 -0700 Subject: [PATCH 06/48] msm: mdss: restructure tearcheck config Since we have a separate function for tear check enable. Tearcheck config with enable flag is not required, and redundant. Remove enable flag and improper usage of the function. CRs-fixed: 873962 Change-Id: I0835f858cc63a41e01a669069677322da408f245 Signed-off-by: Adrian Salido-Moreno --- drivers/video/msm/mdss/mdss_mdp_intf_cmd.c | 71 +++++++++++----------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c index 7a0f064a69e1..8286c499ba99 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c @@ -148,6 +148,9 @@ static int mdss_mdp_tearcheck_enable(struct mdss_mdp_ctl *ctl, bool enable) sctl = mdss_mdp_get_split_ctl(ctl); te = &ctl->panel_data->panel_info.te; + + pr_debug("%s: enable=%d\n", __func__, enable); + mdss_mdp_pingpong_write(mixer->pingpong_base, MDSS_MDP_REG_PP_TEAR_CHECK_EN, (te ? te->tear_check_en : 0) && enable); @@ -177,7 +180,7 @@ static int mdss_mdp_tearcheck_enable(struct mdss_mdp_ctl *ctl, bool enable) } static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, - struct mdss_mdp_cmd_ctx *ctx, bool enable) + struct mdss_mdp_cmd_ctx *ctx) { struct mdss_mdp_pp_tear_check *te = NULL; struct mdss_panel_info *pinfo; @@ -191,43 +194,41 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, return -ENODEV; } - if (enable) { - pinfo = &ctl->panel_data->panel_info; - te = &ctl->panel_data->panel_info.te; + pinfo = &ctl->panel_data->panel_info; + te = &ctl->panel_data->panel_info.te; - mdss_mdp_vsync_clk_enable(1); + mdss_mdp_vsync_clk_enable(1); - vsync_clk_speed_hz = - mdss_mdp_get_clk_rate(MDSS_CLK_MDP_VSYNC); + vsync_clk_speed_hz = + mdss_mdp_get_clk_rate(MDSS_CLK_MDP_VSYNC); - total_lines = mdss_panel_get_vtotal(pinfo); + total_lines = mdss_panel_get_vtotal(pinfo); - total_lines *= pinfo->mipi.frame_rate; + total_lines *= pinfo->mipi.frame_rate; - vclks_line = (total_lines) ? vsync_clk_speed_hz/total_lines : 0; + vclks_line = (total_lines) ? vsync_clk_speed_hz/total_lines : 0; - cfg = BIT(19); - if (pinfo->mipi.hw_vsync_mode) - cfg |= BIT(20); + cfg = BIT(19); + if (pinfo->mipi.hw_vsync_mode) + cfg |= BIT(20); - if (te->refx100) - vclks_line = vclks_line * pinfo->mipi.frame_rate * - 100 / te->refx100; - else { - pr_warn("refx100 cannot be zero! Use 6000 as default\n"); - vclks_line = vclks_line * pinfo->mipi.frame_rate * - 100 / 6000; - } - - cfg |= vclks_line; - - pr_debug("%s: yres=%d vclks=%x height=%d init=%d rd=%d start=%d\n", - __func__, pinfo->yres, vclks_line, te->sync_cfg_height, - te->vsync_init_val, te->rd_ptr_irq, te->start_pos); - pr_debug("thrd_start =%d thrd_cont=%d\n", - te->sync_threshold_start, te->sync_threshold_continue); + if (te->refx100) { + vclks_line = vclks_line * pinfo->mipi.frame_rate * + 100 / te->refx100; + } else { + pr_warn("refx100 cannot be zero! Use 6000 as default\n"); + vclks_line = vclks_line * pinfo->mipi.frame_rate * + 100 / 6000; } + cfg |= vclks_line; + + pr_debug("%s: yres=%d vclks=%x height=%d init=%d rd=%d start=%d\n", + __func__, pinfo->yres, vclks_line, te->sync_cfg_height, + te->vsync_init_val, te->rd_ptr_irq, te->start_pos); + pr_debug("thrd_start =%d thrd_cont=%d\n", + te->sync_threshold_start, te->sync_threshold_continue); + pingpong_base = mixer->pingpong_base; if (ctx->pingpong_split_slave) @@ -258,8 +259,7 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, return 0; } -static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx, - bool enable) +static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx) { int rc = 0; struct mdss_mdp_mixer *mixer; @@ -267,7 +267,7 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx, mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_LEFT); if (mixer) { - rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx, enable); + rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx); if (rc) goto err; } @@ -275,7 +275,7 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx, if (!(ctl->opmode & MDSS_MDP_CTL_OP_PACK_3D_ENABLE)) { mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_RIGHT); if (mixer) - rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx, enable); + rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx); } err: return rc; @@ -1140,7 +1140,7 @@ int mdss_mdp_cmd_restore(struct mdss_mdp_ctl *ctl) { pr_debug("%s: called for ctl%d\n", __func__, ctl->num); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); - if (mdss_mdp_cmd_tearcheck_setup(ctl->intf_ctx[MASTER_CTX], true)) + if (mdss_mdp_cmd_tearcheck_setup(ctl->intf_ctx[MASTER_CTX])) pr_warn("%s: tearcheck setup failed\n", __func__); else mdss_mdp_tearcheck_enable(ctl, true); @@ -1212,7 +1212,6 @@ int mdss_mdp_cmd_ctx_stop(struct mdss_mdp_ctl *ctl, mdss_mdp_cmd_clk_off(ctx); flush_work(&ctx->pp_done_work); - mdss_mdp_cmd_tearcheck_setup(ctx, false); mdss_mdp_tearcheck_enable(ctl, false); if (mdss_panel_is_power_on(panel_power_state)) { @@ -1472,7 +1471,7 @@ static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num, mdss_mdp_cmd_pingpong_done, ctl); - ret = mdss_mdp_cmd_tearcheck_setup(ctx, true); + ret = mdss_mdp_cmd_tearcheck_setup(ctx); if (ret) pr_err("tearcheck setup failed\n"); From 90c7baaebeca61c4fb19782b0ef2367d8406d8e3 Mon Sep 17 00:00:00 2001 From: Ingrid Gallardo Date: Fri, 8 Jan 2016 17:12:16 -0800 Subject: [PATCH 07/48] msm: mdss: keep tear check enabled in LP1 power state Prevent driver from disabling the tear check when going to LP1 state. This is needed for certain panels in cases where there are more than one frame update in LP1 state. Change-Id: Ib80f06e0609d9d49584118504adf87da44455563 Signed-off-by: Ingrid Gallardo --- drivers/video/msm/mdss/mdss_mdp_intf_cmd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c index 8286c499ba99..5be09a8cbc00 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c @@ -1212,7 +1212,10 @@ int mdss_mdp_cmd_ctx_stop(struct mdss_mdp_ctl *ctl, mdss_mdp_cmd_clk_off(ctx); flush_work(&ctx->pp_done_work); - mdss_mdp_tearcheck_enable(ctl, false); + + if (mdss_panel_is_power_off(panel_power_state) || + mdss_panel_is_power_on_ulp(panel_power_state)) + mdss_mdp_tearcheck_enable(ctl, false); if (mdss_panel_is_power_on(panel_power_state)) { pr_debug("%s: intf stopped with panel on\n", __func__); From 07120b47e5ff060335be355c30dfd4a2b3e23e8a Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Mon, 18 Jul 2016 16:07:42 +0530 Subject: [PATCH 08/48] ASoC: msm: qdsp6v2: DAP: Update check to validate data length A big negative data length value can bypass the current check, update the condition to ensure that only valid data length is used to copy the params. CRs-Fixed: 1041130 Change-Id: I6e1a58e901e4c042acfb0ab0a6223dec2949aefe Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 48180cf5e337..ad2f2e9865c3 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1523,8 +1523,9 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) } /* Return if invalid length */ - if (dolby_data->length > - (DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM - DOLBY_PARAM_PAYLOAD_SIZE)) { + if ((dolby_data->length > + (DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM - DOLBY_PARAM_PAYLOAD_SIZE)) || + (dolby_data->length <= 0)) { pr_err("Invalid length %d", dolby_data->length); rc = -EINVAL; goto end; From 644d96001539974e9c73818be90ba1c99ae9c8ad Mon Sep 17 00:00:00 2001 From: Shalini Krishnamoorthi Date: Thu, 30 Jun 2016 14:00:04 -0700 Subject: [PATCH 09/48] msm: mdss: Correct the format specifiers in sscanf function In many parts of the code the sscanf function was getting an unsigned integer with a wrong format specifier. Changed the format specifiers appropriately. Single variable sscanf were replaced by kstrtouint at reported places. CRs-Fixed: 1024872 Change-Id: I03ce718b0456d437d31d701586965d0aa7443b51 Signed-off-by: Shalini Krishnamoorthi --- drivers/video/msm/mdss/mdss_debug.c | 8 ++++---- drivers/video/msm/mdss/mdss_fb.c | 10 +++++----- drivers/video/msm/mdss/mdss_mdp.c | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index 51fb1636d4bb..9fef2437fb96 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -79,7 +79,7 @@ static ssize_t panel_debug_base_offset_write(struct file *file, buf[count] = 0; /* end of string */ - if (sscanf(buf, "%x %d", &off, &cnt) != 2) + if (sscanf(buf, "%x %u", &off, &cnt) != 2) return -EFAULT; if (off > dbg->max_offset) @@ -693,11 +693,11 @@ static ssize_t mdss_debug_factor_write(struct file *file, if (strnchr(buf, count, '/')) { /* Parsing buf as fraction */ - if (sscanf(buf, "%d/%d", &numer, &denom) != 2) + if (sscanf(buf, "%u/%u", &numer, &denom) != 2) return -EFAULT; } else { /* Parsing buf as percentage */ - if (sscanf(buf, "%d", &numer) != 1) + if (kstrtouint(buf, 0, &numer)) return -EFAULT; denom = 100; } @@ -1004,7 +1004,7 @@ static ssize_t mdss_debug_perf_bw_limit_write(struct file *file, if (strnchr(buf, count, ' ')) { /* Parsing buf */ - if (sscanf(buf, "%d %d", &mode, &val) != 2) + if (sscanf(buf, "%u %u", &mode, &val) != 2) return -EFAULT; } diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index 37e9f50fff7a..f9a0885e4da3 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -2,7 +2,7 @@ * Core MDSS framebuffer driver. * * Copyright (C) 2007 Google Incorporated - * Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -623,8 +623,8 @@ static ssize_t mdss_fb_force_panel_dead(struct device *dev, return len; } - if (sscanf(buf, "%d", &pdata->panel_info.panel_force_dead) != 1) - pr_err("sccanf buf error!\n"); + if (kstrtouint(buf, 0, &pdata->panel_info.panel_force_dead)) + pr_err("kstrtouint buf error\n"); return len; } @@ -737,8 +737,8 @@ static ssize_t mdss_fb_change_dfps_mode(struct device *dev, } pinfo = &pdata->panel_info; - if (sscanf(buf, "%d", &dfps_mode) != 1) { - pr_err("sccanf buf error!\n"); + if (kstrtouint(buf, 0, &dfps_mode)) { + pr_err("kstrtouint buf error\n"); return len; } diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 191a86eb7339..09e3d25460c2 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -1674,7 +1674,7 @@ static ssize_t mdss_mdp_store_max_limit_bw(struct device *dev, struct mdss_data_type *mdata = dev_get_drvdata(dev); u32 data = 0; - if (1 != sscanf(buf, "%d", &data)) { + if (kstrtouint(buf, 0, &data)) { pr_info("Not able scan to bw_mode_bitmap\n"); } else { mdata->bw_mode_bitmap = data; From ed6181d8195fadbad328eb4335bf4deb6c115427 Mon Sep 17 00:00:00 2001 From: Anand Kumar Date: Tue, 21 Jun 2016 17:36:05 +0530 Subject: [PATCH 10/48] wcnss: Avoid user buffer overloading for write cal data compare size of allocated cal data buffer from heap and count bytes provided to write by user to avoid heap overflow for write cal data. Change-Id: Id70c3230f761385489e5e94c613f4519239dfb1f CRs-Fixed: 1032174 Signed-off-by: Anand Kumar --- drivers/net/wireless/wcnss/wcnss_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c index fbdcccc91bca..c4c00d737aa6 100644 --- a/drivers/net/wireless/wcnss/wcnss_wlan.c +++ b/drivers/net/wireless/wcnss/wcnss_wlan.c @@ -3361,7 +3361,7 @@ static ssize_t wcnss_wlan_write(struct file *fp, const char __user return -EFAULT; if ((UINT32_MAX - count < penv->user_cal_rcvd) || - MAX_CALIBRATED_DATA_SIZE < count + penv->user_cal_rcvd) { + (penv->user_cal_exp_size < count + penv->user_cal_rcvd)) { pr_err(DEVICE " invalid size to write %zu\n", count + penv->user_cal_rcvd); rc = -ENOMEM; From 80b706950beaf9c4d21b750008aaea52ae6b2efe Mon Sep 17 00:00:00 2001 From: Josh Kirsch Date: Mon, 2 May 2016 14:55:04 -0700 Subject: [PATCH 11/48] drivers: soc: Add buffer overflow check for svc send request Add buffer overflow check in voice_svc_send_req. CRs-fixed: 1010081 Change-Id: I4ae703334b0cf04f327b392bc9cd6febd4ad32f2 Signed-off-by: Josh Kirsch --- drivers/soc/qcom/qdsp6v2/voice_svc.c | 46 +++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/soc/qcom/qdsp6v2/voice_svc.c b/drivers/soc/qcom/qdsp6v2/voice_svc.c index 23b8292c8db5..67c58d1e6d4c 100644 --- a/drivers/soc/qcom/qdsp6v2/voice_svc.c +++ b/drivers/soc/qcom/qdsp6v2/voice_svc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 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 @@ -188,7 +188,8 @@ static int voice_svc_send_req(struct voice_svc_cmd_request *apr_request, int ret = 0; void *apr_handle = NULL; struct apr_data *aprdata = NULL; - uint32_t user_payload_size = 0; + uint32_t user_payload_size; + uint32_t payload_size; pr_debug("%s\n", __func__); @@ -200,15 +201,19 @@ static int voice_svc_send_req(struct voice_svc_cmd_request *apr_request, } user_payload_size = apr_request->payload_size; + payload_size = sizeof(struct apr_data) + user_payload_size; - aprdata = kmalloc(sizeof(struct apr_data) + user_payload_size, - GFP_KERNEL); - - if (aprdata == NULL) { - pr_err("%s: aprdata kmalloc failed.\n", __func__); - - ret = -ENOMEM; + if (payload_size <= user_payload_size) { + pr_err("%s: invalid payload size ( 0x%x ).\n", + __func__, user_payload_size); + ret = -EINVAL; goto done; + } else { + aprdata = kmalloc(payload_size, GFP_KERNEL); + if (aprdata == NULL) { + ret = -ENOMEM; + goto done; + } } voice_svc_update_hdr(apr_request, aprdata); @@ -388,18 +393,31 @@ static ssize_t voice_svc_write(struct file *file, const char __user *buf, switch (cmd) { case MSG_REGISTER: - ret = process_reg_cmd( + if (count >= + (sizeof(struct voice_svc_register) + + sizeof(*data))) { + ret = process_reg_cmd( (struct voice_svc_register *)data->payload, prtd); - if (!ret) - ret = count; - + if (!ret) + ret = count; + } else { + pr_err("%s: invalid payload size\n", __func__); + ret = -EINVAL; + goto done; + } break; case MSG_REQUEST: + if (count >= (sizeof(struct voice_svc_cmd_request) + + sizeof(*data))) { ret = voice_svc_send_req( (struct voice_svc_cmd_request *)data->payload, prtd); if (!ret) ret = count; - + } else { + pr_err("%s: invalid payload size\n", __func__); + ret = -EINVAL; + goto done; + } break; default: pr_debug("%s: Invalid command: %u\n", __func__, cmd); From 12a71f9ca6257cf3ca6566e00bcebc004cbb6b6a Mon Sep 17 00:00:00 2001 From: Pavan Anamula Date: Fri, 13 May 2016 15:01:14 +0530 Subject: [PATCH 12/48] mmc: block: Add check to mmc_blk_part_switch Sometimes after failing RPMB access due to card in bad voltgae state, If issue USER parition access request,it fails as card is already in bad state. Fix this by adding error handling to mmc_blk_part_switch() and by resetting the block whenever partition switch fails. Change-Id: I98c6793e25a11d209553236c266cca908242095f Signed-off-by: Pavan Anamula --- drivers/mmc/card/block.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 80a0f157b2ae..4946e845ae34 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -133,6 +133,7 @@ struct mmc_blk_data { #define MMC_BLK_DISCARD BIT(2) #define MMC_BLK_SECDISCARD BIT(3) #define MMC_BLK_FLUSH BIT(4) +#define MMC_BLK_PARTSWITCH BIT(5) /* @@ -1122,8 +1123,13 @@ static inline int mmc_blk_part_switch(struct mmc_card *card, ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, part_config, card->ext_csd.part_time); - if (ret) + + if (ret) { + pr_err("%s: mmc_blk_part_switch failure, %d -> %d\n", + mmc_hostname(card->host), main_md->part_curr, + md->part_type); return ret; + } card->ext_csd.part_config = part_config; card->part_curr = md->part_type; @@ -3698,6 +3704,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) struct mmc_host *host = card->host; unsigned long flags; unsigned int cmd_flags = req ? req->cmd_flags : 0; + int err; if (req && !mq->mqrq_prev->req) { mmc_rpm_hold(host, &card->dev); @@ -3712,7 +3719,17 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) } ret = mmc_blk_part_switch(card, md); + if (ret) { + err = mmc_blk_reset(md, card->host, MMC_BLK_PARTSWITCH); + if (!err) { + pr_err("%s: mmc_blk_reset(MMC_BLK_PARTSWITCH) succeeded.\n", + mmc_hostname(host)); + mmc_blk_reset_success(md, MMC_BLK_PARTSWITCH); + } else + pr_err("%s: mmc_blk_reset(MMC_BLK_PARTSWITCH) failed.\n", + mmc_hostname(host)); + if (req) { blk_end_request_all(req, -EIO); } From 04802cbb50fda25dffab8fb5e1e56eb31111582c Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Thu, 16 Jun 2016 18:55:47 -0700 Subject: [PATCH 13/48] msm: mdss: Fix memleak in panel_debug_reg_write Free panel buffer or register buffer if either allocation fails. Change-Id: I600c646a0c23b654392d8e00a829bfd88b71c38c Signed-off-by: Krishna Srinivas --- drivers/video/msm/mdss/mdss_debug.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index 9fef2437fb96..de21cd3f7ed6 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -199,6 +199,7 @@ static ssize_t panel_debug_base_reg_read(struct file *file, struct mdss_panel_data *panel_data = ctl->panel_data; struct mdss_dsi_ctrl_pdata *ctrl_pdata = container_of(panel_data, struct mdss_dsi_ctrl_pdata, panel_data); + int rc = -EFAULT; if (!dbg) return -ENODEV; @@ -217,7 +218,8 @@ static ssize_t panel_debug_base_reg_read(struct file *file, if (!rx_buf || !panel_reg_buf) { pr_err("not enough memory to hold panel reg dump\n"); - return -ENOMEM; + rc = -ENOMEM; + goto read_reg_fail; } if (mdata->debug_inf.debug_enable_clock) @@ -252,8 +254,7 @@ static ssize_t panel_debug_base_reg_read(struct file *file, read_reg_fail: kfree(rx_buf); kfree(panel_reg_buf); - return -EFAULT; - + return rc; } static const struct file_operations panel_off_fops = { From 85f23013d1d4f11e08b18036d2d891e4b33b0e7a Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Mon, 18 Jul 2016 13:20:18 -0700 Subject: [PATCH 14/48] qseecom: validate the inputs of __qseecom_send_modfd_resp The resp_len and resp_buf_ptr of qseecom_send_modfd_listener_resp are not checked, then an userspace application that manipulates resp_len can corrupt the kernel memory. Thus make changes to validate these parameters. CRs-fixed: 1036418 Change-Id: Id43ec6b55b332d0dac09a9abb998a410f49b44f7 Signed-off-by: Zhen Kong --- drivers/misc/qseecom.c | 77 +++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 19 deletions(-) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index de26d50a5e94..26df0442ddfe 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -3933,41 +3933,80 @@ static int qseecom_reentrancy_send_resp(struct qseecom_dev_handle *data) return 0; } +static int __validate_send_modfd_resp_inputs(struct qseecom_dev_handle *data, + struct qseecom_send_modfd_listener_resp *resp, + struct qseecom_registered_listener_list *this_lstnr) +{ + int i; + + if (!data || !resp || !this_lstnr) { + pr_err("listener handle or resp msg is null\n"); + return -EINVAL; + } + + if (resp->resp_buf_ptr == NULL) { + pr_err("resp buffer is null\n"); + return -EINVAL; + } + /* validate resp buf length */ + if ((resp->resp_len == 0) || + (resp->resp_len > this_lstnr->sb_length)) { + pr_err("resp buf length %d not valid\n", resp->resp_len); + return -EINVAL; + } + + if ((uintptr_t)resp->resp_buf_ptr > (ULONG_MAX - resp->resp_len)) { + pr_err("Integer overflow in resp_len & resp_buf\n"); + return -EINVAL; + } + if ((uintptr_t)this_lstnr->user_virt_sb_base > + (ULONG_MAX - this_lstnr->sb_length)) { + pr_err("Integer overflow in user_virt_sb_base & sb_length\n"); + return -EINVAL; + } + /* validate resp buf */ + if (((uintptr_t)resp->resp_buf_ptr < + (uintptr_t)this_lstnr->user_virt_sb_base) || + ((uintptr_t)resp->resp_buf_ptr >= + ((uintptr_t)this_lstnr->user_virt_sb_base + + this_lstnr->sb_length)) || + (((uintptr_t)resp->resp_buf_ptr + resp->resp_len) > + ((uintptr_t)this_lstnr->user_virt_sb_base + + this_lstnr->sb_length))) { + pr_err("resp buf is out of shared buffer region\n"); + return -EINVAL; + } + + /* validate offsets */ + for (i = 0; i < MAX_ION_FD; i++) { + if (resp->ifd_data[i].cmd_buf_offset >= resp->resp_len) { + pr_err("Invalid offset %d = 0x%x\n", + i, resp->ifd_data[i].cmd_buf_offset); + return -EINVAL; + } + } + + return 0; +} + static int __qseecom_send_modfd_resp(struct qseecom_dev_handle *data, void __user *argp, bool is_64bit_addr) { struct qseecom_send_modfd_listener_resp resp; - int i; struct qseecom_registered_listener_list *this_lstnr = NULL; if (copy_from_user(&resp, argp, sizeof(resp))) { pr_err("copy_from_user failed"); return -EINVAL; } + this_lstnr = __qseecom_find_svc(data->listener.id); if (this_lstnr == NULL) return -EINVAL; - if (resp.resp_buf_ptr == NULL) { - pr_err("Invalid resp_buf_ptr\n"); + if (__validate_send_modfd_resp_inputs(data, &resp, this_lstnr)) return -EINVAL; - } - /* validate offsets */ - for (i = 0; i < MAX_ION_FD; i++) { - if (resp.ifd_data[i].cmd_buf_offset >= resp.resp_len) { - pr_err("Invalid offset %d = 0x%x\n", - i, resp.ifd_data[i].cmd_buf_offset); - return -EINVAL; - } - } - if ((resp.resp_buf_ptr < this_lstnr->user_virt_sb_base) || - ((uintptr_t)resp.resp_buf_ptr >= - ((uintptr_t)this_lstnr->user_virt_sb_base + - this_lstnr->sb_length))) { - pr_err("resp_buf_ptr address not within shared buffer\n"); - return -EINVAL; - } resp.resp_buf_ptr = this_lstnr->sb_virt + (uintptr_t)(resp.resp_buf_ptr - this_lstnr->user_virt_sb_base); From 443f5910c898d2f3773fa9c36ade844ba99dfae8 Mon Sep 17 00:00:00 2001 From: Ravi Aravamudhan Date: Wed, 1 Jul 2015 16:11:44 -0700 Subject: [PATCH 15/48] diag: Perform member-wise copy instead of memcpy Diag driver was copying the information from early initialization information for forward channels onto the control channel objects. This patch does a member-wise copy of the channel objects. Change-Id: Iaf2f1e4ddb392e1f2ee65a8796e91e4831cf8974 Signed-off-by: Ravi Aravamudhan --- drivers/char/diag/diagfwd_peripheral.c | 30 ++++++++++++++++++++------ 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c index 409248dfba8a..2bf85568936a 100644 --- a/drivers/char/diag/diagfwd_peripheral.c +++ b/drivers/char/diag/diagfwd_peripheral.c @@ -435,8 +435,6 @@ int diagfwd_peripheral_init(void) for (peripheral = 0; peripheral < NUM_PERIPHERALS; peripheral++) { for (type = 0; type < NUM_TYPES; type++) { - if (type == TYPE_CNTL) - continue; fwd_info = &peripheral_info[type][peripheral]; fwd_info->peripheral = peripheral; fwd_info->type = type; @@ -445,11 +443,16 @@ int diagfwd_peripheral_init(void) fwd_info->ch_open = 0; fwd_info->read_bytes = 0; fwd_info->write_bytes = 0; - fwd_info->inited = 1; spin_lock_init(&fwd_info->buf_lock); mutex_init(&fwd_info->data_mutex); + /* + * This state shouldn't be set for Control channels + * during initialization. This is set when the feature + * mask is received for the first time. + */ + if (type != TYPE_CNTL) + fwd_info->inited = 1; } - driver->diagfwd_data[peripheral] = &peripheral_info[TYPE_DATA][peripheral]; driver->diagfwd_cntl[peripheral] = @@ -631,12 +634,25 @@ void diagfwd_close_transport(uint8_t transport, uint8_t peripheral) } fwd_info = &early_init_info[transport_open][peripheral]; + if (fwd_info->p_ops && fwd_info->p_ops->close) + fwd_info->p_ops->close(fwd_info->ctxt); dest_info = &peripheral_info[TYPE_CNTL][peripheral]; - memcpy(dest_info, fwd_info, sizeof(struct diagfwd_info)); + dest_info->inited = 1; + dest_info->ctxt = fwd_info->ctxt; + dest_info->p_ops = fwd_info->p_ops; + dest_info->c_ops = fwd_info->c_ops; + dest_info->ch_open = fwd_info->ch_open; + dest_info->read_bytes = fwd_info->read_bytes; + dest_info->write_bytes = fwd_info->write_bytes; + dest_info->inited = fwd_info->inited; + dest_info->buf_1 = fwd_info->buf_1; + dest_info->buf_2 = fwd_info->buf_2; invalidate_fn(dest_info->ctxt, dest_info); - diagfwd_queue_read(dest_info); + diagfwd_late_open(dest_info); + diagfwd_cntl_open(dest_info); init_fn(peripheral); - diag_cntl_channel_open(dest_info); + diagfwd_queue_read(&peripheral_info[TYPE_DATA][peripheral]); + diagfwd_queue_read(&peripheral_info[TYPE_CMD][peripheral]); } int diagfwd_write(uint8_t peripheral, uint8_t type, void *buf, int len) From 41cbc77d94841990efaf159f8aa5706c194698ad Mon Sep 17 00:00:00 2001 From: Mohit Aggarwal Date: Sat, 13 Feb 2016 11:08:02 -0800 Subject: [PATCH 16/48] diag: Change to GFP_KERNEL in diagfwd_buffers_init() In diagfwd_buffers_init() change the memory allocation from GFP_ATOMIC to GFP_KERNEL. Change-Id: I8ea299a4287401a0a01ff7bbdd86c37ccd138480 Signed-off-by: Sreelakshmi Gownipalli Signed-off-by: Mohit Aggarwal --- drivers/char/diag/diagfwd_peripheral.c | 30 ++++++++++++-------------- drivers/char/diag/diagfwd_peripheral.h | 4 ++-- drivers/char/diag/diagfwd_socket.c | 10 +++------ 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c index 2bf85568936a..c9519dfc1186 100644 --- a/drivers/char/diag/diagfwd_peripheral.c +++ b/drivers/char/diag/diagfwd_peripheral.c @@ -428,7 +428,7 @@ int diagfwd_peripheral_init(void) fwd_info->inited = 1; fwd_info->read_bytes = 0; fwd_info->write_bytes = 0; - spin_lock_init(&fwd_info->buf_lock); + mutex_init(&fwd_info->buf_mutex); mutex_init(&fwd_info->data_mutex); } } @@ -443,7 +443,7 @@ int diagfwd_peripheral_init(void) fwd_info->ch_open = 0; fwd_info->read_bytes = 0; fwd_info->write_bytes = 0; - spin_lock_init(&fwd_info->buf_lock); + mutex_init(&fwd_info->buf_mutex); mutex_init(&fwd_info->data_mutex); /* * This state shouldn't be set for Control channels @@ -973,7 +973,6 @@ static void diagfwd_queue_read(struct diagfwd_info *fwd_info) void diagfwd_buffers_init(struct diagfwd_info *fwd_info) { - unsigned long flags; if (!fwd_info) return; @@ -984,10 +983,10 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) return; } - spin_lock_irqsave(&fwd_info->buf_lock, flags); + mutex_lock(&fwd_info->buf_mutex); if (!fwd_info->buf_1) { fwd_info->buf_1 = kzalloc(sizeof(struct diagfwd_buf_t), - GFP_ATOMIC); + GFP_KERNEL); if (!fwd_info->buf_1) goto err; kmemleak_not_leak(fwd_info->buf_1); @@ -995,7 +994,7 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) if (!fwd_info->buf_1->data) { fwd_info->buf_1->data = kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, - GFP_ATOMIC); + GFP_KERNEL); if (!fwd_info->buf_1->data) goto err; fwd_info->buf_1->len = PERIPHERAL_BUF_SZ; @@ -1007,7 +1006,7 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) if (fwd_info->type == TYPE_DATA) { if (!fwd_info->buf_2) { fwd_info->buf_2 = kzalloc(sizeof(struct diagfwd_buf_t), - GFP_ATOMIC); + GFP_KERNEL); if (!fwd_info->buf_2) goto err; kmemleak_not_leak(fwd_info->buf_2); @@ -1016,7 +1015,7 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) if (!fwd_info->buf_2->data) { fwd_info->buf_2->data = kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, - GFP_ATOMIC); + GFP_KERNEL); if (!fwd_info->buf_2->data) goto err; fwd_info->buf_2->len = PERIPHERAL_BUF_SZ; @@ -1032,7 +1031,7 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) fwd_info->buf_1->data_raw = kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, - GFP_ATOMIC); + GFP_KERNEL); if (!fwd_info->buf_1->data_raw) goto err; fwd_info->buf_1->len_raw = PERIPHERAL_BUF_SZ; @@ -1042,7 +1041,7 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) fwd_info->buf_2->data_raw = kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, - GFP_ATOMIC); + GFP_KERNEL); if (!fwd_info->buf_2->data_raw) goto err; fwd_info->buf_2->len_raw = PERIPHERAL_BUF_SZ; @@ -1056,7 +1055,7 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) if (!fwd_info->buf_1->data_raw) { fwd_info->buf_1->data_raw = kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, - GFP_ATOMIC); + GFP_KERNEL); if (!fwd_info->buf_1->data_raw) goto err; fwd_info->buf_1->len_raw = PERIPHERAL_BUF_SZ; @@ -1064,11 +1063,11 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) } } - spin_unlock_irqrestore(&fwd_info->buf_lock, flags); + mutex_unlock(&fwd_info->buf_mutex); return; err: - spin_unlock_irqrestore(&fwd_info->buf_lock, flags); + mutex_unlock(&fwd_info->buf_mutex); diagfwd_buffers_exit(fwd_info); return; @@ -1076,12 +1075,11 @@ err: static void diagfwd_buffers_exit(struct diagfwd_info *fwd_info) { - unsigned long flags; if (!fwd_info) return; - spin_lock_irqsave(&fwd_info->buf_lock, flags); + mutex_lock(&fwd_info->buf_mutex); if (fwd_info->buf_1) { kfree(fwd_info->buf_1->data); fwd_info->buf_1->data = NULL; @@ -1098,6 +1096,6 @@ static void diagfwd_buffers_exit(struct diagfwd_info *fwd_info) kfree(fwd_info->buf_2); fwd_info->buf_2 = NULL; } - spin_unlock_irqrestore(&fwd_info->buf_lock, flags); + mutex_unlock(&fwd_info->buf_mutex); } diff --git a/drivers/char/diag/diagfwd_peripheral.h b/drivers/char/diag/diagfwd_peripheral.h index dc50d70e80b4..8a90c5a66740 100644 --- a/drivers/char/diag/diagfwd_peripheral.h +++ b/drivers/char/diag/diagfwd_peripheral.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, 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 @@ -67,7 +67,7 @@ struct diagfwd_info { atomic_t opened; unsigned long read_bytes; unsigned long write_bytes; - spinlock_t buf_lock; + struct mutex buf_mutex; struct mutex data_mutex; void *ctxt; struct diagfwd_buf_t *buf_1; diff --git a/drivers/char/diag/diagfwd_socket.c b/drivers/char/diag/diagfwd_socket.c index 6889d257867f..2707601ddff0 100644 --- a/drivers/char/diag/diagfwd_socket.c +++ b/drivers/char/diag/diagfwd_socket.c @@ -226,13 +226,6 @@ static void socket_data_ready(struct sock *sk_ptr, int bytes) spin_unlock_irqrestore(&info->lock, flags); diag_ws_on_notify(); - /* - * Initialize read buffers for the servers. The servers must read data - * first to get the address of its clients. - */ - if (!atomic_read(&info->opened) && info->port_type == PORT_TYPE_SERVER) - diagfwd_buffers_init(info->fwd_ctxt); - queue_work(info->wq, &(info->read_work)); wake_up_interruptible(&info->read_wait_q); return; @@ -621,6 +614,9 @@ static void socket_read_work_fn(struct work_struct *work) if (!info) return; + if (!atomic_read(&info->opened) && info->port_type == PORT_TYPE_SERVER) + diagfwd_buffers_init(info->fwd_ctxt); + diagfwd_channel_read(info->fwd_ctxt); } From 0c5293afc21bf261150692bf132cc4e1c0467812 Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Fri, 17 Jun 2016 10:33:45 -0700 Subject: [PATCH 17/48] msm: mdss: Fix memleak in framebuffer register and remove In FB registration, free allocated memory if an error condition is hit. Also free allocated memory in FB remove. Change-Id: I533e2d6a760ebd52047c521c1a1e85bfc754fce1 Signed-off-by: Krishna Srinivas --- drivers/video/msm/mdss/mdss_dsi.c | 1 + drivers/video/msm/mdss/mdss_fb.c | 2 ++ drivers/video/msm/mdss/mdss_panel.c | 11 ++++++++--- drivers/video/msm/mdss/mdss_panel.h | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c index 088f21aed555..aac9eeb6c67b 100644 --- a/drivers/video/msm/mdss/mdss_dsi.c +++ b/drivers/video/msm/mdss/mdss_dsi.c @@ -971,6 +971,7 @@ static void mdss_dsi_debugfs_cleanup(struct mdss_dsi_ctrl_pdata *ctrl_pdata) struct mdss_dsi_debugfs_info *dfs = ctrl->debugfs_info; if (dfs && dfs->root) debugfs_remove_recursive(dfs->root); + kfree(dfs); pdata = pdata->next; } while (pdata); pr_debug("%s: Cleaned up mdss_dsi_debugfs_info\n", __func__); diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index f9a0885e4da3..42cc23e9adc4 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -1032,6 +1032,8 @@ static int mdss_fb_remove(struct platform_device *pdev) if (mfd->key != MFD_KEY) return -EINVAL; + mdss_panel_debugfs_cleanup(mfd->panel_info); + if (mdss_fb_suspend_sub(mfd)) pr_err("msm_fb_remove: can't stop the device %d\n", mfd->index); diff --git a/drivers/video/msm/mdss/mdss_panel.c b/drivers/video/msm/mdss/mdss_panel.c index 85cc6f6de08b..a881d5ffea00 100644 --- a/drivers/video/msm/mdss/mdss_panel.c +++ b/drivers/video/msm/mdss/mdss_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 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 @@ -435,6 +435,7 @@ int mdss_panel_debugfs_setup(struct mdss_panel_info *panel_info, struct dentry return -ENOMEM; } + debugfs_info->parent = parent; debugfs_info->root = debugfs_create_dir(intf_str, parent); if (IS_ERR_OR_NULL(debugfs_info->root)) { pr_err("Debugfs create dir failed with error: %ld\n", @@ -484,6 +485,7 @@ int mdss_panel_debugfs_init(struct mdss_panel_info *panel_info, intf_str); if (rc) { pr_err("error in initilizing panel debugfs\n"); + mdss_panel_debugfs_cleanup(&pdata->panel_info); return rc; } pdata = pdata->next; @@ -497,13 +499,16 @@ void mdss_panel_debugfs_cleanup(struct mdss_panel_info *panel_info) { struct mdss_panel_data *pdata; struct mdss_panel_debugfs_info *debugfs_info; + struct dentry *parent = NULL; pdata = container_of(panel_info, struct mdss_panel_data, panel_info); do { debugfs_info = pdata->panel_info.debugfs_info; - if (debugfs_info && debugfs_info->root) - debugfs_remove_recursive(debugfs_info->root); + if (debugfs_info && !parent) + parent = debugfs_info->parent; + kfree(debugfs_info); pdata = pdata->next; } while (pdata); + debugfs_remove_recursive(parent); pr_debug("Cleaned up mdss_panel_debugfs_info\n"); } diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h index e7616ff5fb40..242ba2ba16b8 100644 --- a/drivers/video/msm/mdss/mdss_panel.h +++ b/drivers/video/msm/mdss/mdss_panel.h @@ -570,6 +570,7 @@ struct mdss_panel_data { struct mdss_panel_debugfs_info { struct dentry *root; + struct dentry *parent; struct mdss_panel_info panel_info; u32 override_flag; struct mdss_panel_debugfs_info *next; From caba62ac7d23070a0c79b419336726edd9685117 Mon Sep 17 00:00:00 2001 From: Shalini Krishnamoorthi Date: Tue, 2 Aug 2016 10:29:00 -0700 Subject: [PATCH 18/48] msm: mdss: Fix to validate data copied from user space The overlay zorder values copied from user space are used as index in left_lm_zo_cnt and right_lm_zo_cnt. This fix will validate the overlay zorder value copied from user space to not go beyond MDSS_MDP_MAX_STAGE, thus preventing any arbitrary increments in kernel memory. CRs-Fixed: 1049232 Change-Id: Ie8e65ce9f58cb357204bfa4c6a6e0fccec82d5ba Signed-off-by: Shalini Krishnamoorthi --- drivers/video/msm/mdss/mdss_mdp_overlay.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index f98d2497db54..d26e88b6d2bc 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -4159,16 +4159,20 @@ static int __mdss_overlay_src_split_sort(struct msm_fb_data_type *mfd, __overlay_swap_func); for (i = 0; i < num_ovs; i++) { + if (ovs[i].z_order >= MDSS_MDP_MAX_STAGE) { + pr_err("invalid stage:%u\n", ovs[i].z_order); + return -EINVAL; + } if (ovs[i].dst_rect.x < left_lm_w) { if (left_lm_zo_cnt[ovs[i].z_order] == 2) { - pr_err("more than 2 ov @ stage%d on left lm\n", + pr_err("more than 2 ov @ stage%u on left lm\n", ovs[i].z_order); return -EINVAL; } left_lm_zo_cnt[ovs[i].z_order]++; } else { if (right_lm_zo_cnt[ovs[i].z_order] == 2) { - pr_err("more than 2 ov @ stage%d on right lm\n", + pr_err("more than 2 ov @ stage%u on right lm\n", ovs[i].z_order); return -EINVAL; } From 74a7ba4fb6df1e647fe0c655b0361a1da8e1efef Mon Sep 17 00:00:00 2001 From: Srinivasarao P Date: Fri, 22 Jul 2016 12:48:33 +0530 Subject: [PATCH 19/48] msm: dma_test: Initialize newly allocated memory The MSM_DMA_IOALLOC ioctl command allocates kernel memory and this memory can be read back using the MSM_DMA_IORBUF ioctl command. This memory is not zero-initialized and may contain sensitive data. Change-Id: I8c55d6fe500e7607690b89806715893783eecf9c Signed-off-by: Srinivasarao P --- arch/arm/mach-msm/dma_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-msm/dma_test.c b/arch/arm/mach-msm/dma_test.c index 3d13e4e3cdc7..1d717c360c8c 100644 --- a/arch/arm/mach-msm/dma_test.c +++ b/arch/arm/mach-msm/dma_test.c @@ -99,7 +99,7 @@ static int buffer_req(struct msm_dma_alloc_req *req) if (i >= MAX_TEST_BUFFERS) goto error; - buffers[i] = kmalloc(req->size, GFP_KERNEL | __GFP_DMA); + buffers[i] = kzalloc(req->size, GFP_KERNEL | __GFP_DMA); if (buffers[i] == 0) goto error; sizes[i] = req->size; From b79a74f3b9b767108dadb8867b72bdadb8a05169 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Devarakonda Date: Mon, 18 Apr 2016 17:53:12 +0530 Subject: [PATCH 20/48] msm: mdss: Fix potential NULL pointer dereferences Fixing potential NULL pointer dereferences in MDSS driver. Change-Id: Idbb3b2524b3c2165e9922d934047b7ba46141a6c Signed-off-by: Krishna Chaitanya Devarakonda --- drivers/video/msm/msm_dba/adv7533.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/msm/msm_dba/adv7533.c b/drivers/video/msm/msm_dba/adv7533.c index a00799b7e369..7cead00b9012 100644 --- a/drivers/video/msm/msm_dba/adv7533.c +++ b/drivers/video/msm/msm_dba/adv7533.c @@ -724,8 +724,8 @@ static void adv7533_handle_cec_intr(struct adv7533 *pdata, u8 cec_status) { u8 cec_int_clear = 0x08; bool cec_rx_intr = false; - u8 cec_rx_ready; - u8 cec_rx_timestamp; + u8 cec_rx_ready = 0; + u8 cec_rx_timestamp = 0; int ret = 0; if (!pdata) { @@ -828,7 +828,7 @@ end: static void *adv7533_handle_hpd_intr(struct adv7533 *pdata) { - int ret; + int ret = 0; u8 hpd_state; u8 connected = 0, disconnected = 0; From 7d897b4d38b1abf63a22b391fee95a38ba51631d Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Fri, 18 Mar 2016 13:10:53 +0530 Subject: [PATCH 21/48] msm: mdss: update rotator frame rate in the pipe configuration Update rotator frame rate in pipe and control data structures which is used for OT calculation. Change-Id: I76ded6bb0b4a6cebd3e7fbb428997195950a18b4 Signed-off-by: Jayant Shekhar --- drivers/video/msm/mdss/mdss_mdp.c | 6 +++--- drivers/video/msm/mdss/mdss_mdp_intf_writeback.c | 4 ++-- drivers/video/msm/mdss/mdss_mdp_pipe.c | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index 09e3d25460c2..440b48eec8c4 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -1,7 +1,7 @@ /* * MDSS MDP Interface (used by framebuffer core) * - * Copyright (c) 2007-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2007-2016, The Linux Foundation. All rights reserved. * Copyright (C) 2007 Google Incorporated * * This software is licensed under the terms of the GNU General Public @@ -3601,9 +3601,9 @@ static void apply_dynamic_ot_limit(u32 *ot_lim, res = params->width * params->height; - pr_debug("w:%d h:%d rot:%d yuv:%d wb:%d res:%d\n", + pr_debug("w:%d h:%d rot:%d yuv:%d wb:%d res:%d fps:%d\n", params->width, params->height, params->is_rot, - params->is_yuv, params->is_wb, res); + params->is_yuv, params->is_wb, res, params->frame_rate); switch (mdata->mdp_rev) { case MDSS_MDP_HW_REV_111: diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c index cfe54f411ad4..2f3ae0686f86 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -330,7 +330,7 @@ static int mdss_mdp_writeback_prepare_rot(struct mdss_mdp_ctl *ctl, void *arg) ctx->bwc_mode = rot->bwc_mode; ctx->opmode |= ctx->bwc_mode; - + ctx->frame_rate = ctl->frame_rate; ctx->width = ctx->dst_rect.w = rot->dnsc_factor_w ? rot->dst.w / rot->dnsc_factor_w : rot->dst.w; ctx->height = ctx->dst_rect.h = rot->dnsc_factor_h ? diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c index e5389b4a1c38..2f6235268459 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pipe.c +++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -1779,6 +1779,7 @@ static void mdss_mdp_set_ot_limit_pipe(struct mdss_mdp_pipe *pipe) ot_params.is_rot = pipe->mixer_left->rotator_mode; ot_params.is_wb = ctl->intf_num == MDSS_MDP_NO_INTF; ot_params.is_yuv = pipe->src_fmt->is_yuv; + ot_params.frame_rate = pipe->frame_rate; mdss_mdp_set_ot_limit(&ot_params); } From 352507518e67a07287e224e2325bcd375863adfb Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Wed, 10 Aug 2016 15:28:50 +0530 Subject: [PATCH 22/48] power: qpnp-smbcharger: Handle USB removal during pulsing Handle removal of USB during QC 3.0 pulsing operation. While at it, cancel hvdcp detection work before updating input status to USB driver on charger removal. CRs-Fixed: 1011956 Change-Id: I28cf37e60746eab126e7cd6822de9b35b8f832bf Signed-off-by: Anirudh Ghayal Signed-off-by: Ashay Jaiswal --- drivers/power/qpnp-smbcharger.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/power/qpnp-smbcharger.c b/drivers/power/qpnp-smbcharger.c index de95e6f74d1f..5b7cbd4ff4af 100644 --- a/drivers/power/qpnp-smbcharger.c +++ b/drivers/power/qpnp-smbcharger.c @@ -4467,6 +4467,8 @@ static void handle_usb_removal(struct smbchg_chip *chip) /* Clear the OV detected status set before */ if (chip->usb_ov_det) chip->usb_ov_det = false; + /* cancel/wait for hvdcp pending work if any */ + cancel_delayed_work_sync(&chip->hvdcp_det_work); smbchg_change_usb_supply_type(chip, POWER_SUPPLY_TYPE_UNKNOWN); if (!chip->skip_usb_notification) { pr_smb(PR_MISC, "setting usb psy present = %d\n", @@ -5281,6 +5283,10 @@ static int smbchg_prepare_for_pulsing_lite(struct smbchg_chip *chip) out: chip->hvdcp_3_det_ignore_uv = false; restore_from_hvdcp_detection(chip); + if (!is_src_detect_high(chip)) { + pr_smb(PR_MISC, "HVDCP removed - force removal\n"); + update_usb_status(chip, 0, true); + } return rc; } @@ -5300,6 +5306,10 @@ static int smbchg_unprepare_for_pulsing_lite(struct smbchg_chip *chip) if (rc < 0) pr_err("Couldn't retract HVDCP ICL vote rc=%d\n", rc); + if (!is_src_detect_high(chip)) { + pr_smb(PR_MISC, "HVDCP removed\n"); + update_usb_status(chip, 0, 0); + } /* This could be because allow_hvdcp3 set to false runtime */ if (is_usb_present(chip) && !chip->allow_hvdcp3_detection) smbchg_handle_hvdcp3_disable(chip); From d7c30d92d7f7819916819a194cad4fe0cfe09507 Mon Sep 17 00:00:00 2001 From: Neil Leeder Date: Thu, 24 Sep 2015 12:14:20 -0400 Subject: [PATCH 23/48] perf: stop deadlock when cpu_up fails When an attempt is made to free an event on a CPU which is no longer online, perf tries to bring the CPU online. This can fail, resulting in an UP_CANCELLED notifier, which eventually tries to acquire the ctx->mutex which is already being held by the cpu_up code. Removing the attempt to bring the cpu up will remove this deadlock, but also requires temporarily removing support of counting events across hotplug. This will be restored in a later patch. CRs-fixed: 912295 Change-Id: Iaafa3c6688d26508857472fd5bb32139a137880e Signed-off-by: Neil Leeder --- arch/arm64/kernel/perf_event.c | 1 - kernel/events/core.c | 29 ----------------------------- kernel/events/hw_breakpoint.c | 1 - 3 files changed, 31 deletions(-) diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index f075eceae8bf..4428c9617fdd 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -609,7 +609,6 @@ static void __init armpmu_init(struct arm_pmu *armpmu) .start = armpmu_start, .stop = armpmu_stop, .read = armpmu_read, - .events_across_hotplug = 1, }; } diff --git a/kernel/events/core.c b/kernel/events/core.c index 0b1df50a6129..7ab36de04a87 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1408,29 +1408,6 @@ static int __perf_remove_from_context(void *info) return 0; } -#ifdef CONFIG_SMP -static void perf_retry_remove(struct remove_event *rep) -{ - int up_ret; - struct perf_event *event = rep->event; - /* - * CPU was offline. Bring it online so we can - * gracefully exit a perf context. - */ - up_ret = cpu_up(event->cpu); - if (!up_ret) - /* Try the remove call once again. */ - cpu_function_call(event->cpu, __perf_remove_from_context, rep); - else - pr_err("Failed to bring up CPU: %d, ret: %d\n", - event->cpu, up_ret); -} -#else -static void perf_retry_remove(struct remove_event *rep) -{ -} -#endif - /* * Remove the event from a task's (or a CPU's) list of events. * @@ -1462,8 +1439,6 @@ static void __ref perf_remove_from_context(struct perf_event *event, bool detach */ ret = cpu_function_call(event->cpu, __perf_remove_from_context, &re); - if (ret == -ENXIO) - perf_retry_remove(&re); return; } @@ -5760,7 +5735,6 @@ static struct pmu perf_swevent = { .read = perf_swevent_read, .event_idx = perf_swevent_event_idx, - .events_across_hotplug = 1, }; #ifdef CONFIG_EVENT_TRACING @@ -5880,7 +5854,6 @@ static struct pmu perf_tracepoint = { .read = perf_swevent_read, .event_idx = perf_swevent_event_idx, - .events_across_hotplug = 1, }; static inline void perf_tp_register(void) @@ -6108,7 +6081,6 @@ static struct pmu perf_cpu_clock = { .read = cpu_clock_event_read, .event_idx = perf_swevent_event_idx, - .events_across_hotplug = 1, }; /* @@ -6189,7 +6161,6 @@ static struct pmu perf_task_clock = { .read = task_clock_event_read, .event_idx = perf_swevent_event_idx, - .events_across_hotplug = 1, }; static void perf_pmu_nop_void(struct pmu *pmu) diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index 1021bca062c4..20185ea64aa6 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c @@ -646,7 +646,6 @@ static struct pmu perf_breakpoint = { .read = hw_breakpoint_pmu_read, .event_idx = hw_breakpoint_event_idx, - .events_across_hotplug = 1, }; int __init init_hw_breakpoint(void) From 7a6f1195f47207ebbefa579755412f3a6dfbdb28 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 Jan 2016 16:30:58 +0100 Subject: [PATCH 24/48] ALSA: timer: Harden slave timer list handling A slave timer instance might be still accessible in a racy way while operating the master instance as it lacks of locking. Since the master operation is mostly protected with timer->lock, we should cope with it while changing the slave instance, too. Also, some linked lists (active_list and ack_list) of slave instances aren't unlinked immediately at stopping or closing, and this may lead to unexpected accesses. This patch tries to address these issues. It adds spin lock of timer->lock (either from master or slave, which is equivalent) in a few places. For avoiding a deadlock, we ensure that the global slave_active_lock is always locked at first before each timer lock. Also, ack and active_list of slave instances are properly unlinked at snd_timer_stop() and snd_timer_close(). Last but not least, remove the superfluous call of _snd_timer_stop() at removing slave links. This is a noop, and calling it may confuse readers wrt locking. Further cleanup will follow in a later patch. Actually we've got reports of use-after-free by syzkaller fuzzer, and this hopefully fixes these issues. Reported-by: Dmitry Vyukov Cc: Signed-off-by: Takashi Iwai (cherry picked from commit b5a663aa426f4884c71cd8580adae73f33570f0d) Change-Id: I7e7e4e1ab476f93131111d60d8f4e6a1add43193 Signed-off-by: Dennis Cagle --- sound/core/timer.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index 6ddcf06f52f9..38a137d6b04f 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -215,11 +215,13 @@ static void snd_timer_check_master(struct snd_timer_instance *master) slave->slave_id == master->slave_id) { list_move_tail(&slave->open_list, &master->slave_list_head); spin_lock_irq(&slave_active_lock); + spin_lock(&master->timer->lock); slave->master = master; slave->timer = master->timer; if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) list_add_tail(&slave->active_list, &master->slave_active_head); + spin_unlock(&master->timer->lock); spin_unlock_irq(&slave_active_lock); } } @@ -345,15 +347,18 @@ int snd_timer_close(struct snd_timer_instance *timeri) timer->hw.close) timer->hw.close(timer); /* remove slave links */ + spin_lock_irq(&slave_active_lock); + spin_lock(&timer->lock); list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, open_list) { - spin_lock_irq(&slave_active_lock); - _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION); list_move_tail(&slave->open_list, &snd_timer_slave_list); slave->master = NULL; slave->timer = NULL; - spin_unlock_irq(&slave_active_lock); + list_del_init(&slave->ack_list); + list_del_init(&slave->active_list); } + spin_unlock(&timer->lock); + spin_unlock_irq(&slave_active_lock); mutex_unlock(®ister_mutex); } out: @@ -440,9 +445,12 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri) spin_lock_irqsave(&slave_active_lock, flags); timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; - if (timeri->master) + if (timeri->master && timeri->timer) { + spin_lock(&timeri->timer->lock); list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); + spin_unlock(&timeri->timer->lock); + } spin_unlock_irqrestore(&slave_active_lock, flags); return 1; /* delayed start */ } @@ -488,6 +496,8 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri, if (!keep_flag) { spin_lock_irqsave(&slave_active_lock, flags); timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; + list_del_init(&timeri->ack_list); + list_del_init(&timeri->active_list); spin_unlock_irqrestore(&slave_active_lock, flags); } goto __end; From c92895100f05d155c502137a5e696aa8569ecbfd Mon Sep 17 00:00:00 2001 From: Carter Cooper Date: Mon, 20 Jun 2016 15:25:45 -0600 Subject: [PATCH 25/48] msm: kgsl: Allow 0 as a valid ion file descriptor Treat 0 as a valid fd instead of treating it as an error. CRs-Fixed: 1030098 Change-Id: I4a1b14fcbca617bc2a43b30af7256edc3920f04c Signed-off-by: Carter Cooper --- drivers/gpu/msm/kgsl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index dab99c5a0d21..270cda5f67d9 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2336,7 +2336,7 @@ static long _gpuobj_map_dma_buf(struct kgsl_device *device, if (ret) return ret; - if (buf.fd == 0) + if (buf.fd < 0) return -EINVAL; *fd = buf.fd; From b59351dfdfb421ff42c773f0302f979ee6e53c29 Mon Sep 17 00:00:00 2001 From: Mohamad Ayyash Date: Tue, 24 May 2016 12:57:16 -0700 Subject: [PATCH 26/48] Replace %p with %pK to prevent leaking kernel address BUG: 27532522 Change-Id: Ic0710a9a8cfc682acd88ecf3bbfeece2d798c4a4 Signed-off-by: Mohamad Ayyash --- net/netfilter/xt_qtaguid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index af27fa819040..b895156c4909 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -1928,7 +1928,7 @@ static int qtaguid_ctrl_proc_show(struct seq_file *m, void *v) ); f_count = atomic_long_read( &sock_tag_entry->socket->file->f_count); - seq_printf(m, "sock=%p tag=0x%llx (uid=%u) pid=%u " + seq_printf(m, "sock=%pK tag=0x%llx (uid=%u) pid=%u " "f_count=%lu\n", sock_tag_entry->sk, sock_tag_entry->tag, uid, From b47707bd6205051f3b148a157ff32050b6d76189 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 19 Jul 2016 13:39:29 +0530 Subject: [PATCH 27/48] USB: usbfs: fix potential infoleak in devio The stack object "ci" has a total size of 8 bytes. Its last 3 bytes are padding bytes which are not initialized and leaked to userland via "copy_to_user". Change-Id: Iedd743ab04eb30b6133fc45bb549fcbae60c12fa Signed-off-by: Kangjie Lu Signed-off-by: Greg Kroah-Hartman Git-commit: 681fef8380eb818c0b845fca5d2ab1dcbab114ee Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Ravi Kumar Siddojigari --- drivers/usb/core/devio.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 78ddfb43750a..4ccdd01fd0b7 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1106,10 +1106,11 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg) static int proc_connectinfo(struct dev_state *ps, void __user *arg) { - struct usbdevfs_connectinfo ci = { - .devnum = ps->dev->devnum, - .slow = ps->dev->speed == USB_SPEED_LOW - }; + struct usbdevfs_connectinfo ci; + + memset(&ci, 0, sizeof(ci)); + ci.devnum = ps->dev->devnum; + ci.slow = ps->dev->speed == USB_SPEED_LOW; if (copy_to_user(arg, &ci, sizeof(ci))) return -EFAULT; From b2c88daae2740e4f6b14878102b3bc29f81470e7 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 23 Apr 2015 12:46:16 +0100 Subject: [PATCH 28/48] arm64: dma-mapping: always clear allocated buffers [ Upstream commit 6829e274a623187c24f7cfc0e3d35f25d087fcc5 ] Buffers allocated by dma_alloc_coherent() are always zeroed on Alpha, ARM (32bit), MIPS, PowerPC, x86/x86_64 and probably other architectures. It turned out that some drivers rely on this 'feature'. Allocated buffer might be also exposed to userspace with dma_mmap() call, so clearing it is desired from security point of view to avoid exposing random memory to userspace. This patch unifies dma_alloc_coherent() behavior on ARM64 architecture with other implementations by unconditionally zeroing allocated buffer. CRs-Fixed: 1041735 Change-Id: I74bf024e0f603ca8c0b05430dc2ee154d579cfb2 Cc: # v3.14+ Signed-off-by: Marek Szyprowski Signed-off-by: Will Deacon Signed-off-by: Sasha Levin Git-commit: a142e9641dcbead2c8845c949ad518acac96ed28 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git [lmark@codeaurora.org: resolve merge conflicts] Signed-off-by: Liam Mark --- arch/arm64/mm/dma-mapping.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 6c8410754228..94c6f8b64c81 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -88,6 +88,7 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page) if (pageno < pool->nr_pages) { bitmap_set(pool->bitmap, pageno, count); ptr = pool->vaddr + PAGE_SIZE * pageno; + memset(ptr, 0, size); *ret_page = pool->pages[pageno]; } else { pr_err_once("ERROR: %u KiB atomic DMA coherent pool is too small!\n" @@ -208,6 +209,7 @@ static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size, page = pfn_to_page(pfn); addr = page_address(page); + memset(addr, 0, size); if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs) || dma_get_attr(DMA_ATTR_STRONGLY_ORDERED, attrs)) { From c3ba433a042c2efd92e53a04ffe653dc6b5dc24c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Mar 2015 17:41:43 +0000 Subject: [PATCH 29/48] net: validate the range we feed to iov_iter_init() in sys_sendto/sys_recvfrom b/28759139 Cc: stable@vger.kernel.org # v3.19 Signed-off-by: Al Viro Signed-off-by: David S. Miller Signed-off-by: Dennis Cagle Git-commit: 4de930efc23b92ddf88ce91c405ee645fe6e27ea Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git (cherry picked from commit 4de930efc23b92ddf88ce91c405ee645fe6e27ea) Change-Id: I81577c193559f93826c5e85aa2cb06271340a2e8 --- net/socket.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/socket.c b/net/socket.c index d87fdd37e5f6..2bb9e3019c94 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1798,6 +1798,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, if (len > INT_MAX) len = INT_MAX; + if (unlikely(!access_ok(VERIFY_READ, buff, len))) + return -EFAULT; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; @@ -1857,6 +1859,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, if (size > INT_MAX) size = INT_MAX; + if (unlikely(!access_ok(VERIFY_WRITE, ubuf, size))) + return -EFAULT; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; From 04471f084870904d0c3eceafe7eafb1508cd3b3f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 12 Jan 2016 15:36:27 +0100 Subject: [PATCH 30/48] ALSA: seq: Fix race at timer setup and close ALSA sequencer code has an open race between the timer setup ioctl and the close of the client. This was triggered by syzkaller fuzzer, and a use-after-free was caught there as a result. This patch papers over it by adding a proper queue->timer_mutex lock around the timer-related calls in the relevant code path. b/28695438 Reported-by: Dmitry Vyukov Tested-by: Dmitry Vyukov Cc: Git-commit: 3567eb6af614dac436c4b16a8d426f9faed639b3 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Takashi Iwai Signed-off-by: Dennis Cagle (cherry picked from commit 3567eb6af614dac436c4b16a8d426f9faed639b3) Change-Id: I398dd27dcdd1241917fd6d127b2debffc2afd413 --- sound/core/seq/seq_queue.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index f9077361c119..4c9aa462de9b 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -144,8 +144,10 @@ static struct snd_seq_queue *queue_new(int owner, int locked) static void queue_delete(struct snd_seq_queue *q) { /* stop and release the timer */ + mutex_lock(&q->timer_mutex); snd_seq_timer_stop(q->timer); snd_seq_timer_close(q); + mutex_unlock(&q->timer_mutex); /* wait until access free */ snd_use_lock_sync(&q->use_lock); /* release resources... */ From 643acb2111b157a94386b1466edaf1ab70a1d882 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Jan 2016 17:48:01 +0100 Subject: [PATCH 31/48] ALSA: timer: Fix race among timer ioctls ALSA timer ioctls have an open race and this may lead to a use-after-free of timer instance object. A simplistic fix is to make each ioctl exclusive. We have already tread_sem for controlling the tread, and extend this as a global mutex to be applied to each ioctl. The downside is, of course, the worse concurrency. But these ioctls aren't to be parallel accessible, in anyway, so it should be fine to serialize there. b/28694392 Reported-by: Dmitry Vyukov Tested-by: Dmitry Vyukov Cc: Git-commit: af368027a49a751d6ff4ee9e3f9961f35bb4fede Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Takashi Iwai Signed-off-by: Dennis Cagle (cherry picked from commit af368027a49a751d6ff4ee9e3f9961f35bb4fede) Change-Id: I9d45e3d142b42d5dee6ae54c25e78504c871eef8 --- sound/core/timer.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index 38a137d6b04f..1d5461719e31 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -73,7 +73,7 @@ struct snd_timer_user { struct timespec tstamp; /* trigger tstamp */ wait_queue_head_t qchange_sleep; struct fasync_struct *fasync; - struct mutex tread_sem; + struct mutex ioctl_lock; }; /* list of timers */ @@ -1266,7 +1266,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) return -ENOMEM; spin_lock_init(&tu->qlock); init_waitqueue_head(&tu->qchange_sleep); - mutex_init(&tu->tread_sem); + mutex_init(&tu->ioctl_lock); tu->ticks = 1; tu->queue_size = 128; tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), @@ -1286,8 +1286,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file) if (file->private_data) { tu = file->private_data; file->private_data = NULL; + mutex_lock(&tu->ioctl_lock); if (tu->timeri) snd_timer_close(tu->timeri); + mutex_unlock(&tu->ioctl_lock); kfree(tu->queue); kfree(tu->tqueue); kfree(tu); @@ -1525,7 +1527,6 @@ static int snd_timer_user_tselect(struct file *file, int err = 0; tu = file->private_data; - mutex_lock(&tu->tread_sem); if (tu->timeri) { snd_timer_close(tu->timeri); tu->timeri = NULL; @@ -1569,7 +1570,6 @@ static int snd_timer_user_tselect(struct file *file, } __err: - mutex_unlock(&tu->tread_sem); return err; } @@ -1782,7 +1782,7 @@ enum { SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), }; -static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, +static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct snd_timer_user *tu; @@ -1799,17 +1799,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, { int xarg; - mutex_lock(&tu->tread_sem); - if (tu->timeri) { /* too late */ - mutex_unlock(&tu->tread_sem); + if (tu->timeri) /* too late */ return -EBUSY; - } - if (get_user(xarg, p)) { - mutex_unlock(&tu->tread_sem); + if (get_user(xarg, p)) return -EFAULT; - } tu->tread = xarg ? 1 : 0; - mutex_unlock(&tu->tread_sem); return 0; } case SNDRV_TIMER_IOCTL_GINFO: @@ -1842,6 +1836,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, return -ENOTTY; } +static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct snd_timer_user *tu = file->private_data; + long ret; + + mutex_lock(&tu->ioctl_lock); + ret = __snd_timer_user_ioctl(file, cmd, arg); + mutex_unlock(&tu->ioctl_lock); + return ret; +} + static int snd_timer_user_fasync(int fd, struct file * file, int on) { struct snd_timer_user *tu; From c55763e4f73b5d082f1a8ad49005a4996c612511 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 19 Jan 2016 21:35:15 +0000 Subject: [PATCH 32/48] BACKPORT: perf tools: Document the perf sysctls perf_event_paranoid was only documented in source code and a perf error message. Copy the documentation from the error message to Documentation/sysctl/kernel.txt. Conflicts: Documentation/sysctl/kernel.txt tools/perf/util/evsel.c Signed-off-by: Ben Hutchings Cc: Peter Zijlstra Cc: linux-doc@vger.kernel.org Link: http://lkml.kernel.org/r/20160119213515.GG2637@decadent.org.uk [ Remove reference to external Documentation file, provide info inline, as before ] Signed-off-by: Arnaldo Carvalho de Melo Bug: 29054680 Bug: 29119870 Signed-off-by: Dennis Cagle Change-Id: I13e73cfb2ad761c94762d0c8196df7725abdf5c5 (cherry picked from commit 746938f9d97d74f6c2833a0ede49506bdfcd89e4) --- Documentation/sysctl/kernel.txt | 41 +++++++++++++++++++++------------ tools/perf/util/evsel.c | 15 +++++++----- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 550ece773ff1..942d769b78b2 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -51,8 +51,9 @@ show up in /proc/sys/kernel: - overflowuid - panic - panic_on_oops -- panic_on_unrecovered_nmi - panic_on_stackoverflow +- panic_on_unrecovered_nmi +- perf_event_paranoid - pid_max - powersave-nap [ PPC only ] - printk @@ -427,19 +428,6 @@ the recommended setting is 60. ============================================================== -panic_on_unrecovered_nmi: - -The default Linux behaviour on an NMI of either memory or unknown is -to continue operation. For many environments such as scientific -computing it is preferable that the box is taken out and the error -dealt with than an uncorrected parity/ECC error get propagated. - -A small number of systems do generate NMI's for bizarre random reasons -such as power management so the default is off. That sysctl works like -the existing panic controls already in that directory. - -============================================================== - panic_on_oops: Controls the kernel's behaviour when an oops or BUG is encountered. @@ -459,7 +447,6 @@ This file shows up if CONFIG_DEBUG_STACKOVERFLOW is enabled. 0: try to continue operation. -1: panic immediately. ============================================================== @@ -489,6 +476,30 @@ allowed to execute. ============================================================== +panic_on_unrecovered_nmi: + +The default Linux behaviour on an NMI of either memory or unknown is +to continue operation. For many environments such as scientific +computing it is preferable that the box is taken out and the error +dealt with than an uncorrected parity/ECC error get propagated. + +A small number of systems do generate NMI's for bizarre random reasons +such as power management so the default is off. That sysctl works like +the existing panic controls already in that directory. + +============================================================== + +perf_event_paranoid: + +Controls use of the performance events system by unprivileged +users (without CAP_SYS_ADMIN). The default value is 1. + + -1: Allow use of (almost) all events by all users +>=0: Disallow raw tracepoint access by users without CAP_IOC_LOCK +>=1: Disallow CPU event access by users without CAP_SYS_ADMIN +>=2: Disallow kernel profiling by users without CAP_SYS_ADMIN + +============================================================== pid_max: diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 63b6f8c8edf2..54494df33dd2 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1515,12 +1515,15 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, case EPERM: case EACCES: return scnprintf(msg, size, - "You may not have permission to collect %sstats.\n" - "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" - " -1 - Not paranoid at all\n" - " 0 - Disallow raw tracepoint access for unpriv\n" - " 1 - Disallow cpu events for unpriv\n" - " 2 - Disallow kernel profiling for unpriv", + "You may not have permission to collect %sstats.\n\n" + "Consider tweaking /proc/sys/kernel/perf_event_paranoid,\n" + "which controls use of the performance events system by\n" + "unprivileged users (without CAP_SYS_ADMIN).\n\n" + "The default value is 1:\n\n" + " -1: Allow use of (almost) all events by all users\n" + ">= 0: Disallow raw tracepoint access by users without CAP_IOC_LOCK\n" + ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n" + ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN", target->system_wide ? "system-wide " : ""); case ENOENT: return scnprintf(msg, size, "The %s event is not supported.", From 5ed96e4947718e6fb9b72b54c201518532509bfe Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Sun, 29 May 2016 14:22:32 -0700 Subject: [PATCH 33/48] FROMLIST: security,perf: Allow further restriction of perf_event_open When kernel.perf_event_open is set to 3 (or greater), disallow all access to performance events by users without CAP_SYS_ADMIN. Add a Kconfig symbol CONFIG_SECURITY_PERF_EVENTS_RESTRICT that makes this value the default. This is based on a similar feature in grsecurity (CONFIG_GRKERNSEC_PERF_HARDEN). This version doesn't include making the variable read-only. It also allows enabling further restriction at run-time regardless of whether the default is changed. https://lkml.org/lkml/2016/1/11/587 Conflicts: kernel/events/core.c Signed-off-by: Ben Hutchings Signed-off-by: Dennis Cagle Bug: 29054680 Bug: 29119870 Change-Id: Iff5bff4fc1042e85866df9faa01bce8d04335ab8 (cherry picked from commit f16929ac8586f37949c638c738a6f0de969ed1ea) --- Documentation/sysctl/kernel.txt | 4 +++- include/linux/perf_event.h | 5 +++++ kernel/events/core.c | 6 ++++++ security/Kconfig | 9 +++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 942d769b78b2..d438fd2c21a6 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -492,12 +492,14 @@ the existing panic controls already in that directory. perf_event_paranoid: Controls use of the performance events system by unprivileged -users (without CAP_SYS_ADMIN). The default value is 1. +users (without CAP_SYS_ADMIN). The default value is 3 if +CONFIG_SECURITY_PERF_EVENTS_RESTRICT is set, or 1 otherwise. -1: Allow use of (almost) all events by all users >=0: Disallow raw tracepoint access by users without CAP_IOC_LOCK >=1: Disallow CPU event access by users without CAP_SYS_ADMIN >=2: Disallow kernel profiling by users without CAP_SYS_ADMIN +>=3: Disallow all event access by users without CAP_SYS_ADMIN ============================================================== diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 4410efad2f8b..86b43c1dcd61 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -715,6 +715,11 @@ extern int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, loff_t *ppos); +static inline bool perf_paranoid_any(void) +{ + return sysctl_perf_event_paranoid > 2; +} + static inline bool perf_paranoid_tracepoint_raw(void) { return sysctl_perf_event_paranoid > -1; diff --git a/kernel/events/core.c b/kernel/events/core.c index 7ab36de04a87..e8cae75e710a 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -166,9 +166,12 @@ static struct srcu_struct pmus_srcu; * 0 - disallow raw tracepoint access for unpriv * 1 - disallow cpu events for unpriv * 2 - disallow kernel profiling for unpriv + * 3 - disallow all unpriv perf event use */ #ifdef CONFIG_PERF_EVENTS_USERMODE int sysctl_perf_event_paranoid __read_mostly = -1; +#elif defined CONFIG_SECURITY_PERF_EVENTS_RESTRICT +int sysctl_perf_event_paranoid __read_mostly = 3; #else int sysctl_perf_event_paranoid __read_mostly = 1; #endif @@ -6826,6 +6829,9 @@ SYSCALL_DEFINE5(perf_event_open, if (flags & ~PERF_FLAG_ALL) return -EINVAL; + if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN)) + return -EACCES; + err = perf_copy_attr(attr_uptr, &attr); if (err) return err; diff --git a/security/Kconfig b/security/Kconfig index 01145437611e..66a5f8082971 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -18,6 +18,15 @@ config SECURITY_DMESG_RESTRICT If you are unsure how to answer this question, answer N. +config SECURITY_PERF_EVENTS_RESTRICT + bool "Restrict unprivileged use of performance events" + depends on PERF_EVENTS + help + If you say Y here, the kernel.perf_event_paranoid sysctl + will be set to 3 by default, and no unprivileged use of the + perf_event_open syscall will be permitted unless it is + changed. + config SECURITY bool "Enable different security models" depends on SYSFS From 4ba33a90397c3486f30a47fecb2860acb07d2f80 Mon Sep 17 00:00:00 2001 From: Dennis Cagle Date: Mon, 15 Aug 2016 14:35:18 -0700 Subject: [PATCH 34/48] msm_defconfig: Enable config for b/29119870 Restriction of kernel performance events requires a change to the defconfig. Bug: 29119870 Change-Id: Ib7e565a52446e2dcae1aa8c561d4770f2762a4d7 Signed-off-by: Dennis Cagle --- arch/arm64/configs/msm_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index e556f0c19016..098221d50077 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -616,6 +616,7 @@ CONFIG_KERNEL_TEXT_RDONLY=y CONFIG_KEYS=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_LSM_MMAP_MIN_ADDR=4096 CONFIG_SECURITY_SELINUX=y CONFIG_CRYPTO=y From 66800e2e1e1fb298c6c326ca2a424e83ad75bc6f Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:32:16 -0400 Subject: [PATCH 35/48] USB: usbfs: fix potential infoleak in devio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stack object “ci” has a total size of 8 bytes. Its last 3 bytes are padding bytes which are not initialized and leaked to userland via “copy_to_user”. Git-commit: 681fef8380eb818c0b845fca5d2ab1dcbab114ee Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Kangjie Lu Signed-off-by: Greg Kroah-Hartman Signed-off-by: Dennis Cagle (cherry picked from commit 681fef8380eb818c0b845fca5d2ab1dcbab114ee) Change-Id: Idacb2d5ed64654f85fb86fcce0a196223a7ac2af --- drivers/usb/core/devio.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 78ddfb43750a..4ccdd01fd0b7 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1106,10 +1106,11 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg) static int proc_connectinfo(struct dev_state *ps, void __user *arg) { - struct usbdevfs_connectinfo ci = { - .devnum = ps->dev->devnum, - .slow = ps->dev->speed == USB_SPEED_LOW - }; + struct usbdevfs_connectinfo ci; + + memset(&ci, 0, sizeof(ci)); + ci.devnum = ps->dev->devnum; + ci.slow = ps->dev->speed == USB_SPEED_LOW; if (copy_to_user(arg, &ci, sizeof(ci))) return -EFAULT; From 53ab2a184c826dd85b858ca736e57aa9efaf3b60 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:46:24 -0400 Subject: [PATCH 36/48] net: fix infoleak in rtnetlink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stack object “map” has a total size of 32 bytes. Its last 4 bytes are padding generated by compiler. These padding bytes are not initialized and sent out via “nla_put”. Conflicts: net/core/rtnetlink.c b/28620102 Signed-off-by: Kangjie Lu Signed-off-by: David S. Miller Signed-off-by: Dennis Cagle Git-commit: 5f8e44741f9f216e33736ea4ec65ca9ac03036e6 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git (cherry picked from commit 5f8e44741f9f216e33736ea4ec65ca9ac03036e6) Change-Id: I41f4745f24720c7af5ab08dc4274224d7fe4dcfe --- net/core/rtnetlink.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index a67310e00b3f..c468470112ae 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -907,6 +907,14 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, .dma = dev->dma, .port = dev->if_port, }; + memset(&map, 0, sizeof(map)); + map.mem_start = dev->mem_start; + map.mem_end = dev->mem_end; + map.base_addr = dev->base_addr; + map.irq = dev->irq; + map.dma = dev->dma; + map.port = dev->if_port; + if (nla_put(skb, IFLA_MAP, sizeof(map), &map)) goto nla_put_failure; } From 0a30c76c57b70539e3323675102d654b87870668 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:44:07 -0400 Subject: [PATCH 37/48] ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stack object “tread” has a total size of 32 bytes. Its field “event” and “val” both contain 4 bytes padding. These 8 bytes padding bytes are sent to user without being initialized. b/28980557 Git-commit: cec8f96e49d9be372fdb0c3836dcf31ec71e457e Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Signed-off-by: Dennis Cagle (cherry picked from commit cec8f96e49d9be372fdb0c3836dcf31ec71e457e) Change-Id: I3b42ee147fd0883696f9783f0a38d5bef888a10a --- sound/core/timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/timer.c b/sound/core/timer.c index 38a137d6b04f..fa7824b2b5ab 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1683,6 +1683,7 @@ static int snd_timer_user_params(struct file *file, if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) { if (tu->tread) { struct snd_timer_tread tread; + memset(&tread, 0, sizeof(tread)); tread.event = SNDRV_TIMER_EVENT_EARLY; tread.tstamp.tv_sec = 0; tread.tstamp.tv_nsec = 0; From f75578052492644c92077733cfeb54f35f8baa16 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:44:32 -0400 Subject: [PATCH 38/48] ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stack object “r1” has a total size of 32 bytes. Its field “event” and “val” both contain 4 bytes padding. These 8 bytes padding bytes are sent to user without being initialized. b/28980217 Git-commit: e4ec8cc8039a7063e24204299b462bd1383184a5 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Signed-off-by: Dennis Cagle (cherry picked from commit e4ec8cc8039a7063e24204299b462bd1383184a5) Change-Id: I53aa15632e941199010aae670cefb65c8fd56833 --- sound/core/timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/timer.c b/sound/core/timer.c index 38a137d6b04f..411113ac2f17 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1218,6 +1218,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri, } if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) { + memset(&r1, 0, sizeof(r1)); r1.event = SNDRV_TIMER_EVENT_RESOLUTION; r1.tstamp = tstamp; r1.val = resolution; From 86b1314c6ce74f4ae3714dceb8db412c1489f976 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:44:20 -0400 Subject: [PATCH 39/48] ALSA: timer: Fix leak in events via snd_timer_user_ccallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stack object “r1” has a total size of 32 bytes. Its field “event” and “val” both contain 4 bytes padding. These 8 bytes padding bytes are sent to user without being initialized. b/28980217 Git-commit: 9a47e9cff994f37f7f0dbd9ae23740d0f64f9fe6 Git-repo: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Signed-off-by: Dennis Cagle (cherry picked from commit 9a47e9cff994f37f7f0dbd9ae23740d0f64f9fe6) Change-Id: I12949efac2aba669d302908704005fb94ba7efd7 --- sound/core/timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/timer.c b/sound/core/timer.c index 411113ac2f17..ce2867b7f97f 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1184,6 +1184,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri, tu->tstamp = *tstamp; if ((tu->filter & (1 << event)) == 0 || !tu->tread) return; + memset(&r1, 0, sizeof(r1)); r1.event = event; r1.tstamp = *tstamp; r1.val = resolution; From c33331f4b7a8b3d5e91ac87056d6b686301f4276 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 16 Dec 2015 13:32:38 -0500 Subject: [PATCH 40/48] USB: fix invalid memory access in hub_activate() Commit 8520f38099cc ("USB: change hub initialization sleeps to delayed_work") changed the hub_activate() routine to make part of it run in a workqueue. However, the commit failed to take a reference to the usb_hub structure or to lock the hub interface while doing so. As a result, if a hub is plugged in and quickly unplugged before the work routine can run, the routine will try to access memory that has been deallocated. Or, if the hub is unplugged while the routine is running, the memory may be deallocated while it is in active use. This patch fixes the problem by taking a reference to the usb_hub at the start of hub_activate() and releasing it at the end (when the work is finished), and by locking the hub interface while the work routine is running. It also adds a check at the start of the routine to see if the hub has already been disconnected, in which nothing should be done. Change-Id: I1e5a67d22a5b61898e5a2aab8ea87b0c08e1130c Signed-off-by: Alan Stern Reported-by: Alexandru Cornea Tested-by: Alexandru Cornea Fixes: 8520f38099cc ("USB: change hub initialization sleeps to delayed_work") CC: Signed-off-by: Greg Kroah-Hartman Git-commit: e50293ef9775c5f1cf3fcc093037dd6a8c5684ea Git-repo: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git Signed-off-by: Ravi Kumar Siddojigari --- drivers/usb/core/hub.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b616bcbe63b1..8796ce79cce7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -113,6 +113,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); #define HUB_DEBOUNCE_STEP 25 #define HUB_DEBOUNCE_STABLE 100 +static void hub_release(struct kref *kref); static int usb_reset_and_verify_device(struct usb_device *udev); static inline char *portspeed(struct usb_hub *hub, int portstatus) @@ -1020,10 +1021,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) unsigned delay; /* Continue a partial initialization */ - if (type == HUB_INIT2) - goto init2; - if (type == HUB_INIT3) + if (type == HUB_INIT2 || type == HUB_INIT3) { + device_lock(hub->intfdev); + + /* Was the hub disconnected while we were waiting? */ + if (hub->disconnected) { + device_unlock(hub->intfdev); + kref_put(&hub->kref, hub_release); + return; + } + if (type == HUB_INIT2) + goto init2; goto init3; + } + kref_get(&hub->kref); /* The superspeed hub except for root hub has to use Hub Depth * value as an offset into the route string to locate the bits @@ -1229,6 +1240,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3); schedule_delayed_work(&hub->init_work, msecs_to_jiffies(delay)); + device_unlock(hub->intfdev); return; /* Continues at init3: below */ } else { msleep(delay); @@ -1249,6 +1261,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) /* Allow autosuspend if it was suppressed */ if (type <= HUB_INIT3) usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); + + if (type == HUB_INIT2 || type == HUB_INIT3) + device_unlock(hub->intfdev); + + kref_put(&hub->kref, hub_release); } /* Implement the continuations for the delays above */ From 246ecc54ee94386040a0ac9a37fb3befbc3f3ed8 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Tue, 16 Aug 2016 16:13:58 +0530 Subject: [PATCH 41/48] ASoC: msm: qdsp6v2: DAP: Enable non DAP modules on DAP disable Non DAP modules are disabled when DAP is enabled, and when DAP is disabled they are suppose to move to a state as set in the calibration data. Modules which dont have an explicit enable param remain disabled even when DAP is disabled. Hence send an explicit enable command to DSP for all modules followed by the calibration data, this ensures correct state of all modules. Change-Id: I6f8873bb11d96a20f6401eba5fe2979b6a14e11e CRs-Fixed: 1049611 Signed-off-by: Ashish Jain --- sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index ad2f2e9865c3..59835e682408 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -998,6 +998,20 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) copp_idx, rc); } } + /* Turn on qti modules */ + for (j = 1; j < mod_list[0]; j++) { + if (!msm_ds2_dap_can_enable_module( + mod_list[j]) || + mod_list[j] == + DS2_MODULE_ID) + continue; + pr_debug("%s: param enable %d\n", + __func__, mod_list[j]); + adm_param_enable(port_id, copp_idx, + mod_list[j], + MODULE_ENABLE); + } + /* Add adm api to resend calibration on port */ rc = msm_ds2_dap_send_cal_data(i); if (rc < 0) { From 8cac8ed5af0e389e6e5ce9d9d44ab2730c550d20 Mon Sep 17 00:00:00 2001 From: Sandeep Panda Date: Fri, 19 Aug 2016 10:52:21 +0530 Subject: [PATCH 42/48] msm: mdss: configure DSI PHY when resuming from ulps suspend In case ulps suspend feature is enabled, when going to suspend DSI PHY is never disabled as it is required to be enabled in order to drive the DSI lanes in ULPS state. So when resuming also PHY will not be reconfigured. This will cause issues when mdss footswitch is turned off in suspend and hence all the phy registers are reset. So always reconfigure DSI PHY regulators when resuming from ulps suspend. Change-Id: I33793226d5b9af791f0adc171fcacbec5e9a3f97 Signed-off-by: Sandeep Panda --- drivers/video/msm/mdss/mdss_dsi.h | 6 ++++++ drivers/video/msm/mdss/msm_mdss_io_8974.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h index bdc89b969f9e..4808c0dcb7c3 100644 --- a/drivers/video/msm/mdss/mdss_dsi.h +++ b/drivers/video/msm/mdss/mdss_dsi.h @@ -734,6 +734,12 @@ static inline bool mdss_dsi_is_ctrl_clk_slave(struct mdss_dsi_ctrl_pdata *ctrl) (ctrl->ndx == DSI_CTRL_CLK_SLAVE); } +static inline bool mdss_dsi_is_ctrl_clk_master(struct mdss_dsi_ctrl_pdata *ctrl) +{ + return mdss_dsi_is_hw_config_split(ctrl->shared_data) && + (ctrl->ndx == DSI_CTRL_CLK_MASTER); +} + static inline bool mdss_dsi_is_te_based_esd(struct mdss_dsi_ctrl_pdata *ctrl) { return (ctrl->status_mode == ESD_TE) && diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c index 5f143bf85e22..724902be21bd 100644 --- a/drivers/video/msm/mdss/msm_mdss_io_8974.c +++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c @@ -363,6 +363,8 @@ static void mdss_dsi_phy_regulator_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, { struct mdss_dsi_ctrl_pdata *other_ctrl; struct dsi_shared_data *sdata; + struct mdss_panel_data *pdata; + struct mdss_panel_info *pinfo; if (!ctrl) { pr_err("%s: Invalid input data\n", __func__); @@ -371,6 +373,8 @@ static void mdss_dsi_phy_regulator_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, sdata = ctrl->shared_data; other_ctrl = mdss_dsi_get_other_ctrl(ctrl); + pdata = &ctrl->panel_data; + pinfo = &pdata->panel_info; mutex_lock(&sdata->phy_reg_lock); if (enable) { @@ -383,6 +387,8 @@ static void mdss_dsi_phy_regulator_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, * other dsi controller is still active. */ if (mdss_dsi_is_hw_config_single(sdata) || + (mdss_dsi_is_ctrl_clk_master(ctrl) && + pinfo->ulps_suspend_enabled) || (other_ctrl && !other_ctrl->is_phyreg_enabled)) mdss_dsi_28nm_phy_regulator_enable(ctrl); } From 251b7c0fa3346a72933811100b7b8cdfa5c1ae9e Mon Sep 17 00:00:00 2001 From: Kishor PK Date: Thu, 18 Feb 2016 15:26:50 +0530 Subject: [PATCH 43/48] msm: perf: validate input argument of ev_constraints functions Validate input argument before writing into pmu_constraints_codes array. CRs-Fixed: 975404 Change-Id: Id68b1d2201ab1af783af2236833b1dc894e08cc7 Signed-off-by: Kishor PK --- arch/arm/mach-msm/perf_event_msm_krait_l2.c | 23 +++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-msm/perf_event_msm_krait_l2.c b/arch/arm/mach-msm/perf_event_msm_krait_l2.c index cc39b719b33f..2e0c3af3dc1c 100644 --- a/arch/arm/mach-msm/perf_event_msm_krait_l2.c +++ b/arch/arm/mach-msm/perf_event_msm_krait_l2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2012,2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2012,2014,2016 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 @@ -18,13 +18,15 @@ #include +#define PMU_CODES_SIZE 64 + /* * The L2 PMU is shared between all CPU's, so protect * its bitmap access. */ struct pmu_constraints { u64 pmu_bitmap; - u8 codes[64]; + u8 codes[PMU_CODES_SIZE]; raw_spinlock_t lock; } l2_pmu_constraints = { .pmu_bitmap = 0, @@ -427,10 +429,9 @@ static int msm_l2_test_set_ev_constraint(struct perf_event *event) u8 group = evt_type & 0x0000F; u8 code = (evt_type & 0x00FF0) >> 4; unsigned long flags; - u32 err = 0; + int err = 0; u64 bitmap_t; u32 shift_idx; - if (evt_prefix == L2_TRACECTR_PREFIX) return err; /* @@ -444,6 +445,11 @@ static int msm_l2_test_set_ev_constraint(struct perf_event *event) shift_idx = ((reg * 4) + group); + if (shift_idx >= PMU_CODES_SIZE) { + err = -EINVAL; + goto out; + } + bitmap_t = 1 << shift_idx; if (!(l2_pmu_constraints.pmu_bitmap & bitmap_t)) { @@ -485,6 +491,7 @@ static int msm_l2_clear_ev_constraint(struct perf_event *event) unsigned long flags; u64 bitmap_t; u32 shift_idx; + int err = 1; if (evt_prefix == L2_TRACECTR_PREFIX) return 1; @@ -492,6 +499,10 @@ static int msm_l2_clear_ev_constraint(struct perf_event *event) shift_idx = ((reg * 4) + group); + if (shift_idx >= PMU_CODES_SIZE) { + err = -EINVAL; + goto out; + } bitmap_t = 1 << shift_idx; /* Clear constraint bit. */ @@ -499,9 +510,9 @@ static int msm_l2_clear_ev_constraint(struct perf_event *event) /* Clear code. */ l2_pmu_constraints.codes[shift_idx] = -1; - +out: raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags); - return 1; + return err; } int get_num_events(void) From be651d020b122a1ba9410d23ca4ebbe9f5598df6 Mon Sep 17 00:00:00 2001 From: Sanjay Singh Date: Wed, 10 Aug 2016 12:40:58 +0530 Subject: [PATCH 44/48] msm: vidc: use %pK instead of %p which respects kptr_restrict sysctl Hide kernel pointers from unprivileged ussers by using %pK format- specifier instead of %p. This respects the kptr_restrict sysctl setting which is by default on. So by default %pK will print zeroes as address. echo 1 to kptr_restrict to print proper kernel addresses. CRs-Fixed: 987018 Change-Id: I4772257a557c6730ecc0624cbc8e5614e893e9fd Signed-off-by: Sanjay Singh --- .../platform/msm/vidc/hfi_packetization.c | 8 +- .../platform/msm/vidc/hfi_response_handler.c | 48 +++--- drivers/media/platform/msm/vidc/msm_smem.c | 20 +-- .../media/platform/msm/vidc/msm_v4l2_vidc.c | 6 +- drivers/media/platform/msm/vidc/msm_vdec.c | 40 ++--- drivers/media/platform/msm/vidc/msm_venc.c | 32 ++-- drivers/media/platform/msm/vidc/msm_vidc.c | 36 ++--- .../media/platform/msm/vidc/msm_vidc_common.c | 138 +++++++++--------- .../media/platform/msm/vidc/msm_vidc_dcvs.c | 14 +- .../media/platform/msm/vidc/msm_vidc_debug.c | 18 +-- drivers/media/platform/msm/vidc/q6_hfi.c | 22 +-- drivers/media/platform/msm/vidc/venus_hfi.c | 96 ++++++------ drivers/media/platform/msm/vidc/vidc_hfi.c | 4 +- drivers/media/platform/msm/vidc/vmem/vmem.c | 6 +- 14 files changed, 244 insertions(+), 244 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c index 06ac913a60ad..86239e289b47 100644 --- a/drivers/media/platform/msm/vidc/hfi_packetization.c +++ b/drivers/media/platform/msm/vidc/hfi_packetization.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -1402,7 +1402,7 @@ int create_pkt_cmd_session_set_property( break; default: dprintk(VIDC_ERR, - "Invalid Rate control setting: 0x%p\n", + "Invalid Rate control setting: 0x%pK\n", pdata); break; } @@ -2084,7 +2084,7 @@ int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type, struct hfi_cmd_sys_test_ssr_packet *pkt) { if (!pkt) { - dprintk(VIDC_ERR, "Invalid params, device: %p\n", pkt); + dprintk(VIDC_ERR, "Invalid params, device: %pK\n", pkt); return -EINVAL; } pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet); @@ -2097,7 +2097,7 @@ int create_pkt_cmd_sys_image_version( struct hfi_cmd_sys_get_property_packet *pkt) { if (!pkt) { - dprintk(VIDC_ERR, "%s invalid param :%p\n", __func__, pkt); + dprintk(VIDC_ERR, "%s invalid param :%pK\n", __func__, pkt); return -EINVAL; } pkt->size = sizeof(struct hfi_cmd_sys_get_property_packet); diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index e148f04bef99..c315b6d1ad33 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -255,7 +255,7 @@ static void hfi_process_event_notify(msm_vidc_callback callback, u32 device_id, hfi_process_sys_error(callback, device_id); break; case HFI_EVENT_SESSION_PROPERTY_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED[%p]\n", + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED[%pK]\n", session); break; } @@ -267,24 +267,24 @@ static void hfi_process_event_notify(msm_vidc_callback callback, u32 device_id, switch (pkt->event_id) { case HFI_EVENT_SESSION_ERROR: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR[%p]\n", session); + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR[%pK]\n", session); hfi_process_session_error(callback, device_id, session, pkt); break; case HFI_EVENT_SESSION_SEQUENCE_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%p]\n", + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%pK]\n", session); hfi_process_sess_evt_seq_changed(callback, device_id, session, pkt); break; case HFI_EVENT_RELEASE_BUFFER_REFERENCE: - dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%p]\n", + dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%pK]\n", session); hfi_process_evt_release_buffer_ref(callback, device_id, session, pkt); break; default: dprintk(VIDC_WARN, - "hal_process_event_notify: unknown_event_id[%p]\n", + "hal_process_event_notify: unknown_event_id[%pK]\n", session); break; } @@ -887,7 +887,7 @@ static enum vidc_status hfi_parse_init_done_properties( } default: dprintk(VIDC_DBG, - "%s: default case - data_ptr %p, prop_id 0x%x\n", + "%s: default case - data_ptr %pK, prop_id 0x%x\n", __func__, data_ptr, prop_id); break; } @@ -925,7 +925,7 @@ enum vidc_status hfi_process_sys_init_done_prop_read( data_ptr = (u8 *) &pkt->rg_property_data[0]; num_properties = pkt->num_properties; dprintk(VIDC_DBG, - "%s: data_start %p, num_properties %#x\n", + "%s: data_start %pK, num_properties %#x\n", __func__, data_ptr, num_properties); bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done); @@ -955,7 +955,7 @@ static void hfi_process_sess_get_prop_profile_level( dprintk(VIDC_DBG, "Entered %s\n", __func__); if (!prop) { dprintk(VIDC_ERR, - "hal_process_sess_get_profile_level: bad_prop: %p\n", + "hal_process_sess_get_profile_level: bad_prop: %pK\n", prop); return; } @@ -986,7 +986,7 @@ static void hfi_process_sess_get_prop_buf_req( if (!prop) { dprintk(VIDC_ERR, - "hal_process_sess_get_prop_buf_req: bad_prop: %p\n", + "hal_process_sess_get_prop_buf_req: bad_prop: %pK\n", prop); return; } @@ -1105,7 +1105,7 @@ static void hfi_process_session_prop_info(msm_vidc_callback callback, struct buffer_requirements buff_req; memset(&buff_req, 0, sizeof(struct buffer_requirements)); - dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%p]\n", session); + dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%pK]\n", session); if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) { dprintk(VIDC_ERR, @@ -1161,7 +1161,7 @@ static void hfi_process_session_init_done( memset(&session_init_done, 0, sizeof(struct vidc_hal_session_init_done)); - dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%pK]\n", session); if (sizeof(struct hfi_msg_sys_session_init_done_packet) > pkt->size) { @@ -1181,7 +1181,7 @@ static void hfi_process_session_init_done( pkt, &session_init_done); } else { dprintk(VIDC_WARN, - "Sess init failed: 0x%p, 0x%p\n", + "Sess init failed: 0x%pK, 0x%pK\n", session->session_id, session); } cmd_done.size = sizeof(struct vidc_hal_session_init_done); @@ -1193,7 +1193,7 @@ static void hfi_process_session_load_res_done(msm_vidc_callback callback, struct hfi_msg_session_load_resources_done_packet *pkt) { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%p]\n", + dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%pK]\n", session); if (sizeof(struct hfi_msg_session_load_resources_done_packet) != @@ -1218,7 +1218,7 @@ static void hfi_process_session_flush_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%pK]\n", session); if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) { dprintk(VIDC_ERR, @@ -1241,7 +1241,7 @@ static void hfi_process_session_etb_done(msm_vidc_callback callback, { struct msm_vidc_cb_data_done data_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%pK]\n", session); if (!pkt || pkt->size < sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { @@ -1282,7 +1282,7 @@ static void hfi_process_session_ftb_done(msm_vidc_callback callback, return; } - dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%pK]\n", session); if (is_decoder == 0) { struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt = @@ -1382,7 +1382,7 @@ static void hfi_process_session_start_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_start_done_packet)) { @@ -1405,7 +1405,7 @@ static void hfi_process_session_stop_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_stop_done_packet)) { @@ -1428,7 +1428,7 @@ static void hfi_process_session_rel_res_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%p]\n", + dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%pK]\n", session); if (!pkt || pkt->size != @@ -1459,7 +1459,7 @@ static void hfi_process_session_rel_buf_done(msm_vidc_callback callback, pkt ? pkt->size : 0); return; } - dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%p]\n", + dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%pK]\n", session); cmd_done.device_id = device_id; @@ -1481,7 +1481,7 @@ static void hfi_process_session_end_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_end_done_packet)) { @@ -1503,7 +1503,7 @@ static void hfi_process_session_abort_done(msm_vidc_callback callback, { struct msm_vidc_cb_cmd_done cmd_done = {0}; - dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%pK]\n", session); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_abort_done_packet)) { @@ -1540,7 +1540,7 @@ static void hfi_process_session_get_seq_hdr_done(msm_vidc_callback callback, __func__); return; } - dprintk(VIDC_DBG, "RECEIVED:SESSION_GET_SEQ_HDR_DONE[%p]\n", session); + dprintk(VIDC_DBG, "RECEIVED:SESSION_GET_SEQ_HDR_DONE[%pK]\n", session); data_done.device_id = device_id; data_done.size = sizeof(struct msm_vidc_cb_data_done); diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c index 47d3ca54b4e3..8ab44a1a68d6 100644 --- a/drivers/media/platform/msm/vidc/msm_smem.c +++ b/drivers/media/platform/msm/vidc/msm_smem.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -34,7 +34,7 @@ static int get_device_address(struct smem_client *smem_client, struct ion_client *clnt = NULL; if (!iova || !buffer_size || !hndl || !smem_client) { - dprintk(VIDC_ERR, "Invalid params: %p, %p, %p, %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK, %pK, %pK, %pK\n", smem_client, hndl, iova, buffer_size); return -EINVAL; } @@ -86,7 +86,7 @@ static void put_device_address(struct smem_client *smem_client, struct ion_client *clnt = NULL; if (!hndl || !smem_client) { - dprintk(VIDC_WARN, "Invalid params: %p, %p\n", + dprintk(VIDC_WARN, "Invalid params: %pK, %pK\n", smem_client, hndl); return; } @@ -120,7 +120,7 @@ static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, hndl = ion_import_dma_buf(client->clnt, fd); if (IS_ERR_OR_NULL(hndl)) { - dprintk(VIDC_ERR, "Failed to get handle: %p, %d, %d, %p\n", + dprintk(VIDC_ERR, "Failed to get handle: %pK, %d, %d, %pK\n", client, fd, offset, hndl); rc = -ENOMEM; goto fail_import_fd; @@ -153,7 +153,7 @@ static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, goto fail_device_address; } dprintk(VIDC_DBG, - "%s: ion_handle = 0x%p, fd = %d, device_addr = 0x%pa, size = %zx, kvaddr = 0x%p, buffer_type = %d, flags = 0x%lx\n", + "%s: ion_handle = 0x%pK, fd = %d, device_addr = 0x%pa, size = %zx, kvaddr = 0x%pK, buffer_type = %d, flags = 0x%lx\n", __func__, mem->smem_priv, fd, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); return rc; @@ -199,7 +199,7 @@ static int alloc_ion_mem(struct smem_client *client, size_t size, u32 align, hndl = ion_alloc(client->clnt, size, align, heap_mask, flags); if (IS_ERR_OR_NULL(hndl)) { dprintk(VIDC_ERR, - "Failed to allocate shared memory = %p, %zx, %d, 0x%x\n", + "Failed to allocate shared memory = %pK, %zx, %d, 0x%x\n", client, size, align, flags); rc = -ENOMEM; goto fail_shared_mem_alloc; @@ -237,7 +237,7 @@ static int alloc_ion_mem(struct smem_client *client, size_t size, u32 align, } mem->size = size; dprintk(VIDC_DBG, - "%s: ion_handle = 0x%p, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%p, buffer_type = 0x%x, flags = 0x%lx\n", + "%s: ion_handle = 0x%pK, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%pK, buffer_type = 0x%x, flags = 0x%lx\n", __func__, mem->smem_priv, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); @@ -255,7 +255,7 @@ static void free_ion_mem(struct smem_client *client, struct msm_smem *mem) int domain, partition, rc; dprintk(VIDC_DBG, - "%s: ion_handle = 0x%p, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%p, buffer_type = 0x%x\n", + "%s: ion_handle = 0x%pK, device_addr = 0x%pa, size = 0x%zx, kvaddr = 0x%pK, buffer_type = 0x%x\n", __func__, mem->smem_priv, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type); rc = msm_smem_get_domain_partition((void *)client, mem->flags, @@ -333,7 +333,7 @@ static int ion_cache_operations(struct smem_client *client, int rc = 0; int msm_cache_ops = 0; if (!mem || !client) { - dprintk(VIDC_ERR, "Invalid params: %p, %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK, %pK\n", mem, client); return -EINVAL; } @@ -380,7 +380,7 @@ int msm_smem_cache_operations(void *clt, struct msm_smem *mem, struct smem_client *client = clt; int rc = 0; if (!client) { - dprintk(VIDC_ERR, "Invalid params: %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK\n", client); return -EINVAL; } diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c index 309979c05b9d..c43c64c04e6d 100644 --- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -307,7 +307,7 @@ static int read_platform_resources(struct msm_vidc_core *core, struct platform_device *pdev) { if (!core || !pdev) { - dprintk(VIDC_ERR, "%s: Invalid params %p %p\n", + dprintk(VIDC_ERR, "%s: Invalid params %pK %pK\n", __func__, core, pdev); return -EINVAL; } @@ -696,7 +696,7 @@ static int msm_vidc_remove(struct platform_device *pdev) struct msm_vidc_core *core; if (!pdev) { - dprintk(VIDC_ERR, "%s invalid input %p", __func__, pdev); + dprintk(VIDC_ERR, "%s invalid input %pK", __func__, pdev); return -EINVAL; } core = pdev->dev.platform_data; diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c index c92d655e831e..dd512ad43bb9 100644 --- a/drivers/media/platform/msm/vidc/msm_vdec.c +++ b/drivers/media/platform/msm/vidc/msm_vdec.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -835,7 +835,7 @@ int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || inst->core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring prepare buf\n", + "Core %pK in bad state, ignoring prepare buf\n", inst->core); goto exit; } @@ -914,7 +914,7 @@ int msm_vdec_release_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring release output buf\n", + "Core %pK in bad state, ignoring release output buf\n", core); goto exit; } @@ -1007,7 +1007,7 @@ int msm_vdec_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b) int rc = 0; if (!inst || !b) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, buffer = %p\n", inst, b); + "Invalid input, inst = %pK, buffer = %pK\n", inst, b); return -EINVAL; } q = msm_comm_get_vb2q(inst, b->type); @@ -1038,7 +1038,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (!inst || !f || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -1215,7 +1215,7 @@ int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a) fps = fps - 1; if (inst->prop.fps != fps) { - dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n", + dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n", inst, inst->prop.fps, fps); inst->prop.fps = fps; msm_dcvs_init_load(inst); @@ -1381,7 +1381,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (!f || !inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, - "%s: invalid parameters, format %p, inst %p\n", + "%s: invalid parameters, format %pK, inst %pK\n", __func__, f, inst); return -EINVAL; } @@ -1562,7 +1562,7 @@ int msm_vdec_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap) { if (!inst || !cap) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, cap = %p\n", inst, cap); + "Invalid input, inst = %pK, cap = %pK\n", inst, cap); return -EINVAL; } strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver)); @@ -1582,7 +1582,7 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) int rc = 0; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, f = %p\n", inst, f); + "Invalid input, inst = %pK, f = %pK\n", inst, f); return -EINVAL; } if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -1640,7 +1640,7 @@ static int msm_vdec_queue_setup(struct vb2_queue *q, if (!q || !num_buffers || !num_planes || !sizes || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p, %p, %p\n", + dprintk(VIDC_ERR, "Invalid input, q = %pK, %pK, %pK\n", q, num_buffers, num_planes); return -EINVAL; } @@ -1829,7 +1829,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto fail_start; } msm_dcvs_init_load(inst); @@ -1866,7 +1866,7 @@ static inline int stop_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); return rc; } @@ -1876,7 +1876,7 @@ static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count) int rc = 0; struct hfi_device *hdev; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1909,7 +1909,7 @@ static int msm_vdec_stop_streaming(struct vb2_queue *q) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1934,7 +1934,7 @@ static int msm_vdec_stop_streaming(struct vb2_queue *q) if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p, cap = %d to state: %d\n", + "Failed to move inst: %pK, cap = %d to state: %d\n", inst, q->type, MSM_VIDC_RELEASE_RESOURCES_DONE); return rc; } @@ -1992,7 +1992,7 @@ int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec) if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, Sending CLOSE event\n", + "Core %pK in bad state, Sending CLOSE event\n", core); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_CLOSE_DONE); @@ -2034,7 +2034,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) { int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "Invalid input = %p\n", inst); + dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); return -EINVAL; } inst->fmts[OUTPUT_PORT] = &vdec_formats[1]; @@ -2575,7 +2575,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: property_id = 0; inst->operating_rate = ctrl->val; - dprintk(VIDC_DBG, "inst(%p) operating rate changed to %d", + dprintk(VIDC_DBG, "inst(%pK) operating rate changed to %d", inst, inst->operating_rate >> 16); msm_comm_scale_clocks_and_bus(inst); break; @@ -2607,7 +2607,7 @@ static int msm_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } @@ -2639,7 +2639,7 @@ static int msm_vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } for (c = 0; c < master->ncontrols; ++c) { diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index 932c980c4907..d3f176d62ae8 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -1520,7 +1520,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto fail_start; } msm_dcvs_init_load(inst); @@ -1547,7 +1547,7 @@ static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1574,7 +1574,7 @@ static int msm_venc_stop_streaming(struct vb2_queue *q) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1595,7 +1595,7 @@ static int msm_venc_stop_streaming(struct vb2_queue *q) if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p, cap = %d to state: %d\n", + "Failed to move inst: %pK, cap = %d to state: %d\n", inst, q->type, MSM_VIDC_CLOSE_DONE); return rc; } @@ -2835,7 +2835,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE: property_id = 0; inst->operating_rate = ctrl->val; - dprintk(VIDC_DBG, "inst(%p) operating rate changed to %d", + dprintk(VIDC_DBG, "inst(%pK) operating rate changed to %d", inst, inst->operating_rate >> 16); msm_comm_scale_clocks_and_bus(inst); break; @@ -3054,7 +3054,7 @@ static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl) if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } @@ -3098,7 +3098,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) { int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "Invalid input = %p\n", inst); + dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); return -EINVAL; } inst->fmts[CAPTURE_PORT] = &venc_formats[1]; @@ -3181,7 +3181,7 @@ int msm_venc_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap) { if (!inst || !cap) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, cap = %p\n", inst, cap); + "Invalid input, inst = %pK, cap = %pK\n", inst, cap); return -EINVAL; } strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver)); @@ -3201,7 +3201,7 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) int rc = 0; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, f = %p\n", inst, f); + "Invalid input, inst = %pK, f = %pK\n", inst, f); return -EINVAL; } if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -3275,7 +3275,7 @@ int msm_venc_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a) fps = fps - 1; if (inst->prop.fps != fps) { - dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n", + dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n", inst, inst->prop.fps, fps); inst->prop.fps = fps; frame_rate.frame_rate = inst->prop.fps * (0x1<<16); @@ -3329,7 +3329,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) struct hfi_device *hdev; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -3512,7 +3512,7 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -3577,7 +3577,7 @@ int msm_venc_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b) int rc = 0; if (!inst || !b) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, buffer = %p\n", inst, b); + "Invalid input, inst = %pK, buffer = %pK\n", inst, b); return -EINVAL; } q = msm_comm_get_vb2q(inst, b->type); @@ -3614,7 +3614,7 @@ int msm_venc_prepare_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || inst->core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring prepare buf\n", + "Core %pK in bad state, ignoring prepare buf\n", inst->core); goto exit; } @@ -3685,7 +3685,7 @@ int msm_venc_release_buf(struct msm_vidc_inst *inst, rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to release res done state\n", + "Failed to move inst: %pK to release res done state\n", inst); goto exit; } diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 38ccaa39fd80..8f4b6b60caaa 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -331,7 +331,7 @@ struct buffer_info *device_to_uvaddr(struct msm_vidc_list *buf_list, if (!buf_list || !device_addr) { dprintk(VIDC_ERR, - "Invalid input- device_addr: 0x%pa buf_list: %p\n", + "Invalid input- device_addr: 0x%pa buf_list: %pK\n", &device_addr, buf_list); goto err_invalid_input; } @@ -487,7 +487,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } - dprintk(VIDC_DBG, "[MAP] Create binfo = %p fd = %d type = %d\n", + dprintk(VIDC_DBG, "[MAP] Create binfo = %pK fd = %d type = %d\n", binfo, b->m.planes[0].reserved[0], b->type); for (i = 0; i < b->length; ++i) { @@ -570,7 +570,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } dprintk(VIDC_DBG, - "%s: [MAP] binfo = %p, handle[%d] = %p, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [MAP] binfo = %pK, handle[%d] = %pK, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", __func__, binfo, i, binfo->handle[i], &binfo->device_addr[i], binfo->fd[i], binfo->buff_off[i], binfo->mapped[i]); @@ -593,7 +593,7 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, bool found = false, keep_node = false; if (!inst || !binfo) { - dprintk(VIDC_ERR, "%s invalid param: %p %p\n", + dprintk(VIDC_ERR, "%s invalid param: %pK %pK\n", __func__, inst, binfo); return -EINVAL; } @@ -623,7 +623,7 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, for (i = 0; i < temp->num_planes; i++) { dprintk(VIDC_DBG, - "%s: [UNMAP] binfo = %p, handle[%d] = %p, device_addr = 0x%pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [UNMAP] binfo = %pK, handle[%d] = %pK, device_addr = 0x%pKa, fd = %d, offset = %d, mapped = %d\n", __func__, temp, i, temp->handle[i], &temp->device_addr[i], temp->fd[i], temp->buff_off[i], temp->mapped[i]); @@ -652,12 +652,12 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, } } if (!keep_node) { - dprintk(VIDC_DBG, "[UNMAP] AND-FREED binfo: %p\n", temp); + dprintk(VIDC_DBG, "[UNMAP] AND-FREED binfo: %pK\n", temp); list_del(&temp->list); kfree(temp); } else { temp->inactive = true; - dprintk(VIDC_DBG, "[UNMAP] NOT-FREED binfo: %p\n", temp); + dprintk(VIDC_DBG, "[UNMAP] NOT-FREED binfo: %pK\n", temp); } exit: return 0; @@ -671,7 +671,7 @@ int qbuf_dynamic_buf(struct msm_vidc_inst *inst, struct v4l2_plane plane[VIDEO_MAX_PLANES] = { {0} }; if (!binfo) { - dprintk(VIDC_ERR, "%s invalid param: %p\n", __func__, binfo); + dprintk(VIDC_ERR, "%s invalid param: %pK\n", __func__, binfo); return -EINVAL; } dprintk(VIDC_DBG, "%s fd[0] = %d\n", __func__, binfo->fd[0]); @@ -694,7 +694,7 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst, int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return -EINVAL; } @@ -702,7 +702,7 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst, return 0; if (!binfo) { - dprintk(VIDC_ERR, "%s: invalid buffer info: %p\n", + dprintk(VIDC_ERR, "%s: invalid buffer info: %pK\n", __func__, inst); return -EINVAL; } @@ -780,7 +780,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type) rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to release res done\n", + "Failed to move inst: %pK to release res done\n", inst); } } @@ -862,7 +862,7 @@ int msm_vidc_free_buffers(void *instance, int buffer_type) for (i = 0; i < bi->num_planes; i++) { if (bi->handle[i] && bi->mapped[i]) { dprintk(VIDC_DBG, - "%s: binfo = 0x%p, handle[%d] = %p, device_addr = %pa, fd = %d, offset = %d, buffer_type 0x%x, mapped = %d\n", + "%s: binfo = 0x%pK, handle[%d] = %pK, device_addr = %pa, fd = %d, offset = %d, buffer_type 0x%x, mapped = %d\n", __func__, bi, i, bi->handle[i], &bi->device_addr[i], bi->fd[i], bi->buff_off[i], bi->type, @@ -1089,7 +1089,7 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) struct msm_vidc_capability *capability = NULL; if (!inst || !fsize) { - dprintk(VIDC_ERR, "%s: invalid parameter: %p %p\n", + dprintk(VIDC_ERR, "%s: invalid parameter: %pK %pK\n", __func__, inst, fsize); return -EINVAL; } @@ -1156,7 +1156,7 @@ void *msm_vidc_smem_get_client(void *instance) struct msm_vidc_inst *inst = instance; if (!inst || !inst->mem_client) { - dprintk(VIDC_ERR, "%s: invalid instance or client = %p\n", + dprintk(VIDC_ERR, "%s: invalid instance or client = %pK\n", __func__, inst); return NULL; } @@ -1214,7 +1214,7 @@ static int setup_event_queue(void *inst, struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst; if (!inst || !pvdev) { - dprintk(VIDC_ERR, "%s Invalid params inst %p pvdev %p\n", + dprintk(VIDC_ERR, "%s Invalid params inst %pK pvdev %pK\n", __func__, inst, pvdev); return -EINVAL; } @@ -1290,7 +1290,7 @@ void *msm_vidc_open(int core_id, int session_type) goto err_invalid_core; } - pr_info(VIDC_DBG_TAG "Opening video instance: %p, %d\n", + pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n", VIDC_MSG_PRIO2STRING(VIDC_INFO), inst, session_type); mutex_init(&inst->sync_lock); mutex_init(&inst->bufq[CAPTURE_PORT].lock); @@ -1493,7 +1493,7 @@ int msm_vidc_close(void *instance) msm_smem_delete_client(inst->mem_client); - pr_info(VIDC_DBG_TAG "Closed video instance: %p\n", + pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n", VIDC_MSG_PRIO2STRING(VIDC_INFO), inst); kfree(inst); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index f001290c5d30..48192b3bdea5 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -159,7 +159,7 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, if (!is_thumbnail_session(inst) && !is_realtime_session(inst) && (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) { if (!inst->prop.fps) { - dprintk(VIDC_INFO, "%s: instance:%p prop->fps is set 0\n", __func__, inst); + dprintk(VIDC_INFO, "%s: instance:%pK prop->fps is set 0\n", __func__, inst); load = 0; } else { load = msm_comm_get_mbs_per_sec(inst) / inst->prop.fps; @@ -167,7 +167,7 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, } dprintk(VIDC_DBG, - "inst[%p]: load %d, wxh %dx%d, fps %d, operating_rate %d, flags 0x%x, quirks 0x%x\n", + "inst[%pK]: load %d, wxh %dx%d, fps %d, operating_rate %d, flags 0x%x, quirks 0x%x\n", inst, load, inst->prop.width[OUTPUT_PORT], inst->prop.height[OUTPUT_PORT], inst->prop.fps, inst->operating_rate >> 16, inst->flags, quirks); @@ -182,7 +182,7 @@ int msm_comm_get_load(struct msm_vidc_core *core, int num_mbs_per_sec = 0; if (!core) { - dprintk(VIDC_ERR, "Invalid args: %p\n", core); + dprintk(VIDC_ERR, "Invalid args: %pK\n", core); return -EINVAL; } @@ -280,13 +280,13 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core) struct vidc_bus_vote_data *vote_data = NULL; if (!core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s Invalid device handle: %p\n", + dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n", __func__, hdev); return -EINVAL; } @@ -387,7 +387,7 @@ const struct msm_vidc_format *msm_comm_get_pixel_fmt_index( { int i, k = 0; if (!fmt || index < 0) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %p, index = %d\n", + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK, index = %d\n", fmt, index); return NULL; } @@ -409,7 +409,7 @@ struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc( { int i; if (!fmt) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %p\n", fmt); + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt); return NULL; } for (i = 0; i < size; i++) { @@ -572,11 +572,11 @@ static void change_inst_state(struct msm_vidc_inst *inst, mutex_lock(&inst->lock); if (inst->state == MSM_VIDC_CORE_INVALID) { dprintk(VIDC_DBG, - "Inst: %p is in bad state can't change state to %d\n", + "Inst: %pK is in bad state can't change state to %d\n", inst, state); goto exit; } - dprintk(VIDC_DBG, "Moved inst: %p from state: %d to state: %d\n", + dprintk(VIDC_DBG, "Moved inst: %pK from state: %d to state: %d\n", inst, inst->state, state); inst->state = state; exit: @@ -587,7 +587,7 @@ static int signal_session_msg_receipt(enum command_response cmd, struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, "Invalid(%p) instance id\n", inst); + dprintk(VIDC_ERR, "Invalid(%pK) instance id\n", inst); return -EINVAL; } if (IS_SESSION_CMD_VALID(cmd)) { @@ -628,7 +628,7 @@ static int wait_for_state(struct msm_vidc_inst *inst, { int rc = 0; if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto err_same_state; } @@ -689,7 +689,7 @@ static void handle_session_init_done(enum command_response cmd, void *data) inst = response->session_id; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, - "%s: invalid parameters, inst %p\n", __func__, inst); + "%s: invalid parameters, inst %pK\n", __func__, inst); return; } core = inst->core; @@ -813,7 +813,7 @@ static void handle_event_change(enum command_response cmd, void *data) struct buffer_info *binfo = NULL, *temp = NULL; u32 *ptr = NULL; - dprintk(VIDC_DBG, "%s - inst: %p buffer: 0x%pa extra: 0x%pa\n", + dprintk(VIDC_DBG, "%s - inst: %pK buffer: 0x%pa extra: 0x%pa\n", __func__, inst, &event_notify->packet_buffer, &event_notify->extra_data_buffer); @@ -1149,7 +1149,7 @@ static void handle_sys_idle(enum command_response cmd, void *data) goto exit; } - dprintk(VIDC_DBG, "SYS_IDLE received for core %p\n", core); + dprintk(VIDC_DBG, "SYS_IDLE received for core %pK\n", core); if (core->resources.dynamic_bw_update) { mutex_lock(&core->lock); core->idle_stats.start_time = ktime_get(); @@ -1182,23 +1182,23 @@ static void handle_session_error(enum command_response cmd, void *data) if (!inst || !inst->session || !inst->core->device) { dprintk(VIDC_ERR, - "Session (%p) not in a stable enough state to handle session error\n", + "Session (%pK) not in a stable enough state to handle session error\n", inst); return; } hdev = inst->core->device; - dprintk(VIDC_WARN, "Session error received for session %p\n", inst); + dprintk(VIDC_WARN, "Session error received for session %pK\n", inst); change_inst_state(inst, MSM_VIDC_CORE_INVALID); if (response->status == VIDC_ERR_MAX_CLIENTS) { - dprintk(VIDC_WARN, "Too many clients, rejecting %p", inst); + dprintk(VIDC_WARN, "Too many clients, rejecting %pK", inst); event = V4L2_EVENT_MSM_VIDC_MAX_CLIENTS; } else if (response->status == VIDC_ERR_NOT_SUPPORTED) { - dprintk(VIDC_WARN, "Unsupported error for %p", inst); + dprintk(VIDC_WARN, "Unsupported error for %pK", inst); event = V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED; } else { - dprintk(VIDC_WARN, "Unknown session error (%d) for %p\n", + dprintk(VIDC_WARN, "Unknown session error (%d) for %pK\n", response->status, inst); event = V4L2_EVENT_MSM_VIDC_SYS_ERROR; } @@ -1213,7 +1213,7 @@ static void msm_comm_clean_notify_client(struct msm_vidc_core *core) return; } - dprintk(VIDC_WARN, "%s: Core %p\n", __func__, core); + dprintk(VIDC_WARN, "%s: Core %pK\n", __func__, core); mutex_lock(&core->lock); core->state = VIDC_CORE_INVALID; @@ -1222,7 +1222,7 @@ static void msm_comm_clean_notify_client(struct msm_vidc_core *core) inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->lock); dprintk(VIDC_WARN, - "%s Send sys error for inst %p\n", __func__, inst); + "%s Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); } @@ -1255,7 +1255,7 @@ static void handle_sys_error(enum command_response cmd, void *data) return; } - dprintk(VIDC_WARN, "SYS_ERROR %d received for core %p\n", cmd, core); + dprintk(VIDC_WARN, "SYS_ERROR %d received for core %pK\n", cmd, core); msm_comm_clean_notify_client(core); hdev = core->device; mutex_lock(&core->lock); @@ -1290,12 +1290,12 @@ void msm_comm_session_clean(struct msm_vidc_inst *inst) hdev = inst->core->device; if (hdev && inst->session) { - dprintk(VIDC_DBG, "cleaning up instance: 0x%p\n", inst); + dprintk(VIDC_DBG, "cleaning up instance: 0x%pK\n", inst); rc = call_hfi_op(hdev, session_clean, (void *) inst->session); if (rc) { dprintk(VIDC_ERR, - "Session clean failed :%p\n", inst); + "Session clean failed :%pK\n", inst); } inst->session = NULL; } @@ -1696,7 +1696,7 @@ static void handle_fbd(enum command_response cmd, void *data) if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { dprintk(VIDC_DBG, - "extradata: userptr = %p;" + "extradata: userptr = %pK;" " bytesused = %d; length = %d\n", (u8 *)vb->v4l2_planes[extra_idx].m.userptr, vb->v4l2_planes[extra_idx].bytesused, @@ -1838,13 +1838,13 @@ int msm_comm_scale_clocks_load(struct msm_vidc_core *core, int num_mbs_per_sec) int codec = 0; if (!core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s Invalid device handle: %p\n", + dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n", __func__, hdev); return -EINVAL; } @@ -1996,7 +1996,7 @@ static int msm_comm_session_abort(struct msm_vidc_inst *inst) msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { dprintk(VIDC_ERR, - "%s: Wait interrupted or timed out [%p]: %d\n", + "%s: Wait interrupted or timed out [%pK]: %d\n", __func__, inst, abort_completion); rc = -EBUSY; } else { @@ -2023,7 +2023,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) mutex_unlock(&core->lock); if (inst->state >= MSM_VIDC_OPEN_DONE && inst->state < MSM_VIDC_CLOSE_DONE) { - dprintk(VIDC_WARN, "%s: abort inst %p\n", + dprintk(VIDC_WARN, "%s: abort inst %pK\n", __func__, inst); change_inst_state(inst, MSM_VIDC_CORE_INVALID); @@ -2035,7 +2035,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) goto err_sess_abort; } dprintk(VIDC_WARN, - "%s Send sys error for inst %p\n", + "%s Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); @@ -2290,7 +2290,7 @@ static int msm_comm_session_init(int flipped_state, hdev = inst->core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2311,7 +2311,7 @@ static int msm_comm_session_init(int flipped_state, if (!inst->session) { dprintk(VIDC_ERR, - "Failed to call session init for: %p, %p, %d, %d\n", + "Failed to call session init for: %pK, %pK, %d, %d\n", inst->core->device, inst, inst->session_type, fourcc); rc = -EINVAL; @@ -2405,7 +2405,7 @@ static int msm_vidc_load_resources(int flipped_state, hdev = core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2441,7 +2441,7 @@ static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2471,7 +2471,7 @@ static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2501,7 +2501,7 @@ static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2533,7 +2533,7 @@ static int msm_comm_session_close(int flipped_state, hdev = inst->core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2939,16 +2939,16 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) struct msm_vidc_core *core; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } dprintk(VIDC_DBG, - "Trying to move inst: %p from: 0x%x to 0x%x\n", + "Trying to move inst: %pK from: 0x%x to 0x%x\n", inst, inst->state, state); core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", inst); + "Invalid core pointer = %pK\n", inst); return -EINVAL; } mutex_lock(&inst->sync_lock); @@ -3117,7 +3117,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb) int extra_idx = 0; if (!vb || !vb->vb2_queue) { - dprintk(VIDC_ERR, "%s: Invalid input: %p\n", + dprintk(VIDC_ERR, "%s: Invalid input: %pK\n", __func__, vb); return -EINVAL; } @@ -3125,7 +3125,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb) q = vb->vb2_queue; inst = q->drv_priv; if (!inst) { - dprintk(VIDC_ERR, "%s: Invalid input: %p\n", + dprintk(VIDC_ERR, "%s: Invalid input: %pK\n", __func__, vb); return -EINVAL; } @@ -3133,12 +3133,12 @@ int msm_comm_qbuf(struct vb2_buffer *vb) core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid input: %p, %p, %p\n", inst, core, vb); + "Invalid input: %pK, %pK, %pK\n", inst, core, vb); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s: Invalid input: %p\n", + dprintk(VIDC_ERR, "%s: Invalid input: %pK\n", __func__, hdev); return -EINVAL; } @@ -3292,7 +3292,7 @@ int msm_comm_qbuf(struct vb2_buffer *vb) (void *) inst->session, &seq_hdr); if (!rc) { inst->vb2_seq_hdr = vb; - dprintk(VIDC_DBG, "Seq_hdr: %p\n", + dprintk(VIDC_DBG, "Seq_hdr: %pK\n", inst->vb2_seq_hdr); } atomic_dec(&inst->seq_hdr_reqs); @@ -3406,7 +3406,7 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype, msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { dprintk(VIDC_ERR, - "%s: Wait interrupted or timed out [%p]: %d\n", + "%s: Wait interrupted or timed out [%pK]: %d\n", __func__, inst, SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)); inst->state = MSM_VIDC_CORE_INVALID; @@ -3444,18 +3444,18 @@ int msm_comm_release_output_buffers(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } mutex_lock(&inst->outputbufs.lock); @@ -3551,18 +3551,18 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, enum hal_buffer sufficiency = HAL_BUFFER_NONE; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -3639,18 +3639,18 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -3699,7 +3699,7 @@ int msm_comm_try_set_prop(struct msm_vidc_inst *inst, int rc = 0; struct hfi_device *hdev; if (!inst) { - dprintk(VIDC_ERR, "Invalid input: %p\n", inst); + dprintk(VIDC_ERR, "Invalid input: %pK\n", inst); return -EINVAL; } @@ -3913,7 +3913,7 @@ void msm_comm_flush_pending_dynamic_buffers(struct msm_vidc_inst *inst) list_for_each_entry(binfo, &inst->registeredbufs.list, list) { if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { dprintk(VIDC_DBG, - "%s: binfo = %p device_addr = 0x%pa\n", + "%s: binfo = %pK device_addr = 0x%pa\n", __func__, binfo, &binfo->device_addr[0]); buf_ref_put(inst, binfo); } @@ -3933,18 +3933,18 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -3961,7 +3961,7 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) core->state == VIDC_CORE_UNINIT || core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p and inst %p are in bad state\n", + "Core %pK and inst %pK are in bad state\n", core, inst); msm_comm_flush_in_invalid_state(inst); return 0; @@ -4153,7 +4153,7 @@ int msm_vidc_trigger_ssr(struct msm_vidc_core *core, int rc = 0; struct hfi_device *hdev; if (!core || !core->device) { - dprintk(VIDC_WARN, "Invalid parameters: %p\n", core); + dprintk(VIDC_WARN, "Invalid parameters: %pK\n", core); return -EINVAL; } hdev = core->device; @@ -4389,7 +4389,7 @@ int msm_comm_kill_session(struct msm_vidc_inst *inst) change_inst_state(inst, MSM_VIDC_CLOSE_DONE); } else { dprintk(VIDC_WARN, - "Inactive session %p, triggering an internal session error\n", + "Inactive session %pK, triggering an internal session error\n", inst); msm_comm_generate_session_error(inst); @@ -4421,7 +4421,7 @@ struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst, struct msm_smem *m = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return NULL; } mutex_lock(&inst->core->lock); @@ -4439,7 +4439,7 @@ void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem) { if (!inst || !inst->core || !mem) { dprintk(VIDC_ERR, - "%s: invalid params: %p %p\n", __func__, inst, mem); + "%s: invalid params: %pK %pK\n", __func__, inst, mem); return; } @@ -4458,7 +4458,7 @@ int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst, { if (!inst || !mem) { dprintk(VIDC_ERR, - "%s: invalid params: %p %p\n", __func__, inst, mem); + "%s: invalid params: %pK %pK\n", __func__, inst, mem); return -EINVAL; } return msm_smem_cache_operations(inst->mem_client, mem, cache_ops); @@ -4470,7 +4470,7 @@ struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst, struct msm_smem *m = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return NULL; } @@ -4496,7 +4496,7 @@ int msm_comm_smem_get_domain_partition(struct msm_vidc_inst *inst, int *domain_num, int *partition_num) { if (!inst || !domain_num || !partition_num) { - dprintk(VIDC_ERR, "%s: invalid params: %p %p %p\n", + dprintk(VIDC_ERR, "%s: invalid params: %pK %pK %pK\n", __func__, inst, domain_num, partition_num); return -EINVAL; } diff --git a/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c b/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c index 708b44a454f8..231ec66208ee 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014 - 2016, 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 @@ -40,7 +40,7 @@ static inline int msm_dcvs_count_active_instances(struct msm_vidc_core *core) struct msm_vidc_inst *inst = NULL; if (!core) { - dprintk(VIDC_ERR, "%s: Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s: Invalid args: %pK\n", __func__, core); return -EINVAL; } @@ -116,7 +116,7 @@ static void msm_dcvs_dec_check_and_scale_clocks(struct msm_vidc_inst *inst) void msm_dcvs_check_and_scale_clocks(struct msm_vidc_inst *inst, bool is_etb) { if (!inst) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -168,7 +168,7 @@ void msm_dcvs_init_load(struct msm_vidc_inst *inst) dprintk(VIDC_DBG, "Init DCVS Load\n"); if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -217,7 +217,7 @@ void msm_dcvs_init(struct msm_vidc_inst *inst) dprintk(VIDC_DBG, "Init DCVS Struct\n"); if (!inst) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -234,7 +234,7 @@ void msm_dcvs_monitor_buffer(struct msm_vidc_inst *inst) struct hal_buffer_requirements *output_buf_req; if (!inst) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } dcvs = &inst->dcvs; @@ -243,7 +243,7 @@ void msm_dcvs_monitor_buffer(struct msm_vidc_inst *inst) output_buf_req = get_buff_req_buffer(inst, msm_comm_get_hal_output_buffer(inst)); if (!output_buf_req) { - dprintk(VIDC_ERR, "%s : Get output buffer req failed %p\n", + dprintk(VIDC_ERR, "%s : Get output buffer req failed %pK\n", __func__, inst); mutex_unlock(&inst->lock); return; diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c index c422ed7354b0..5cf5e818b1bb 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -76,13 +76,13 @@ static ssize_t core_info_read(struct file *file, char __user *buf, int i = 0, rc = 0; if (!core || !core->device) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", core); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); return 0; } hdev = core->device; INIT_DBG_BUF(dbg_buf); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "CORE %d: 0x%p\n", core->id, core); + write_str(&dbg_buf, "CORE %d: 0x%pK\n", core->id, core); write_str(&dbg_buf, "===============================\n"); write_str(&dbg_buf, "Core state: %d\n", core->state); rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info); @@ -242,7 +242,7 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, struct dentry *dir = NULL; char debugfs_name[MAX_DEBUGFS_NAME]; if (!core) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", core); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); goto failed_create_dir; } @@ -306,15 +306,15 @@ static ssize_t inst_info_read(struct file *file, char __user *buf, struct msm_vidc_inst *inst = file->private_data; int i, j; if (!inst) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", inst); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", inst); return 0; } INIT_DBG_BUF(dbg_buf); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "INSTANCE: 0x%p (%s)\n", inst, + write_str(&dbg_buf, "INSTANCE: 0x%pK (%s)\n", inst, inst->session_type == MSM_VIDC_ENCODER ? "Encoder" : "Decoder"); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "core: 0x%p\n", inst->core); + write_str(&dbg_buf, "core: 0x%pK\n", inst->core); write_str(&dbg_buf, "height: %d\n", inst->prop.height[CAPTURE_PORT]); write_str(&dbg_buf, "width: %d\n", inst->prop.width[CAPTURE_PORT]); write_str(&dbg_buf, "fps: %d\n", inst->prop.fps); @@ -381,10 +381,10 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, struct dentry *dir = NULL; char debugfs_name[MAX_DEBUGFS_NAME]; if (!inst) { - dprintk(VIDC_ERR, "Invalid params, inst: %p\n", inst); + dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst); goto failed_create_dir; } - snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst); dir = debugfs_create_dir(debugfs_name, parent); if (!dir) { dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n"); diff --git a/drivers/media/platform/msm/vidc/q6_hfi.c b/drivers/media/platform/msm/vidc/q6_hfi.c index 10f4baaccd45..31f626353575 100644 --- a/drivers/media/platform/msm/vidc/q6_hfi.c +++ b/drivers/media/platform/msm/vidc/q6_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 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 @@ -202,7 +202,7 @@ static int q6_hfi_register_iommu_domains(struct q6_hfi_device *device) struct iommu_info *iommu_map; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return -EINVAL; } @@ -220,7 +220,7 @@ static int q6_hfi_register_iommu_domains(struct q6_hfi_device *device) domain = iommu_group_get_iommudata(iommu_map->group); if (IS_ERR_OR_NULL(domain)) { dprintk(VIDC_ERR, - "Failed to get domain data for group %p\n", + "Failed to get domain data for group %pK\n", iommu_map->group); rc = -EINVAL; goto fail_group; @@ -228,7 +228,7 @@ static int q6_hfi_register_iommu_domains(struct q6_hfi_device *device) iommu_map->domain = msm_find_domain_no(domain); if (iommu_map->domain < 0) { dprintk(VIDC_ERR, - "Failed to get domain index for domain %p\n", + "Failed to get domain index for domain %pK\n", domain); rc = -EINVAL; goto fail_group; @@ -254,7 +254,7 @@ static void q6_hfi_deregister_iommu_domains(struct q6_hfi_device *device) int i = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return; } @@ -347,7 +347,7 @@ static void *q6_hfi_get_device(u32 device_id, int rc = 0; if (!callback) { - dprintk(VIDC_ERR, "%s Invalid params: %p\n", + dprintk(VIDC_ERR, "%s Invalid params: %pK\n", __func__, callback); return NULL; } @@ -663,7 +663,7 @@ static int q6_hfi_session_clean(void *session) return -EINVAL; } sess_close = session; - dprintk(VIDC_DBG, "deleted the session: 0x%p\n", + dprintk(VIDC_DBG, "deleted the session: 0x%pK\n", sess_close->session_id); mutex_lock(&((struct q6_hfi_device *) sess_close->device)->session_lock); @@ -1207,7 +1207,7 @@ static int q6_hfi_iommu_attach(struct q6_hfi_device *device) struct iommu_info *iommu_map; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return -EINVAL; } @@ -1222,7 +1222,7 @@ static int q6_hfi_iommu_attach(struct q6_hfi_device *device) rc = PTR_ERR(domain) ?: -EINVAL; break; } - dprintk(VIDC_DBG, "Attaching domain(id:%d) %p to group %p\n", + dprintk(VIDC_DBG, "Attaching domain(id:%d) %pK to group %pK\n", iommu_map->domain, domain, group); rc = iommu_attach_group(domain, group); if (rc) { @@ -1253,7 +1253,7 @@ static void q6_hfi_iommu_detach(struct q6_hfi_device *device) int i; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid parameter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return; } @@ -1382,7 +1382,7 @@ int q6_hfi_initialize(struct hfi_device *hdev, u32 device_id, int rc = 0; if (!hdev || !res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK %pK %pK\n", hdev, res, callback); rc = -EINVAL; goto err_hfi_init; diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 76ad1bcca9cd..0015c84cf85b 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -370,7 +370,7 @@ static int venus_hfi_write_queue(void *info, u8 *packet, u32 *rx_req_is_set) } if (msm_vidc_debug & VIDC_PKT) { - dprintk(VIDC_PKT, "%s: %p\n", __func__, qinfo); + dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); venus_hfi_dump_packet(packet); } @@ -580,7 +580,7 @@ static int venus_hfi_read_queue(void *info, u8 *packet, u32 *pb_tx_req_is_set) if ((msm_vidc_debug & VIDC_PKT) && (queue->qhdr_type & HFI_Q_ID_CTRL_TO_HOST_MSG_Q)) { - dprintk(VIDC_PKT, "%s: %p\n", __func__, qinfo); + dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); venus_hfi_dump_packet(packet); } @@ -611,7 +611,7 @@ static int venus_hfi_alloc(struct venus_hfi_device *dev, void *mem, rc = -ENOMEM; goto fail_smem_alloc; } - dprintk(VIDC_DBG, "venus_hfi_alloc: ptr = %p, size = %d\n", + dprintk(VIDC_DBG, "venus_hfi_alloc: ptr = %pK, size = %d\n", alloc->kvaddr, size); rc = msm_smem_cache_operations(dev->hal_client, alloc, SMEM_CACHE_CLEAN); @@ -631,7 +631,7 @@ fail_smem_alloc: static void venus_hfi_free(struct venus_hfi_device *dev, struct msm_smem *mem) { if (!dev || !mem) { - dprintk(VIDC_ERR, "invalid param %p %p\n", dev, mem); + dprintk(VIDC_ERR, "invalid param %pK %pK\n", dev, mem); return; } @@ -647,7 +647,7 @@ static void venus_hfi_write_register( u32 hwiosymaddr = reg; u8 *base_addr; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return; } if (device->clk_state != ENABLED_PREPARED) { @@ -657,7 +657,7 @@ static void venus_hfi_write_register( } base_addr = device->hal_data->register_base; - dprintk(VIDC_DBG, "Base addr: 0x%p, written to: 0x%x, Value: 0x%x...\n", + dprintk(VIDC_DBG, "Base addr: 0x%pK, written to: 0x%x, Value: 0x%x...\n", base_addr, hwiosymaddr, value); base_addr += hwiosymaddr; writel_relaxed(value, base_addr); @@ -669,7 +669,7 @@ static int venus_hfi_read_register(struct venus_hfi_device *device, u32 reg) int rc = 0; u8 *base_addr; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } if (device->clk_state != ENABLED_PREPARED) { @@ -681,7 +681,7 @@ static int venus_hfi_read_register(struct venus_hfi_device *device, u32 reg) rc = readl_relaxed(base_addr + reg); rmb(); - dprintk(VIDC_DBG, "Base addr: 0x%p, read from: 0x%x, value: 0x%x...\n", + dprintk(VIDC_DBG, "Base addr: 0x%pK, read from: 0x%x, value: 0x%x...\n", base_addr, reg, rc); return rc; @@ -783,7 +783,7 @@ static void venus_hfi_iommu_detach(struct venus_hfi_device *device) int i; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid paramter: %p\n", device); + dprintk(VIDC_ERR, "Invalid paramter: %pK\n", device); return; } @@ -1209,7 +1209,7 @@ static int __alloc_ocmem(struct venus_hfi_device *device) unsigned long size; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1244,7 +1244,7 @@ static int __free_ocmem(struct venus_hfi_device *device) int rc = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1268,14 +1268,14 @@ static int __set_ocmem(struct venus_hfi_device *device, bool locked) struct on_chip_mem *ocmem; if (!device) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } ocmem = &device->resources.ocmem; if (!ocmem->buf) { - dprintk(VIDC_ERR, "Invalid params, ocmem_buffer: 0x%p\n", + dprintk(VIDC_ERR, "Invalid params, ocmem_buffer: 0x%pK\n", ocmem->buf); return -EINVAL; } @@ -1304,7 +1304,7 @@ static int __unset_ocmem(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); rc = -EINVAL; goto ocmem_unset_failed; @@ -1335,7 +1335,7 @@ static int __alloc_set_ocmem(struct venus_hfi_device *device, bool locked) int rc = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1375,7 +1375,7 @@ static int __unset_free_ocmem(struct venus_hfi_device *device) int rc = 0; if (!device || !device->res) { - dprintk(VIDC_ERR, "%s Invalid param, device: 0x%p\n", + dprintk(VIDC_ERR, "%s Invalid param, device: 0x%pK\n", __func__, device); return -EINVAL; } @@ -1551,7 +1551,7 @@ static unsigned long venus_hfi_get_core_clock_rate(void *dev) struct clock_info *vc; if (!device) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, device); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, device); return -EINVAL; } @@ -1607,7 +1607,7 @@ static int venus_hfi_halt_axi(struct venus_hfi_device *device) u32 reg; int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid input: %p\n", device); + dprintk(VIDC_ERR, "Invalid input: %pK\n", device); return -EINVAL; } /* @@ -1642,7 +1642,7 @@ static inline int venus_hfi_power_off(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } if (!device->power_enabled) { @@ -1709,7 +1709,7 @@ static inline int venus_hfi_power_on(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } if (device->power_enabled) @@ -1825,7 +1825,7 @@ static int venus_hfi_power_enable(void *dev) int rc = 0; struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } mutex_lock(&device->write_lock); @@ -1845,7 +1845,7 @@ static int venus_hfi_regulator_set_voltage( struct regulator_info *rinfo = NULL; if (!device || !cv_info) { - dprintk(VIDC_WARN, "%s: invalid args %p %p\n", + dprintk(VIDC_WARN, "%s: invalid args %pK %pK\n", __func__, device, cv_info); return -EINVAL; } @@ -1893,7 +1893,7 @@ static int venus_hfi_scale_regulators(struct venus_hfi_device *device, bool matches = false; if (!device || !data) { - dprintk(VIDC_ERR, "%s: Invalid args %p, %p\n", + dprintk(VIDC_ERR, "%s: Invalid args %pK, %pK\n", __func__, device, data); return -EINVAL; } @@ -1968,7 +1968,7 @@ static int venus_hfi_scale_clocks(void *dev, int load, struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "Invalid args: %p\n", device); + dprintk(VIDC_ERR, "Invalid args: %pK\n", device); return -EINVAL; } @@ -2566,7 +2566,7 @@ static int venus_hfi_core_init(void *device) goto err_core_init; } - dprintk(VIDC_DBG, "Dev_Virt: 0x%pa, Reg_Virt: 0x%p\n", + dprintk(VIDC_DBG, "Dev_Virt: 0x%pa, Reg_Virt: 0x%pK\n", &dev->hal_data->firmware_base, dev->hal_data->register_base); @@ -2718,12 +2718,12 @@ static void venus_hfi_core_clear_interrupt(struct venus_hfi_device *device) device->intr_status |= intr_status; device->reg_count++; dprintk(VIDC_DBG, - "INTERRUPT for device: 0x%p: times: %d interrupt_status: %d\n", + "INTERRUPT for device: 0x%pK: times: %d interrupt_status: %d\n", device, device->reg_count, intr_status); } else { device->spur_count++; dprintk(VIDC_INFO, - "SPURIOUS_INTR for device: 0x%p: times: %d interrupt_status: %d\n", + "SPURIOUS_INTR for device: 0x%pK: times: %d interrupt_status: %d\n", device, device->spur_count, intr_status); } @@ -2876,7 +2876,7 @@ static int venus_hfi_session_clean(void *session) sess_close = session; device = sess_close->device; venus_hfi_flush_debug_queue(sess_close->device, NULL); - dprintk(VIDC_DBG, "deleted the session: 0x%p\n", + dprintk(VIDC_DBG, "deleted the session: 0x%pK\n", sess_close); mutex_lock(&device->session_lock); list_del(&sess_close->list); @@ -2914,7 +2914,7 @@ static void *venus_hfi_session_init(void *device, void *session_id, new_session->codec = codec_type; new_session->domain = session_type; dprintk(VIDC_DBG, - "%s: inst %p, session %p, codec 0x%x, domain 0x%x\n", + "%s: inst %pK, session %pK, codec 0x%x, domain 0x%x\n", __func__, session_id, new_session, new_session->codec, new_session->domain); @@ -2992,7 +2992,7 @@ static int venus_hfi_session_abort(void *sess) struct hal_session *session; session = sess; if (!session || !session->device) { - dprintk(VIDC_ERR, "%s: Invalid Params %p\n", + dprintk(VIDC_ERR, "%s: Invalid Params %pK\n", __func__, session); return -EINVAL; } @@ -3012,7 +3012,7 @@ static int venus_hfi_session_set_buffers(void *sess, struct venus_hfi_device *device; if (!session || !session->device || !buffer_info) { - dprintk(VIDC_ERR, "%s: Invalid Params, %p %p\n", + dprintk(VIDC_ERR, "%s: Invalid Params, %pK %pK\n", __func__, session, buffer_info); return -EINVAL; } @@ -3047,7 +3047,7 @@ static int venus_hfi_session_release_buffers(void *sess, struct venus_hfi_device *device; if (!session || !session->device || !buffer_info) { - dprintk(VIDC_ERR, "%s: Invalid Params %p, %p\n", + dprintk(VIDC_ERR, "%s: Invalid Params %pK, %pK\n", __func__, session, buffer_info); return -EINVAL; } @@ -3738,7 +3738,7 @@ static void venus_hfi_response_handler(struct venus_hfi_device *device) } venus_hfi_flush_debug_queue(device, packet); } else { - dprintk(VIDC_DBG, "device (%p) is in deinit state\n", device); + dprintk(VIDC_DBG, "device (%pK) is in deinit state\n", device); } kfree(packet); } @@ -3750,7 +3750,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work) dprintk(VIDC_INFO, "GOT INTERRUPT\n"); if (!device->callback) { - dprintk(VIDC_ERR, "No interrupt callback function: %p\n", + dprintk(VIDC_ERR, "No interrupt callback function: %pK\n", device); return; } @@ -3850,7 +3850,7 @@ static inline int venus_hfi_init_clocks(struct msm_vidc_platform_resources *res, struct clock_info *cl = NULL; if (!res || !device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } @@ -3921,7 +3921,7 @@ static inline void venus_hfi_disable_unprepare_clks( struct clock_info *cl; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return; } @@ -3957,7 +3957,7 @@ static inline int venus_hfi_prepare_enable_clks(struct venus_hfi_device *device) struct clock_info *cl = NULL, *cl_fail = NULL; int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } @@ -4026,7 +4026,7 @@ static int venus_hfi_register_iommu_domains(struct venus_hfi_device *device, domain = iommu_group_get_iommudata(iommu_map->group); if (!domain) { dprintk(VIDC_ERR, - "Failed to get domain data for group %p\n", + "Failed to get domain data for group %pK\n", iommu_map->group); rc = -EINVAL; goto fail_group; @@ -4034,7 +4034,7 @@ static int venus_hfi_register_iommu_domains(struct venus_hfi_device *device, iommu_map->domain = msm_find_domain_no(domain); if (iommu_map->domain < 0) { dprintk(VIDC_ERR, - "Failed to get domain index for domain %p\n", + "Failed to get domain index for domain %pK\n", domain); rc = -EINVAL; goto fail_group; @@ -4180,7 +4180,7 @@ static int venus_hfi_init_resources(struct venus_hfi_device *device, device->res = res; if (!res) { - dprintk(VIDC_ERR, "Invalid params: %p\n", res); + dprintk(VIDC_ERR, "Invalid params: %pK\n", res); return -ENODEV; } @@ -4237,7 +4237,7 @@ static int venus_hfi_iommu_get_domain_partition(void *dev, u32 flags, struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "%s: Invalid param device: %p\n", + dprintk(VIDC_ERR, "%s: Invalid param device: %pK\n", __func__, device); return -EINVAL; } @@ -4262,7 +4262,7 @@ static int protect_cp_mem(struct venus_hfi_device *device) iommu_group_set = &device->res->iommu_group_set; if (!iommu_group_set) { - dprintk(VIDC_ERR, "invalid params: %p\n", iommu_group_set); + dprintk(VIDC_ERR, "invalid params: %pK\n", iommu_group_set); return -EINVAL; } @@ -4430,7 +4430,7 @@ static int venus_hfi_load_fw(void *dev) struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "%s Invalid paramter: %p\n", + dprintk(VIDC_ERR, "%s Invalid paramter: %pK\n", __func__, device); return -EINVAL; } @@ -4520,7 +4520,7 @@ static void venus_hfi_unload_fw(void *dev) { struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "%s Invalid paramter: %p\n", + dprintk(VIDC_ERR, "%s Invalid paramter: %pK\n", __func__, device); return; } @@ -4556,7 +4556,7 @@ static int venus_hfi_get_fw_info(void *dev, struct hal_fw_info *fw_info) if (!device || !fw_info) { dprintk(VIDC_ERR, - "%s Invalid paramter: device = %p fw_info = %p\n", + "%s Invalid paramter: device = %pK fw_info = %pK\n", __func__, device, fw_info); return -EINVAL; } @@ -4745,7 +4745,7 @@ static void *venus_hfi_get_device(u32 device_id, int rc = 0; if (!res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p\n", res, callback); + dprintk(VIDC_ERR, "Invalid params: %pK %pK\n", res, callback); return NULL; } @@ -4845,7 +4845,7 @@ int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, int rc = 0; if (!hdev || !res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK %pK %pK\n", hdev, res, callback); rc = -EINVAL; goto err_venus_hfi_init; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.c b/drivers/media/platform/msm/vidc/vidc_hfi.c index ef0de370eb09..193b42f69aae 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.c +++ b/drivers/media/platform/msm/vidc/vidc_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -61,7 +61,7 @@ void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type, struct hfi_device *hdev) { if (!hdev) { - dprintk(VIDC_ERR, "%s invalid device %p", __func__, hdev); + dprintk(VIDC_ERR, "%s invalid device %pK", __func__, hdev); return; } diff --git a/drivers/media/platform/msm/vidc/vmem/vmem.c b/drivers/media/platform/msm/vidc/vmem/vmem.c index 81e5b087b2a7..fb733fbae92b 100644 --- a/drivers/media/platform/msm/vidc/vmem/vmem.c +++ b/drivers/media/platform/msm/vidc/vmem/vmem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2016, 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 @@ -115,7 +115,7 @@ static inline u32 __readl(void * __iomem addr) { u32 value = 0; - pr_debug("read %p ", addr); + pr_debug("read %pK ", addr); value = readl_relaxed(addr); pr_debug("-> %08x\n", value); @@ -124,7 +124,7 @@ static inline u32 __readl(void * __iomem addr) static inline void __writel(u32 val, void * __iomem addr) { - pr_debug("write %08x -> %p\n", val, addr); + pr_debug("write %08x -> %pK\n", val, addr); writel_relaxed(val, addr); /* * Commit all writes via a mem barrier, as subsequent __readl() From edf380792d77d4137924c0065e44dbd0c4932268 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 29 Nov 2015 19:37:57 -0800 Subject: [PATCH 45/48] ipv6: add complete rcu protection around np->opt [ Upstream commit 45f6fad84cc305103b28d73482b344d7f5b76f39 ] This patch addresses multiple problems : UDP/RAW sendmsg() need to get a stable struct ipv6_txoptions while socket is not locked : Other threads can change np->opt concurrently. Dmitry posted a syzkaller (http://github.com/google/syzkaller) program desmonstrating use-after-free. Starting with TCP/DCCP lockless listeners, tcp_v6_syn_recv_sock() and dccp_v6_request_recv_sock() also need to use RCU protection to dereference np->opt once (before calling ipv6_dup_options()) This patch adds full RCU protection to np->opt b/28746669 Reported-by: Dmitry Vyukov Signed-off-by: Eric Dumazet Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Dennis Cagle Git-commit: 45f6fad84cc305103b28d73482b344d7f5b76f39 Git-repo: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git (cherry picked from commit 46ddb98e2018a5a62cefa75b3c80882850c91e39) Signed-off-by: Ravi Kumar Siddojigari Change-Id: I10d51f00b5f570fbc5e849aad3d05ac04bc2a6e3 Signed-off-by: Venumadhav Kurva --- include/linux/ipv6.h | 2 +- include/net/ipv6.h | 20 +++++++++++++++++- net/dccp/ipv6.c | 33 ++++++++++++++++++----------- net/ipv6/af_inet6.c | 13 ++++++++---- net/ipv6/datagram.c | 4 +++- net/ipv6/exthdrs.c | 3 ++- net/ipv6/inet6_connection_sock.c | 11 +++++++--- net/ipv6/ipv6_sockglue.c | 36 +++++++++++++++++++++----------- net/ipv6/raw.c | 10 ++++++--- net/ipv6/syncookies.c | 2 +- net/ipv6/tcp_ipv6.c | 28 +++++++++++++++---------- net/ipv6/udp.c | 8 +++++-- net/l2tp/l2tp_ip6.c | 8 +++++-- 13 files changed, 124 insertions(+), 54 deletions(-) diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index a6c5471822d3..c7972a6b2205 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -220,7 +220,7 @@ struct ipv6_pinfo { struct ipv6_ac_socklist *ipv6_ac_list; struct ipv6_fl_socklist __rcu *ipv6_fl_list; - struct ipv6_txoptions *opt; + struct ipv6_txoptions __rcu *opt; struct sk_buff *pktoptions; struct sk_buff *rxpmtu; struct { diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 27e9ba47b304..7dfa475473ba 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -203,6 +203,7 @@ extern rwlock_t ip6_ra_lock; */ struct ipv6_txoptions { + atomic_t refcnt; /* Length of this structure */ int tot_len; @@ -215,7 +216,7 @@ struct ipv6_txoptions { struct ipv6_opt_hdr *dst0opt; struct ipv6_rt_hdr *srcrt; /* Routing Header */ struct ipv6_opt_hdr *dst1opt; - + struct rcu_head rcu; /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ }; @@ -254,6 +255,23 @@ extern void fl6_free_socklist(struct sock *sk); extern int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen); extern int ip6_flowlabel_init(void); extern void ip6_flowlabel_cleanup(void); +static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np) +{ + struct ipv6_txoptions *opt; + + rcu_read_lock(); + opt = rcu_dereference(np->opt); + if (opt && !atomic_inc_not_zero(&opt->refcnt)) + opt = NULL; + rcu_read_unlock(); + return opt; +} + +static inline void txopt_put(struct ipv6_txoptions *opt) +{ + if (opt && atomic_dec_and_test(&opt->refcnt)) + kfree_rcu(opt, rcu); +} static inline void fl6_sock_release(struct ip6_flowlabel *fl) { diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 6cf9f7782ad4..86eedbaf037f 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -235,7 +235,9 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) security_req_classify_flow(req, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); + rcu_read_unlock(); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { @@ -252,7 +254,10 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) &ireq6->loc_addr, &ireq6->rmt_addr); fl6.daddr = ireq6->rmt_addr; - err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); + rcu_read_lock(); + err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), + np->tclass); + rcu_read_unlock(); err = net_xmit_eval(err); } @@ -448,6 +453,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, { struct inet6_request_sock *ireq6 = inet6_rsk(req); struct ipv6_pinfo *newnp, *np = inet6_sk(sk); + struct ipv6_txoptions *opt; struct inet_sock *newinet; struct dccp6_sock *newdp6; struct sock *newsk; @@ -571,13 +577,15 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, * Yes, keeping reference count would be much more clever, but we make * one more one thing there: reattach optmem to newsk. */ - if (np->opt != NULL) - newnp->opt = ipv6_dup_options(newsk, np->opt); - + opt = rcu_dereference(np->opt); + if (opt) { + opt = ipv6_dup_options(newsk, opt); + RCU_INIT_POINTER(newnp->opt, opt); + } inet_csk(newsk)->icsk_ext_hdr_len = 0; - if (newnp->opt != NULL) - inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + - newnp->opt->opt_flen); + if (opt) + inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + + opt->opt_flen; dccp_sync_mss(newsk, dst_mtu(dst)); @@ -829,6 +837,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, struct ipv6_pinfo *np = inet6_sk(sk); struct dccp_sock *dp = dccp_sk(sk); struct in6_addr *saddr = NULL, *final_p, final; + struct ipv6_txoptions *opt; struct flowi6 fl6; struct dst_entry *dst; int addr_type; @@ -931,7 +940,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, fl6.fl6_sport = inet->inet_sport; security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl6, np->opt, &final); + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + final_p = fl6_update_dst(&fl6, opt, &final); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); if (IS_ERR(dst)) { @@ -951,9 +961,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, __ip6_dst_store(sk, dst, NULL, NULL); icsk->icsk_ext_hdr_len = 0; - if (np->opt != NULL) - icsk->icsk_ext_hdr_len = (np->opt->opt_flen + - np->opt->opt_nflen); + if (opt) + icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; inet->inet_dport = usin->sin6_port; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index d29ae19ae698..04e88b508d4e 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -448,9 +448,11 @@ void inet6_destroy_sock(struct sock *sk) /* Free tx options */ - opt = xchg(&np->opt, NULL); - if (opt != NULL) - sock_kfree_s(sk, opt, opt->tot_len); + opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } } EXPORT_SYMBOL_GPL(inet6_destroy_sock); @@ -697,7 +699,10 @@ int inet6_sk_rebuild_header(struct sock *sk) fl6.flowi6_uid = sock_i_uid(sk); security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), + &final); + rcu_read_unlock(); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 2b7cbebcd2b1..7d766307438c 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -169,8 +169,10 @@ ipv4_connected: security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - opt = flowlabel ? flowlabel->opt : np->opt; + rcu_read_lock(); + opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt); final_p = fl6_update_dst(&fl6, opt, &final); + rcu_read_unlock(); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); err = 0; diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 8d67900aa003..33dbd6c1a00d 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -727,6 +727,7 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt) *((char **)&opt2->dst1opt) += dif; if (opt2->srcrt) *((char **)&opt2->srcrt) += dif; + atomic_set(&opt2->refcnt, 1); } return opt2; } @@ -790,7 +791,7 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, return ERR_PTR(-ENOBUFS); memset(opt2, 0, tot_len); - + atomic_set(&opt2->refcnt, 1); opt2->tot_len = tot_len; p = (char *)(opt2 + 1); diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 329985bb067b..f92676cb879f 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -78,7 +78,9 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, memset(fl6, 0, sizeof(*fl6)); fl6->flowi6_proto = IPPROTO_TCP; fl6->daddr = treq->rmt_addr; - final_p = fl6_update_dst(fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); + rcu_read_unlock(); fl6->saddr = treq->loc_addr; fl6->flowi6_oif = treq->iif; fl6->flowi6_mark = inet_rsk(req)->ir_mark; @@ -214,7 +216,9 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk, fl6->fl6_dport = inet->inet_dport; security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); - final_p = fl6_update_dst(fl6, np->opt, &final); + rcu_read_lock(); + final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); + rcu_read_unlock(); dst = __inet6_csk_dst_check(sk, np->dst_cookie); if (!dst) { @@ -248,7 +252,8 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) /* Restore final destination back after routing done */ fl6.daddr = np->daddr; - res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); + res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), + np->tclass); rcu_read_unlock(); return res; } diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index d1e2e8ef29c5..f4d2412d9c60 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -110,10 +110,12 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk, icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); } - opt = xchg(&inet6_sk(sk)->opt, opt); + opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt, + opt); } else { spin_lock(&sk->sk_dst_lock); - opt = xchg(&inet6_sk(sk)->opt, opt); + opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt, + opt); spin_unlock(&sk->sk_dst_lock); } sk_dst_reset(sk); @@ -213,9 +215,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, sk->sk_socket->ops = &inet_dgram_ops; sk->sk_family = PF_INET; } - opt = xchg(&np->opt, NULL); - if (opt) - sock_kfree_s(sk, opt, opt->tot_len); + opt = xchg((__force struct ipv6_txoptions **)&np->opt, + NULL); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } pktopt = xchg(&np->pktoptions, NULL); kfree_skb(pktopt); @@ -385,7 +390,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW)) break; - opt = ipv6_renew_options(sk, np->opt, optname, + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + opt = ipv6_renew_options(sk, opt, optname, (struct ipv6_opt_hdr __user *)optval, optlen); if (IS_ERR(opt)) { @@ -414,8 +420,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, retv = 0; opt = ipv6_update_options(sk, opt); sticky_done: - if (opt) - sock_kfree_s(sk, opt, opt->tot_len); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } break; } @@ -468,6 +476,7 @@ sticky_done: break; memset(opt, 0, sizeof(*opt)); + atomic_set(&opt->refcnt, 1); opt->tot_len = sizeof(*opt) + optlen; retv = -EFAULT; if (copy_from_user(opt+1, optval, optlen)) @@ -484,8 +493,10 @@ update: retv = 0; opt = ipv6_update_options(sk, opt); done: - if (opt) - sock_kfree_s(sk, opt, opt->tot_len); + if (opt) { + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); + txopt_put(opt); + } break; } case IPV6_UNICAST_HOPS: @@ -1085,10 +1096,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, case IPV6_RTHDR: case IPV6_DSTOPTS: { + struct ipv6_txoptions *opt; lock_sock(sk); - len = ipv6_getsockopt_sticky(sk, np->opt, - optname, optval, len); + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len); release_sock(sk); /* check if ipv6_getsockopt_sticky() returns err code */ if (len < 0) diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index a9db8d252c9b..27e974fdf2b7 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -726,6 +726,7 @@ static int rawv6_probe_proto_opt(struct flowi6 *fl6, struct msghdr *msg) static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len) { + struct ipv6_txoptions *opt_to_free = NULL; struct ipv6_txoptions opt_space; struct sockaddr_in6 * sin6 = (struct sockaddr_in6 *) msg->msg_name; struct in6_addr *daddr, *final_p, final; @@ -833,8 +834,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (!(opt->opt_nflen|opt->opt_flen)) opt = NULL; } - if (opt == NULL) - opt = np->opt; + if (!opt) { + opt = txopt_get(np); + opt_to_free = opt; + } if (flowlabel) opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); @@ -901,7 +904,8 @@ done: dst_release(dst); out: fl6_sock_release(flowlabel); - return err<0?err:len; + txopt_put(opt_to_free); + return err < 0 ? err : len; do_confirm: dst_confirm(dst); if (!(msg->msg_flags & MSG_PROBE) || len) diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index ba8622daffd7..701d0656a402 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -237,7 +237,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = IPPROTO_TCP; fl6.daddr = ireq6->rmt_addr; - final_p = fl6_update_dst(&fl6, np->opt, &final); + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); fl6.saddr = ireq6->loc_addr; fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.flowi6_mark = ireq->ir_mark; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 2d064e8a8fb8..c22d2540beb5 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -133,6 +133,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_sock *tp = tcp_sk(sk); struct in6_addr *saddr = NULL, *final_p, final; + struct ipv6_txoptions *opt; struct rt6_info *rt; struct flowi6 fl6; struct dst_entry *dst; @@ -254,7 +255,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, fl6.fl6_sport = inet->inet_sport; fl6.flowi6_uid = sock_i_uid(sk); - final_p = fl6_update_dst(&fl6, np->opt, &final); + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); + final_p = fl6_update_dst(&fl6, opt, &final); security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); @@ -283,9 +285,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, tcp_fetch_timewait_stamp(sk, dst); icsk->icsk_ext_hdr_len = 0; - if (np->opt) - icsk->icsk_ext_hdr_len = (np->opt->opt_flen + - np->opt->opt_nflen); + if (opt) + icsk->icsk_ext_hdr_len = opt->opt_flen + + opt->opt_nflen; tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); @@ -481,7 +483,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, fl6->daddr = treq->rmt_addr; skb_set_queue_mapping(skb, queue_mapping); - err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass); + err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), + np->tclass); err = net_xmit_eval(err); } @@ -1090,6 +1093,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, struct inet6_request_sock *treq; struct ipv6_pinfo *newnp, *np = inet6_sk(sk); struct tcp6_sock *newtcp6sk; + struct ipv6_txoptions *opt; struct inet_sock *newinet; struct tcp_sock *newtp; struct sock *newsk; @@ -1223,13 +1227,15 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, but we make one more one thing there: reattach optmem to newsk. */ - if (np->opt) - newnp->opt = ipv6_dup_options(newsk, np->opt); - + opt = rcu_dereference(np->opt); + if (opt) { + opt = ipv6_dup_options(newsk, opt); + RCU_INIT_POINTER(newnp->opt, opt); + } inet_csk(newsk)->icsk_ext_hdr_len = 0; - if (newnp->opt) - inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + - newnp->opt->opt_flen); + if (opt) + inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + + opt->opt_flen; tcp_mtup_init(newsk); tcp_sync_mss(newsk, dst_mtu(dst)); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index e62340d60fab..2adb06986852 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1015,6 +1015,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name; struct in6_addr *daddr, *final_p, final; struct ipv6_txoptions *opt = NULL; + struct ipv6_txoptions *opt_to_free = NULL; struct ip6_flowlabel *flowlabel = NULL; struct flowi6 fl6; struct dst_entry *dst; @@ -1169,8 +1170,10 @@ do_udp_sendmsg: opt = NULL; connected = 0; } - if (opt == NULL) - opt = np->opt; + if (!opt) { + opt = txopt_get(np); + opt_to_free = opt; + } if (flowlabel) opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); @@ -1271,6 +1274,7 @@ do_append_data: out: dst_release(dst); fl6_sock_release(flowlabel); + txopt_put(opt_to_free); if (!err) return len; /* diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index e6e8408c9e36..3b61ddd6e4a6 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -485,6 +485,7 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, (struct sockaddr_l2tpip6 *) msg->msg_name; struct in6_addr *daddr, *final_p, final; struct ipv6_pinfo *np = inet6_sk(sk); + struct ipv6_txoptions *opt_to_free = NULL; struct ipv6_txoptions *opt = NULL; struct ip6_flowlabel *flowlabel = NULL; struct dst_entry *dst = NULL; @@ -575,8 +576,10 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, opt = NULL; } - if (opt == NULL) - opt = np->opt; + if (!opt) { + opt = txopt_get(np); + opt_to_free = opt; + } if (flowlabel) opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); @@ -637,6 +640,7 @@ done: dst_release(dst); out: fl6_sock_release(flowlabel); + txopt_put(opt_to_free); return err < 0 ? err : len; From c198e4f44fd2ef64e3b28ed8e22c2b4db88e6c08 Mon Sep 17 00:00:00 2001 From: Dennis Cagle Date: Mon, 1 Aug 2016 11:48:04 -0700 Subject: [PATCH 46/48] adf: Zero out the mapping data The adf_device_post_nocopy function eventually calls the dma_buf_attach and dma_buf_map_attachment functions. If the dma_buf_attach function succeeds but the dma_buf_map_attachment function fails, both the adf_buffer_map function and the adf_device_post_nocopy function will call the dma_buf_detach function to tear down the same dma-buf attachment. b/28447556 Change-Id: I8eb40486496fe2a2ae5dfa1be4b76a4af0d6b827 Signed-off-by: Dennis Cagle --- drivers/video/adf/adf_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/adf/adf_client.c b/drivers/video/adf/adf_client.c index 8061d8e6b9fb..75b2f0b18522 100644 --- a/drivers/video/adf/adf_client.c +++ b/drivers/video/adf/adf_client.c @@ -305,8 +305,10 @@ static int adf_buffer_map(struct adf_device *dev, struct adf_buffer *buf, } done: - if (ret < 0) + if (ret < 0) { adf_buffer_mapping_cleanup(mapping, buf); + memset(mapping, 0, sizeof(*mapping)); + } return ret; } From 7baa7d8ca0b36ed798f856a7180cc0cb416594e5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 13 Feb 2016 02:34:52 +0000 Subject: [PATCH 47/48] pipe: Fix buffer offset after partially failed read Quoting the RHEL advisory: > It was found that the fix for CVE-2015-1805 incorrectly kept buffer > offset and buffer length in sync on a failed atomic read, potentially > resulting in a pipe buffer state corruption. A local, unprivileged user > could use this flaw to crash the system or leak kernel memory to user > space. (CVE-2016-0774, Moderate) The same flawed fix was applied to stable branches from 2.6.32.y to 3.14.y inclusive, and I was able to reproduce the issue on 3.2.y. We need to give pipe_iov_copy_to_user() a separate offset variable and only update the buffer offset if it succeeds. References: https://rhn.redhat.com/errata/RHSA-2016-0103.html cherry picked from commit feae3ca2e5e1a8f44aa6290255d3d9709985d0b2) Git-commit: feae3ca2e5e1a8f44aa6290255d3d9709985d0b2 Git-repo : https://android.googlesource.com/kernel/common change-Id: I988802f38acf40c7671fa0978880928b02d29b56 Signed-off-by: Srinivasa Rao Kuppala --- fs/pipe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/pipe.c b/fs/pipe.c index 3e7ab278bb0c..50267e6ba688 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -401,6 +401,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, void *addr; size_t chars = buf->len, remaining; int error, atomic; + int offset; if (chars > total_len) chars = total_len; @@ -414,9 +415,10 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, atomic = !iov_fault_in_pages_write(iov, chars); remaining = chars; + offset = buf->offset; redo: addr = ops->map(pipe, buf, atomic); - error = pipe_iov_copy_to_user(iov, addr, &buf->offset, + error = pipe_iov_copy_to_user(iov, addr, &offset, &remaining, atomic); ops->unmap(pipe, buf, addr); if (unlikely(error)) { @@ -432,6 +434,7 @@ redo: break; } ret += chars; + buf->offset += chars; buf->len -= chars; /* Was it a packet buffer? Clean up and exit */ From b73847a75055daf57295a8d32fd2c3f998d0b72a Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 25 Apr 2016 15:52:05 -0700 Subject: [PATCH 48/48] BACKPORT: f2fs: add a max block check for get_data_block_bmap (cherry pick from commit 179448bfe4cd201e98e728391c6b01b25c849fe8) This patch adds a max block check for get_data_block_bmap. Trinity test program will send a block number as parameter into ioctl_fibmap, which will be used in get_node_path(), when the block number large than f2fs max blocks, it will trigger kernel bug. Signed-off-by: Yunlei He Signed-off-by: Xue Liu [Jaegeuk Kim: fix missing condition, pointed by Chao Yu] Signed-off-by: Jaegeuk Kim Bug: 28271368 Change-Id: Ia5acae04522993d5b60a0bcb5ccc184c66532be8 Git-commit: 3c714201e02ec08652be4b9544a5267e79bde3a9 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Srinivasarao P --- fs/f2fs/data.c | 11 ++++++++++- fs/f2fs/f2fs.h | 1 + fs/f2fs/super.c | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 91ff93b0b0f4..96234982c26f 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -445,6 +445,15 @@ static int get_data_block_ro(struct inode *inode, sector_t iblock, return 0; } +static int get_data_block_bmap(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + /* Block number less than F2FS MAX BLOCKS */ + if (unlikely(iblock >= max_file_size(0))) + return -EFBIG; + return get_data_block_ro(inode, iblock, bh_result, create); +} + static int f2fs_read_data_page(struct file *file, struct page *page) { return mpage_readpage(page, get_data_block_ro); @@ -731,7 +740,7 @@ static int f2fs_set_data_page_dirty(struct page *page) static sector_t f2fs_bmap(struct address_space *mapping, sector_t block) { - return generic_block_bmap(mapping, block, get_data_block_ro); + return generic_block_bmap(mapping, block, get_data_block_bmap); } const struct address_space_operations f2fs_dblock_aops = { diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 20aab02f2a42..8aeea5dbce5a 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -928,6 +928,7 @@ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode) /* * super.c */ +loff_t max_file_size(unsigned bits); int f2fs_sync_fs(struct super_block *, int); extern __printf(3, 4) void f2fs_msg(struct super_block *, const char *, const char *, ...); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 03ab8b830940..9f3bbc577c6a 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -375,7 +375,7 @@ static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi, return 0; } -static loff_t max_file_size(unsigned bits) +loff_t max_file_size(unsigned bits) { loff_t result = ADDRS_PER_INODE; loff_t leaf_count = ADDRS_PER_BLOCK;