From 5d7e23a79444385d03717dc19cc58dd2d5883052 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 1 Mar 2016 17:14:22 -0800 Subject: ARM: dts: Add clocks for dm814x ADPLL These use the standard clock bindings and now we can make some of the fixed clocks into real clocks. Note that the clock output names may become optional as we probably want to eventually use descriptive names, or use just dynamically generated names as suggested by Tero. Acked-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dm814x-clocks.dtsi | 243 ++++++++++++++++++++++++++++++----- arch/arm/boot/dts/dra62x-clocks.dtsi | 26 ++++ 2 files changed, 238 insertions(+), 31 deletions(-) diff --git a/arch/arm/boot/dts/dm814x-clocks.dtsi b/arch/arm/boot/dts/dm814x-clocks.dtsi index 26001585673a..60e9b332fabb 100644 --- a/arch/arm/boot/dts/dm814x-clocks.dtsi +++ b/arch/arm/boot/dts/dm814x-clocks.dtsi @@ -4,6 +4,157 @@ * published by the Free Software Foundation. */ +&pllss { + /* + * See TRM "2.6.10 Connected outputso DPLLS" and + * "2.6.11 Connected Outputs of DPLLJ". Only clkout is + * connected except for hdmi and usb. + */ + adpll_mpu_ck: adpll@40 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-s-clock"; + reg = <0x40 0x40>; + clocks = <&devosc_ck &devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow", "clkinphif"; + clock-output-names = "481c5040.adpll.dcoclkldo", + "481c5040.adpll.clkout", + "481c5040.adpll.clkoutx2", + "481c5040.adpll.clkouthif"; + }; + + adpll_dsp_ck: adpll@80 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x80 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c5080.adpll.dcoclkldo", + "481c5080.adpll.clkout", + "481c5080.adpll.clkoutldo"; + }; + + adpll_sgx_ck: adpll@b0 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0xb0 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c50b0.adpll.dcoclkldo", + "481c50b0.adpll.clkout", + "481c50b0.adpll.clkoutldo"; + }; + + adpll_hdvic_ck: adpll@e0 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0xe0 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c50e0.adpll.dcoclkldo", + "481c50e0.adpll.clkout", + "481c50e0.adpll.clkoutldo"; + }; + + adpll_l3_ck: adpll@110 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x110 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c5110.adpll.dcoclkldo", + "481c5110.adpll.clkout", + "481c5110.adpll.clkoutldo"; + }; + + adpll_isp_ck: adpll@140 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x140 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c5140.adpll.dcoclkldo", + "481c5140.adpll.clkout", + "481c5140.adpll.clkoutldo"; + }; + + adpll_dss_ck: adpll@170 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x170 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c5170.adpll.dcoclkldo", + "481c5170.adpll.clkout", + "481c5170.adpll.clkoutldo"; + }; + + adpll_video0_ck: adpll@1a0 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x1a0 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c51a0.adpll.dcoclkldo", + "481c51a0.adpll.clkout", + "481c51a0.adpll.clkoutldo"; + }; + + adpll_video1_ck: adpll@1d0 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x1d0 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c51d0.adpll.dcoclkldo", + "481c51d0.adpll.clkout", + "481c51d0.adpll.clkoutldo"; + }; + + adpll_hdmi_ck: adpll@200 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x200 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c5200.adpll.dcoclkldo", + "481c5200.adpll.clkout", + "481c5200.adpll.clkoutldo"; + }; + + adpll_audio_ck: adpll@230 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x230 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c5230.adpll.dcoclkldo", + "481c5230.adpll.clkout", + "481c5230.adpll.clkoutldo"; + }; + + adpll_usb_ck: adpll@260 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x260 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c5260.adpll.dcoclkldo", + "481c5260.adpll.clkout", + "481c5260.adpll.clkoutldo"; + }; + + adpll_ddr_ck: adpll@290 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x290 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c5290.adpll.dcoclkldo", + "481c5290.adpll.clkout", + "481c5290.adpll.clkoutldo"; + }; +}; + &pllss_clocks { timer1_fck: timer1_fck { #clock-cells = <0>; @@ -23,6 +174,24 @@ reg = <0x2e0>; }; + /* CPTS_RFT_CLK in RMII_REFCLK_SRC, usually sourced from auiod */ + cpsw_cpts_rft_clk: cpsw_cpts_rft_clk { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&adpll_video0_ck 1 + &adpll_video1_ck 1 + &adpll_audio_ck 1>; + ti,bit-shift = <1>; + reg = <0x2e8>; + }; + + /* REVISIT: Set up with a proper mux using RMII_REFCLK_SRC */ + cpsw_125mhz_gclk: cpsw_125mhz_gclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <125000000>; + }; + sysclk18_ck: sysclk18_ck { #clock-cells = <0>; compatible = "ti,mux-clock"; @@ -79,37 +248,6 @@ compatible = "fixed-clock"; clock-frequency = <1000000000>; }; - - sysclk4_ck: sysclk4_ck { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <222000000>; - }; - - sysclk6_ck: sysclk6_ck { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <100000000>; - }; - - sysclk10_ck: sysclk10_ck { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <48000000>; - }; - - cpsw_125mhz_gclk: cpsw_125mhz_gclk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <125000000>; - }; - - cpsw_cpts_rft_clk: cpsw_cpts_rft_clk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <250000000>; - }; - }; &prcm_clocks { @@ -138,6 +276,49 @@ clock-div = <78125>; }; + /* L4_HS 220 MHz*/ + sysclk4_ck: sysclk4_ck { + #clock-cells = <0>; + compatible = "ti,fixed-factor-clock"; + clocks = <&adpll_l3_ck 1>; + ti,clock-mult = <1>; + ti,clock-div = <1>; + }; + + /* L4_FWCFG */ + sysclk5_ck: sysclk5_ck { + #clock-cells = <0>; + compatible = "ti,fixed-factor-clock"; + clocks = <&adpll_l3_ck 1>; + ti,clock-mult = <1>; + ti,clock-div = <2>; + }; + + /* L4_LS 110 MHz */ + sysclk6_ck: sysclk6_ck { + #clock-cells = <0>; + compatible = "ti,fixed-factor-clock"; + clocks = <&adpll_l3_ck 1>; + ti,clock-mult = <1>; + ti,clock-div = <2>; + }; + + sysclk8_ck: sysclk8_ck { + #clock-cells = <0>; + compatible = "ti,fixed-factor-clock"; + clocks = <&adpll_usb_ck 1>; + ti,clock-mult = <1>; + ti,clock-div = <1>; + }; + + sysclk10_ck: sysclk10_ck { + compatible = "ti,divider-clock"; + reg = <0x324>; + ti,max-div = <7>; + #clock-cells = <0>; + clocks = <&adpll_usb_ck 1>; + }; + aud_clkin0_ck: aud_clkin0_ck { #clock-cells = <0>; compatible = "fixed-clock"; diff --git a/arch/arm/boot/dts/dra62x-clocks.dtsi b/arch/arm/boot/dts/dra62x-clocks.dtsi index 6f98dc8df9dd..0e49741747ef 100644 --- a/arch/arm/boot/dts/dra62x-clocks.dtsi +++ b/arch/arm/boot/dts/dra62x-clocks.dtsi @@ -6,6 +6,32 @@ #include "dm814x-clocks.dtsi" +/* Compared to dm814x, dra62x does not have hdic, l3 or dss PLLs */ +&adpll_hdvic_ck { + status = "disabled"; +}; + +&adpll_l3_ck { + status = "disabled"; +}; + +&adpll_dss_ck { + status = "disabled"; +}; + +/* Compared to dm814x, dra62x has interconnect clocks on isp PLL */ +&sysclk4_ck { + clocks = <&adpll_isp_ck 1>; +}; + +&sysclk5_ck { + clocks = <&adpll_isp_ck 1>; +}; + +&sysclk6_ck { + clocks = <&adpll_isp_ck 1>; +}; + /* * Compared to dm814x, dra62x has different shifts and more mux options. * Please add the extra options for ysclk_14 and 16 if really needed. -- cgit v1.2.3 From ebf24414809200915b9ddf7f109bba7c278c8210 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 2 Mar 2016 07:29:29 -0800 Subject: ARM: OMAP2+: Use srst_udelay for USB on dm814x Without this booting t410 can fail randomly with no output depending on the .config options chosen. Enabling debug_ll causes the problem to go away. I narrowed this down to USB by disabling one module at a time. Acked-by: Paul Walmsley Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_81xx_data.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index f8cc40021729..743a2a2183a0 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -546,9 +546,11 @@ static struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__gpmc = { .user = OCP_USER_MPU, }; +/* USB needs udelay 1 after reset at least on hp t410, use 2 for margin */ static struct omap_hwmod_class_sysconfig dm81xx_usbhsotg_sysc = { .rev_offs = 0x0, .sysc_offs = 0x10, + .srst_udelay = 2, .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | SYSC_HAS_SOFTRESET, .idlemodes = SIDLE_SMART | MSTANDBY_FORCE | MSTANDBY_SMART, -- cgit v1.2.3 From dd5dc001581a7cf6f563e188c302caae1be998c2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 14 Mar 2016 15:49:54 +0100 Subject: ASoC: cs35l32: avoid uninitialized variable access gcc warns about the possibilty of accessing a property read from devicetree in cs35l32_i2c_probe() when it has not been initialized because CONFIG_OF is disabled: sound/soc/codecs/cs35l32.c: In function 'cs35l32_i2c_probe': sound/soc/codecs/cs35l32.c:278:2: warning: 'val' may be used uninitialized in this function [-Wmaybe-uninitialized] The code is actually correct because it checks the dev->of_node variable first and we know this is NULL here when CONFIG_OF is disabled, but Russell King noticed that it's broken when we probe the device using DT, and the properties are absent. The code already has some checking for incorrect values, and I keep that checking unchanged here, but add an additional check for an error returned by the property accessor functions that now gets handled the same way as incorrect data in the properties. Signed-off-by: Arnd Bergmann Acked-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l32.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index 44c30fe3e315..287d13740be4 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c @@ -274,7 +274,9 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, if (of_property_read_u32(np, "cirrus,sdout-share", &val) >= 0) pdata->sdout_share = val; - of_property_read_u32(np, "cirrus,boost-manager", &val); + if (of_property_read_u32(np, "cirrus,boost-manager", &val)) + val = -1u; + switch (val) { case CS35L32_BOOST_MGR_AUTO: case CS35L32_BOOST_MGR_AUTO_AUDIO: @@ -282,13 +284,15 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, case CS35L32_BOOST_MGR_FIXED: pdata->boost_mng = val; break; + case -1u: default: dev_err(&i2c_client->dev, "Wrong cirrus,boost-manager DT value %d\n", val); pdata->boost_mng = CS35L32_BOOST_MGR_BYPASS; } - of_property_read_u32(np, "cirrus,sdout-datacfg", &val); + if (of_property_read_u32(np, "cirrus,sdout-datacfg", &val)) + val = -1u; switch (val) { case CS35L32_DATA_CFG_LR_VP: case CS35L32_DATA_CFG_LR_STAT: @@ -296,13 +300,15 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, case CS35L32_DATA_CFG_LR_VPSTAT: pdata->sdout_datacfg = val; break; + case -1u: default: dev_err(&i2c_client->dev, "Wrong cirrus,sdout-datacfg DT value %d\n", val); pdata->sdout_datacfg = CS35L32_DATA_CFG_LR; } - of_property_read_u32(np, "cirrus,battery-threshold", &val); + if (of_property_read_u32(np, "cirrus,battery-threshold", &val)) + val = -1u; switch (val) { case CS35L32_BATT_THRESH_3_1V: case CS35L32_BATT_THRESH_3_2V: @@ -310,13 +316,15 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, case CS35L32_BATT_THRESH_3_4V: pdata->batt_thresh = val; break; + case -1u: default: dev_err(&i2c_client->dev, "Wrong cirrus,battery-threshold DT value %d\n", val); pdata->batt_thresh = CS35L32_BATT_THRESH_3_3V; } - of_property_read_u32(np, "cirrus,battery-recovery", &val); + if (of_property_read_u32(np, "cirrus,battery-recovery", &val)) + val = -1u; switch (val) { case CS35L32_BATT_RECOV_3_1V: case CS35L32_BATT_RECOV_3_2V: @@ -326,6 +334,7 @@ static int cs35l32_handle_of_data(struct i2c_client *i2c_client, case CS35L32_BATT_RECOV_3_6V: pdata->batt_recov = val; break; + case -1u: default: dev_err(&i2c_client->dev, "Wrong cirrus,battery-recovery DT value %d\n", val); -- cgit v1.2.3 From af139d5592bc812e7a1997727172ddba3e6be968 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 15 Mar 2016 22:42:50 +0100 Subject: ASoC: rt5616: add I2C dependency The rt5616 codec registers itself as an i2c driver, but can be enabled even when i2c is turned off, which leads to a build error: codecs/rt5616.c:1419:1: error: data definition has no type or storage class [-Werror] module_i2c_driver(rt5616_i2c_driver); This adds an explicit Kconfig dependency, like the other codec drivers. Signed-off-by: Arnd Bergmann Fixes: 288bc356a881 ("ASoC: rt5616: allow to build with CONFIG_SND_SOC_RT5616") Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 649e92a252ae..7ef3a0c16478 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -629,6 +629,7 @@ config SND_SOC_RT5514 config SND_SOC_RT5616 tristate "Realtek RT5616 CODEC" + depends on I2C config SND_SOC_RT5631 tristate "Realtek ALC5631/RT5631 CODEC" -- cgit v1.2.3 From 4a6c5e6a8d29e4d33858227db9179e91aa8a7407 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 15 Mar 2016 16:39:23 +0530 Subject: ALSA: hda: use list macro for parsing on cleanup It is always better to use list_for_each_entry_safe() while doing cleanup. So use this instead of open coding this in list in snd_hdac_stream_free_all() Signed-off-by: Jeeja KP Acked-by: Takashi Iwai Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/hda/ext/hdac_ext_stream.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c index 023cc4cad5c1..626f3bb24c55 100644 --- a/sound/hda/ext/hdac_ext_stream.c +++ b/sound/hda/ext/hdac_ext_stream.c @@ -104,12 +104,11 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init_all); */ void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus) { - struct hdac_stream *s; + struct hdac_stream *s, *_s; struct hdac_ext_stream *stream; struct hdac_bus *bus = ebus_to_hbus(ebus); - while (!list_empty(&bus->stream_list)) { - s = list_first_entry(&bus->stream_list, struct hdac_stream, list); + list_for_each_entry_safe(s, _s, &bus->stream_list, list) { stream = stream_to_hdac_ext_stream(s); snd_hdac_ext_stream_decouple(ebus, stream, false); list_del(&s->list); -- cgit v1.2.3 From 7373f481dc4098a844a756201e98341bc56baaa2 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 15 Mar 2016 16:39:24 +0530 Subject: ASoC: Intel: Skylake: free codec objects on removal On driver removal we should ask the core to remove the device objects as well, so invoke snd_hdac_ext_bus_device_remove() in remove. Signed-off-by: Jeeja KP Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index ab5e25aaeee3..292d51db9a22 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -725,6 +725,10 @@ static void skl_remove(struct pci_dev *pci) if (pci_dev_run_wake(pci)) pm_runtime_get_noresume(&pci->dev); pci_dev_put(pci); + + /* codec removal, invoke bus_device_remove */ + snd_hdac_ext_bus_device_remove(ebus); + skl_platform_unregister(&pci->dev); skl_free_dsp(skl); skl_machine_device_unregister(skl); -- cgit v1.2.3 From 3f7f8489e25b180cf8de8a3ae3896b3f18fc4aa5 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 15 Mar 2016 16:39:25 +0530 Subject: ASoC: Intel: Skylake: Freeup properly on skl_dsp_free We are supposed to freeup the Code loader DMA allocation and ensure all interrupts are disabled before we disable dsp cores. So invoke these to ensure DSP shuts down properly. Signed-off-by: Jeeja KP Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-sst-dsp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c index a5267e8a96e0..2962ef22fc84 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.c +++ b/sound/soc/intel/skylake/skl-sst-dsp.c @@ -336,6 +336,11 @@ void skl_dsp_free(struct sst_dsp *dsp) skl_ipc_int_disable(dsp); free_irq(dsp->irq, dsp); + dsp->cl_dev.ops.cl_cleanup_controller(dsp); + skl_cldma_int_disable(dsp); + skl_ipc_op_int_disable(dsp); + skl_ipc_int_disable(dsp); + skl_dsp_disable_core(dsp); } EXPORT_SYMBOL_GPL(skl_dsp_free); -- cgit v1.2.3 From 077411e5eb8872736fdc5f3e7277719160918dde Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 15 Mar 2016 16:39:26 +0530 Subject: ASoC: Intel: Skylake: Unmap the address last In Skylake destructor we unmap the hardware address and then free links and streams. The stream free accesses hardware to write to registers and predictably causes oops. So change the order and unmap last in destructor. Signed-off-by: Jeeja KP Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 292d51db9a22..6e916c3c3a4b 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -316,12 +316,13 @@ static int skl_free(struct hdac_ext_bus *ebus) if (bus->irq >= 0) free_irq(bus->irq, (void *)bus); - if (bus->remap_addr) - iounmap(bus->remap_addr); - snd_hdac_bus_free_stream_pages(bus); snd_hdac_stream_free_all(ebus); snd_hdac_link_free_all(ebus); + + if (bus->remap_addr) + iounmap(bus->remap_addr); + pci_release_regions(skl->pci); pci_disable_device(skl->pci); -- cgit v1.2.3 From 5b2fe89856b2d0faaaea9e4b4b2c4920de7a600c Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 15 Mar 2016 16:39:27 +0530 Subject: ASoC: Intel: Skylake: Call i915 exit last The Skylake driver uses i915 component APIs to talk to display. On remove we should free up by invoking snd_hdac_i915_exit() but that should be last thing in remove routine, so move it to last in skl_free() Signed-off-by: Jeeja KP Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 6e916c3c3a4b..72971dc55c52 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -328,6 +328,8 @@ static int skl_free(struct hdac_ext_bus *ebus) snd_hdac_ext_bus_exit(ebus); + if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) + snd_hdac_i915_exit(&ebus->bus); return 0; } @@ -720,9 +722,6 @@ static void skl_remove(struct pci_dev *pci) if (skl->tplg) release_firmware(skl->tplg); - if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) - snd_hdac_i915_exit(&ebus->bus); - if (pci_dev_run_wake(pci)) pm_runtime_get_noresume(&pci->dev); pci_dev_put(pci); -- cgit v1.2.3 From 36e7972c0d3f8819a5d9335c36c5dcd168cd2b72 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 16 Mar 2016 21:51:31 +0530 Subject: ASoC: Intel: Skylake: remove call to pci_dev_put The PCI bus takes pci_dev_get() and pci_dev_put() is also there. So no need for drivers to invoke these. In SKL driver we were calling pci_dev_put() only which is not right, so remove this Signed-off-by: Jeeja KP Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 72971dc55c52..07d9bc1cf3cb 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -724,7 +724,6 @@ static void skl_remove(struct pci_dev *pci) if (pci_dev_run_wake(pci)) pm_runtime_get_noresume(&pci->dev); - pci_dev_put(pci); /* codec removal, invoke bus_device_remove */ snd_hdac_ext_bus_device_remove(ebus); -- cgit v1.2.3 From 653aa4645244042826f105aab1be3d01b3d493ca Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Fri, 18 Mar 2016 14:54:22 +0800 Subject: ASoC: rt5640: Correct the digital interface data select this patch corrects the interface adc/dac control register definition according to datasheet. Signed-off-by: Sugar Zhang Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/rt5640.c | 2 +- sound/soc/codecs/rt5640.h | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index e8b5ba04417a..09e8988bbb2d 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -359,7 +359,7 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv, /* Interface data select */ static const char * const rt5640_data_select[] = { - "Normal", "left copy to right", "right copy to left", "Swap"}; + "Normal", "Swap", "left copy to right", "right copy to left"}; static SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA, RT5640_IF1_DAC_SEL_SFT, rt5640_data_select); diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index 1761c3a98b76..58b664b06c16 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -443,39 +443,39 @@ #define RT5640_IF1_DAC_SEL_MASK (0x3 << 14) #define RT5640_IF1_DAC_SEL_SFT 14 #define RT5640_IF1_DAC_SEL_NOR (0x0 << 14) -#define RT5640_IF1_DAC_SEL_L2R (0x1 << 14) -#define RT5640_IF1_DAC_SEL_R2L (0x2 << 14) -#define RT5640_IF1_DAC_SEL_SWAP (0x3 << 14) +#define RT5640_IF1_DAC_SEL_SWAP (0x1 << 14) +#define RT5640_IF1_DAC_SEL_L2R (0x2 << 14) +#define RT5640_IF1_DAC_SEL_R2L (0x3 << 14) #define RT5640_IF1_ADC_SEL_MASK (0x3 << 12) #define RT5640_IF1_ADC_SEL_SFT 12 #define RT5640_IF1_ADC_SEL_NOR (0x0 << 12) -#define RT5640_IF1_ADC_SEL_L2R (0x1 << 12) -#define RT5640_IF1_ADC_SEL_R2L (0x2 << 12) -#define RT5640_IF1_ADC_SEL_SWAP (0x3 << 12) +#define RT5640_IF1_ADC_SEL_SWAP (0x1 << 12) +#define RT5640_IF1_ADC_SEL_L2R (0x2 << 12) +#define RT5640_IF1_ADC_SEL_R2L (0x3 << 12) #define RT5640_IF2_DAC_SEL_MASK (0x3 << 10) #define RT5640_IF2_DAC_SEL_SFT 10 #define RT5640_IF2_DAC_SEL_NOR (0x0 << 10) -#define RT5640_IF2_DAC_SEL_L2R (0x1 << 10) -#define RT5640_IF2_DAC_SEL_R2L (0x2 << 10) -#define RT5640_IF2_DAC_SEL_SWAP (0x3 << 10) +#define RT5640_IF2_DAC_SEL_SWAP (0x1 << 10) +#define RT5640_IF2_DAC_SEL_L2R (0x2 << 10) +#define RT5640_IF2_DAC_SEL_R2L (0x3 << 10) #define RT5640_IF2_ADC_SEL_MASK (0x3 << 8) #define RT5640_IF2_ADC_SEL_SFT 8 #define RT5640_IF2_ADC_SEL_NOR (0x0 << 8) -#define RT5640_IF2_ADC_SEL_L2R (0x1 << 8) -#define RT5640_IF2_ADC_SEL_R2L (0x2 << 8) -#define RT5640_IF2_ADC_SEL_SWAP (0x3 << 8) +#define RT5640_IF2_ADC_SEL_SWAP (0x1 << 8) +#define RT5640_IF2_ADC_SEL_L2R (0x2 << 8) +#define RT5640_IF2_ADC_SEL_R2L (0x3 << 8) #define RT5640_IF3_DAC_SEL_MASK (0x3 << 6) #define RT5640_IF3_DAC_SEL_SFT 6 #define RT5640_IF3_DAC_SEL_NOR (0x0 << 6) -#define RT5640_IF3_DAC_SEL_L2R (0x1 << 6) -#define RT5640_IF3_DAC_SEL_R2L (0x2 << 6) -#define RT5640_IF3_DAC_SEL_SWAP (0x3 << 6) +#define RT5640_IF3_DAC_SEL_SWAP (0x1 << 6) +#define RT5640_IF3_DAC_SEL_L2R (0x2 << 6) +#define RT5640_IF3_DAC_SEL_R2L (0x3 << 6) #define RT5640_IF3_ADC_SEL_MASK (0x3 << 4) #define RT5640_IF3_ADC_SEL_SFT 4 #define RT5640_IF3_ADC_SEL_NOR (0x0 << 4) -#define RT5640_IF3_ADC_SEL_L2R (0x1 << 4) -#define RT5640_IF3_ADC_SEL_R2L (0x2 << 4) -#define RT5640_IF3_ADC_SEL_SWAP (0x3 << 4) +#define RT5640_IF3_ADC_SEL_SWAP (0x1 << 4) +#define RT5640_IF3_ADC_SEL_L2R (0x2 << 4) +#define RT5640_IF3_ADC_SEL_R2L (0x3 << 4) /* REC Left Mixer Control 1 (0x3b) */ #define RT5640_G_HP_L_RM_L_MASK (0x7 << 13) -- cgit v1.2.3 From 47325078f2a3e543150e7df967e45756b2fff7ec Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 18 Mar 2016 12:04:23 +0000 Subject: ASoC: dapm: Make sure we have a card when displaying component widgets The dummy component is reused for all cards so we special case and don't bind it to any of them. This means that code like that displaying the component widgets that tries to look at the card will crash. In the future we will fix this by ensuring that the dummy component looks like other components but that is invasive and so not suitable for a fix. Instead add a special case check here. Reported-by: Harry Pan Suggested-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/soc-dapm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 801ae1a81dfd..c4464858bf01 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2188,6 +2188,13 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt, int count = 0; char *state = "not set"; + /* card won't be set for the dummy component, as a spot fix + * we're checking for that case specifically here but in future + * we will ensure that the dummy component looks like others. + */ + if (!cmpnt->card) + return 0; + list_for_each_entry(w, &cmpnt->card->widgets, list) { if (w->dapm != dapm) continue; -- cgit v1.2.3 From c3efb42b207e22991dee86ca15861ede11a419fc Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 18 Mar 2016 20:10:23 +0530 Subject: ASoC: Intel: Skylake: Fix kbuild dependency The Skylake driver selects SND_HDA_I915 which causes kbuild to spew warning: warning: (SND_SOC_INTEL_SKYLAKE) selects SND_HDA_I915 which has unmet direct dependencies (SOUND && !M68K && !UML && SND && DRM_I915 && SND_HDA_CORE) The SND_HDA_I915 should not be selected so drop that. Reported-by: Takashi Iwai Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index b3e6c2300457..1120f4f4d011 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -163,7 +163,6 @@ config SND_SOC_INTEL_SKYLAKE tristate select SND_HDA_EXT_CORE select SND_SOC_TOPOLOGY - select SND_HDA_I915 select SND_SOC_INTEL_SST config SND_SOC_INTEL_SKL_RT286_MACH -- cgit v1.2.3 From d30596737e8e7b2f1235d7ba20592b8309e3af04 Mon Sep 17 00:00:00 2001 From: Cyan Ogilvie Date: Wed, 16 Mar 2016 18:59:41 +0200 Subject: HID: wiimote: Fix wiimote mp scale linearization The wiimote motion plus gyros use two scales to report fast and slow rotation - below 440 deg/s uses 8192/440 units / deg/s, and above uses 8192/2000 units / deg/s. Previously this driver attempted to linearize the two by scaling the fast rate by 18 and the slow by 9, but this results in a scale of 8192*9/440 = ~167.564 for slow and 8192*18/2000 = 73.728 for fast. Correct the fast motion scale factor so that both report ~167.564 units / deg/s Signed-off-by: Cyan Ogilvie Reviewed-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/hid-wiimote-modules.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index 4390eee2ce84..c830ed39348f 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c @@ -2049,9 +2049,11 @@ static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext) * -----+------------------------------+-----+-----+ * The single bits Yaw, Roll, Pitch in the lower right corner specify * whether the wiimote is rotating fast (0) or slow (1). Speed for slow - * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a - * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast - * and 9 for slow. + * roation is 8192/440 units / deg/s and for fast rotation 8192/2000 + * units / deg/s. To get a linear scale for fast rotation we multiply + * by 2000/440 = ~4.5454 and scale both fast and slow by 9 to match the + * previous scale reported by this driver. + * This leaves a linear scale with 8192*9/440 (~167.564) units / deg/s. * If the wiimote is not rotating the sensor reports 2^13 = 8192. * Ext specifies whether an extension is connected to the motionp. * which is parsed by wiimote-core. @@ -2070,15 +2072,15 @@ static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext) z -= 8192; if (!(ext[3] & 0x02)) - x *= 18; + x = (x * 2000 * 9) / 440; else x *= 9; if (!(ext[4] & 0x02)) - y *= 18; + y = (y * 2000 * 9) / 440; else y *= 9; if (!(ext[3] & 0x01)) - z *= 18; + z = (z * 2000 * 9) / 440; else z *= 9; -- cgit v1.2.3 From 9fc515bc9e735c10cd327f05c20f5ef69474188d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 10 Mar 2016 13:07:17 +0200 Subject: iwlwifi: pcie: lower the debug level for RSA semaphore access IWL_INFO is not an error but still printed by default. "can't access the RSA semaphore it is write protected" seems worrisome but it is not really a problem. CC: [4.1+] Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index eb39c7e09781..b2b79354d5c0 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -732,8 +732,8 @@ static int iwl_pcie_rsa_race_bug_wa(struct iwl_trans *trans) */ val = iwl_read_prph(trans, PREG_AUX_BUS_WPROT_0); if (val & (BIT(1) | BIT(17))) { - IWL_INFO(trans, - "can't access the RSA semaphore it is write protected\n"); + IWL_DEBUG_INFO(trans, + "can't access the RSA semaphore it is write protected\n"); return 0; } -- cgit v1.2.3 From 7fdf9663261cc77a516396fec82cee8a8ea07e76 Mon Sep 17 00:00:00 2001 From: Matti Gottlieb Date: Tue, 15 Mar 2016 13:46:47 +0200 Subject: iwlwifi: mvm: fix memory leak in paging Currently paging download buffer is freed during the the unloading of the opmode which happens when the driver is unloaded. This causes a memory leak since the paging download buffer is allocated every time we enable the interface, so the download buffer can be allocated many times, but only be freed once. Free paging download buffer during disabling of the interface. CC: stable@vger.kernel.org [4.3+] Signed-off-by: Matti Gottlieb Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 ++ drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 76e649c680a1..a50f4df7eae7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1147,6 +1147,8 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) /* the fw is stopped, the aux sta is dead: clean up driver state */ iwl_mvm_del_aux_sta(mvm); + iwl_free_fw_paging(mvm); + /* * Clear IN_HW_RESTART flag when stopping the hw (as restart_complete() * won't be called in this case). diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 5e8ab796d5bc..d278399097dc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -761,8 +761,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) for (i = 0; i < NVM_MAX_NUM_SECTIONS; i++) kfree(mvm->nvm_sections[i].data); - iwl_free_fw_paging(mvm); - iwl_mvm_tof_clean(mvm); ieee80211_free_hw(mvm->hw); -- cgit v1.2.3 From 372f7d6ac11235a69b2cb356cdc8bf67bd68f4c4 Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Fri, 11 Mar 2016 22:44:37 +0530 Subject: b43: Fix memory leaks in b43_bus_dev_ssb_init and b43_bus_dev_bcma_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The memory allocated by kzalloc in b43_bus_dev_ssb_init and b43_bus_dev_bcma_init is not freed. This patch fixes the bug by adding kfree in b43_ssb_remove, b43_bcma_remove and error handling code of b43_bcma_probe. Thanks Michael for his suggestion. Signed-off-by: Jia-Ju Bai Acked-by: Michael Büsch Signed-off-by: Sudip Mukherjee Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/b43/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c index 72380af9dc52..b0603e796ad8 100644 --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c @@ -5680,11 +5680,12 @@ static int b43_bcma_probe(struct bcma_device *core) INIT_WORK(&wl->firmware_load, b43_request_firmware); schedule_work(&wl->firmware_load); -bcma_out: return err; bcma_err_wireless_exit: ieee80211_free_hw(wl->hw); +bcma_out: + kfree(dev); return err; } @@ -5712,8 +5713,8 @@ static void b43_bcma_remove(struct bcma_device *core) b43_rng_exit(wl); b43_leds_unregister(wl); - ieee80211_free_hw(wl->hw); + kfree(wldev->dev); } static struct bcma_driver b43_bcma_driver = { @@ -5796,6 +5797,7 @@ static void b43_ssb_remove(struct ssb_device *sdev) b43_leds_unregister(wl); b43_wireless_exit(dev, wl); + kfree(dev); } static struct ssb_driver b43_ssb_driver = { -- cgit v1.2.3 From c58d900cc96a5106e2feaed8d3d7361669a91396 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 17 Mar 2016 10:20:20 +0100 Subject: bcma: fix building without OF_IRQ The bcma driver core can be built with or without DT support, but it fails to build when CONFIG_OF=y and CONFIG_OF_IRQ=n, which can happen on platforms that do not support IRQ domains. ERROR: "irq_create_of_mapping" [drivers/bcma/bcma.ko] undefined! ERROR: "of_irq_parse_raw" [drivers/bcma/bcma.ko] undefined! ERROR: "of_irq_parse_one" [drivers/bcma/bcma.ko] undefined! This adds another compile-time check for OF_IRQ, but also gets rid of now unneeded #ifdef checks: Using the simpler IS_ENABLED() check for OF_IRQ also covers the case of not having CONFIG_OF enabled. The check for CONFIG_OF_ADDRESS was added to allow building on architectures without OF_ADDRESS, but that has been addressed already in b1d06b60e90c ("of: Provide static inline function for of_translate_address if needed"). Signed-off-by: Arnd Bergmann Signed-off-by: Kalle Valo --- drivers/bcma/main.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 786be8fed39e..1f635471f318 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -136,7 +136,6 @@ static bool bcma_is_core_needed_early(u16 core_id) return false; } -#if defined(CONFIG_OF) && defined(CONFIG_OF_ADDRESS) static struct device_node *bcma_of_find_child_device(struct platform_device *parent, struct bcma_device *core) { @@ -184,7 +183,7 @@ static unsigned int bcma_of_get_irq(struct platform_device *parent, struct of_phandle_args out_irq; int ret; - if (!parent || !parent->dev.of_node) + if (!IS_ENABLED(CONFIG_OF_IRQ) || !parent || !parent->dev.of_node) return 0; ret = bcma_of_irq_parse(parent, core, &out_irq, num); @@ -202,23 +201,15 @@ static void bcma_of_fill_device(struct platform_device *parent, { struct device_node *node; + if (!IS_ENABLED(CONFIG_OF_IRQ)) + return; + node = bcma_of_find_child_device(parent, core); if (node) core->dev.of_node = node; core->irq = bcma_of_get_irq(parent, core, 0); } -#else -static void bcma_of_fill_device(struct platform_device *parent, - struct bcma_device *core) -{ -} -static inline unsigned int bcma_of_get_irq(struct platform_device *parent, - struct bcma_device *core, int num) -{ - return 0; -} -#endif /* CONFIG_OF */ unsigned int bcma_core_irq(struct bcma_device *core, int num) { -- cgit v1.2.3 From 2acd846485549655582ee379ceb966206f91e6f8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 17 Mar 2016 11:03:50 +0100 Subject: rtlwifi: fix gcc-6 indentation warning The rtl8821ae_dm_txpower_tracking_callback_thermalmeter function contains a call to RT_TRACE() that is indented in a misleading way, as pointed out by a gcc-6 warning: drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c: In function 'rtl8821ae_dm_txpower_tracking_callback_thermalmeter': drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c:2491:4: error: statement is indented as if it were guarded by... RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ^~~~~~~~ drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c:2488:3: note: ...this 'for' clause, but it is not for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) ^~~ It is clear from the context that the call was not meant to be part of the loop and only the indentation is wrong, so this removes the extra tabs. Signed-off-by: Arnd Bergmann Acked-by: Larry Finger Signed-off-by: Kalle Valo --- drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c index 95dcbff4673b..6a8245c4ea48 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c @@ -2488,9 +2488,9 @@ void rtl8821ae_dm_txpower_tracking_callback_thermalmeter( for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) rtldm->swing_idx_ofdm_base[p] = rtldm->swing_idx_ofdm[p]; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n", - rtldm->thermalvalue, thermal_value); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n", + rtldm->thermalvalue, thermal_value); /*Record last Power Tracking Thermal Value*/ rtldm->thermalvalue = thermal_value; } -- cgit v1.2.3 From 972e6a993f278b416a8ee3ec65475724fc36feb2 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 23 Mar 2016 12:17:09 -0400 Subject: HID: usbhid: fix inconsistent reset/resume/reset-resume behavior The usbhid driver has inconsistently duplicated code in its post-reset, resume, and reset-resume pathways. reset-resume doesn't check HID_STARTED before trying to restart the I/O queues. resume fails to clear the HID_SUSPENDED flag if HID_STARTED isn't set. resume calls usbhid_restart_queues() with usbhid->lock held and the others call it without holding the lock. The first item in particular causes a problem following a reset-resume if the driver hasn't started up its I/O. URB submission fails because usbhid->urbin is NULL, and this triggers an unending reset-retry loop. This patch fixes the problem by creating a new subroutine, hid_restart_io(), to carry out all the common activities. It also adds some checks that were missing in the original code: After a reset, there's no need to clear any halted endpoints. After a resume, if a reset is pending there's no need to restart any I/O until the reset is finished. After a resume, if the interrupt-IN endpoint is halted there's no need to submit the input URB until the halt has been cleared. Signed-off-by: Alan Stern Reported-by: Daniel Fraga Tested-by: Daniel Fraga CC: Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 73 ++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index ad71160b9ea4..ae83af649a60 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -951,14 +951,6 @@ static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count) return ret; } -static void usbhid_restart_queues(struct usbhid_device *usbhid) -{ - if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)) - usbhid_restart_out_queue(usbhid); - if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl)) - usbhid_restart_ctrl_queue(usbhid); -} - static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) { struct usbhid_device *usbhid = hid->driver_data; @@ -1404,6 +1396,37 @@ static void hid_cease_io(struct usbhid_device *usbhid) usb_kill_urb(usbhid->urbout); } +static void hid_restart_io(struct hid_device *hid) +{ + struct usbhid_device *usbhid = hid->driver_data; + int clear_halt = test_bit(HID_CLEAR_HALT, &usbhid->iofl); + int reset_pending = test_bit(HID_RESET_PENDING, &usbhid->iofl); + + spin_lock_irq(&usbhid->lock); + clear_bit(HID_SUSPENDED, &usbhid->iofl); + usbhid_mark_busy(usbhid); + + if (clear_halt || reset_pending) + schedule_work(&usbhid->reset_work); + usbhid->retry_delay = 0; + spin_unlock_irq(&usbhid->lock); + + if (reset_pending || !test_bit(HID_STARTED, &usbhid->iofl)) + return; + + if (!clear_halt) { + if (hid_start_in(hid) < 0) + hid_io_error(hid); + } + + spin_lock_irq(&usbhid->lock); + if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)) + usbhid_restart_out_queue(usbhid); + if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl)) + usbhid_restart_ctrl_queue(usbhid); + spin_unlock_irq(&usbhid->lock); +} + /* Treat USB reset pretty much the same as suspend/resume */ static int hid_pre_reset(struct usb_interface *intf) { @@ -1453,14 +1476,14 @@ static int hid_post_reset(struct usb_interface *intf) return 1; } + /* No need to do another reset or clear a halted endpoint */ spin_lock_irq(&usbhid->lock); clear_bit(HID_RESET_PENDING, &usbhid->iofl); + clear_bit(HID_CLEAR_HALT, &usbhid->iofl); spin_unlock_irq(&usbhid->lock); hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); - status = hid_start_in(hid); - if (status < 0) - hid_io_error(hid); - usbhid_restart_queues(usbhid); + + hid_restart_io(hid); return 0; } @@ -1483,25 +1506,9 @@ void usbhid_put_power(struct hid_device *hid) #ifdef CONFIG_PM static int hid_resume_common(struct hid_device *hid, bool driver_suspended) { - struct usbhid_device *usbhid = hid->driver_data; - int status; - - spin_lock_irq(&usbhid->lock); - clear_bit(HID_SUSPENDED, &usbhid->iofl); - usbhid_mark_busy(usbhid); - - if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) || - test_bit(HID_RESET_PENDING, &usbhid->iofl)) - schedule_work(&usbhid->reset_work); - usbhid->retry_delay = 0; - - usbhid_restart_queues(usbhid); - spin_unlock_irq(&usbhid->lock); - - status = hid_start_in(hid); - if (status < 0) - hid_io_error(hid); + int status = 0; + hid_restart_io(hid); if (driver_suspended && hid->driver && hid->driver->resume) status = hid->driver->resume(hid); return status; @@ -1570,12 +1577,8 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message) static int hid_resume(struct usb_interface *intf) { struct hid_device *hid = usb_get_intfdata (intf); - struct usbhid_device *usbhid = hid->driver_data; int status; - if (!test_bit(HID_STARTED, &usbhid->iofl)) - return 0; - status = hid_resume_common(hid, true); dev_dbg(&intf->dev, "resume status %d\n", status); return 0; @@ -1584,10 +1587,8 @@ static int hid_resume(struct usb_interface *intf) static int hid_reset_resume(struct usb_interface *intf) { struct hid_device *hid = usb_get_intfdata(intf); - struct usbhid_device *usbhid = hid->driver_data; int status; - clear_bit(HID_SUSPENDED, &usbhid->iofl); status = hid_post_reset(intf); if (status >= 0 && hid->driver && hid->driver->reset_resume) { int ret = hid->driver->reset_resume(hid); -- cgit v1.2.3 From 3ca4a238106dedc285193ee47f494a6584b6fd2f Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Sat, 26 Mar 2016 23:08:55 -0600 Subject: ARM: OMAP2+: hwmod: Fix updating of sysconfig register Commit 127500ccb766f ("ARM: OMAP2+: Only write the sysconfig on idle when necessary") talks about verification of sysconfig cache value before updating it, only during idle path. But the patch is adding the verification in the enable path. So, adding the check in a proper place as per the commit description. Not keeping this check during enable path as there is a chance of losing context and it is safe to do on idle as the context of the register will never be lost while the device is active. Signed-off-by: Lokesh Vutla Acked-by: Tero Kristo Cc: Jon Hunter Cc: # 3.12+ Fixes: commit 127500ccb766 "ARM: OMAP2+: Only write the sysconfig on idle when necessary" [paul@pwsan.com: appears to have been caused by my own mismerge of the originally posted patch] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index b6d62e4cdfdd..2af6ff63e3b4 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1416,9 +1416,7 @@ static void _enable_sysc(struct omap_hwmod *oh) (sf & SYSC_HAS_CLOCKACTIVITY)) _set_clockactivity(oh, oh->class->sysc->clockact, &v); - /* If the cached value is the same as the new value, skip the write */ - if (oh->_sysc_cache != v) - _write_sysconfig(v, oh); + _write_sysconfig(v, oh); /* * Set the autoidle bit only after setting the smartidle bit @@ -1481,7 +1479,9 @@ static void _idle_sysc(struct omap_hwmod *oh) _set_master_standbymode(oh, idlemode, &v); } - _write_sysconfig(v, oh); + /* If the cached value is the same as the new value, skip the write */ + if (oh->_sysc_cache != v) + _write_sysconfig(v, oh); } /** -- cgit v1.2.3 From dcf5341f0150bc4c5bf37786e1198d2ff8fc2c38 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 9 Mar 2016 20:38:59 +0100 Subject: ARM: dts: sun8i-q8-common: Do not set constraints on dc1sw regulator dc1sw is an on/off only regulator and as such it cannot have constraints. This is a limitation of the kernel regulator implementation which resolves supplies on the first regulator_get(), which is done after applying constraints, and applying the constrains will fail because it calls _regulator_get_voltage() and _regulator_do_set_voltage() both of which will fail on a switch regulator when there is no supply (yet). This causes registering of all axp22x regulators to fail with the following errors: [ 1.395249] vcc-lcd: failed to get the current voltage(-22) [ 1.405131] axp20x-regulator axp20x-regulator: Failed to register dc1sw [ 1.412436] axp20x-regulator: probe of axp20x-regulator failed with error -22 This commit removes the constrains on dc1sw / vcc-lcd fixing this problem note that dcdc1 itself is contrained to the exact same values, so this does not change anything. Signed-off-by: Hans de Goede Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-q8-common.dtsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/boot/dts/sun8i-q8-common.dtsi b/arch/arm/boot/dts/sun8i-q8-common.dtsi index 9d2b7e2f5975..346a49d805a7 100644 --- a/arch/arm/boot/dts/sun8i-q8-common.dtsi +++ b/arch/arm/boot/dts/sun8i-q8-common.dtsi @@ -125,8 +125,6 @@ }; ®_dc1sw { - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; regulator-name = "vcc-lcd"; }; -- cgit v1.2.3 From d643678b9a4e432a574b2ec601216afd720c69b6 Mon Sep 17 00:00:00 2001 From: Jeeja KP Date: Mon, 28 Mar 2016 22:11:30 +0530 Subject: ASoC: Intel: Skylake: Fix for unloading module only when it is loaded Module needs to be unloaded only when it is loaded successfully. To fix this, first correct the module state sequence and set module state to LOADED if module is loaded successfully. When unloading the module check if module state is not in UNINIT, then unload it. Signed-off-by: Jeeja KP Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-topology.c | 5 ++++- sound/soc/intel/skylake/skl-topology.h | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 545b4e77b8aa..3f393cbe1bfe 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -490,6 +490,8 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) mconfig->id.module_id, mconfig->guid); if (ret < 0) return ret; + + mconfig->m_state = SKL_MODULE_LOADED; } /* update blob if blob is null for be with default value */ @@ -524,7 +526,8 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, list_for_each_entry(w_module, &pipe->w_list, node) { mconfig = w_module->w->priv; - if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod) + if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && + mconfig->m_state > SKL_MODULE_UNINIT) return ctx->dsp->fw_ops.unload_mod(ctx->dsp, mconfig->id.module_id); } diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index de3c401284d9..d2d923002d5c 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -274,10 +274,10 @@ struct skl_pipe { enum skl_module_state { SKL_MODULE_UNINIT = 0, - SKL_MODULE_INIT_DONE = 1, - SKL_MODULE_LOADED = 2, - SKL_MODULE_UNLOADED = 3, - SKL_MODULE_BIND_DONE = 4 + SKL_MODULE_LOADED = 1, + SKL_MODULE_INIT_DONE = 2, + SKL_MODULE_BIND_DONE = 3, + SKL_MODULE_UNLOADED = 4, }; struct skl_module_cfg { -- cgit v1.2.3 From 4f329d9fbab630af44db2f787eb79ca52e6ba22e Mon Sep 17 00:00:00 2001 From: Jeeja KP Date: Mon, 28 Mar 2016 22:11:31 +0530 Subject: ASoC: Intel: Skylake: Fix DSP resource de-allocation In PRE PMD of widget handler DSP resources are allocated after the creation of DSP pipe and modules and in POST PMD DSP resources are destroyed. If there is any failure in pipe or module creation in PRE PMD, pcm trigger fails and finally POST PMD gets called and DSP resources are freed, without getting allocated. Fixes the DSP resource de-allocation by allocating the resource before creation of pipe and module in PRE PMD and in POST PMD, free the resources. Signed-off-by: Jeeja KP Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-topology.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 3f393cbe1bfe..5a85f3a4699b 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -485,6 +485,8 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) if (!skl_is_pipe_mcps_avail(skl, mconfig)) return -ENOMEM; + skl_tplg_alloc_pipe_mcps(skl, mconfig); + if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) { ret = ctx->dsp->fw_ops.load_mod(ctx->dsp, mconfig->id.module_id, mconfig->guid); @@ -511,7 +513,6 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) ret = skl_tplg_set_module_params(w, ctx); if (ret < 0) return ret; - skl_tplg_alloc_pipe_mcps(skl, mconfig); } return 0; @@ -561,6 +562,9 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, if (!skl_is_pipe_mem_avail(skl, mconfig)) return -ENOMEM; + skl_tplg_alloc_pipe_mem(skl, mconfig); + skl_tplg_alloc_pipe_mcps(skl, mconfig); + /* * Create a list of modules for pipe. * This list contains modules from source to sink @@ -604,9 +608,6 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, src_module = dst_module; } - skl_tplg_alloc_pipe_mem(skl, mconfig); - skl_tplg_alloc_pipe_mcps(skl, mconfig); - return 0; } -- cgit v1.2.3 From e6cee90075c0ff261ff7eef8ad892429f028e194 Mon Sep 17 00:00:00 2001 From: Ben Zhang Date: Fri, 25 Mar 2016 16:10:39 -0700 Subject: ASoC: nau8825: Fix jack detection across suspend Jack plug status is rechecked at resume to handle plug/unplug in S3 when the chip has no power. Suspend/resume callbacks are moved from the i2c dev_pm_ops to snd_soc_codec_driver. soc_resume_deferred is a delayed work which may trigger nau8825_set_bias_level. The bias change races against dev_pm_ops, causing jack detection issues. soc_resume_deferred ensures bias change and snd_soc_codec_driver suspend/resume are sequenced correctly. Signed-off-by: Ben Zhang Signed-off-by: Mark Brown --- sound/soc/codecs/nau8825.c | 126 +++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 55 deletions(-) diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 1c8729984c2b..683769f0f246 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -343,9 +343,12 @@ static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("ADC Power", NAU8825_REG_ANALOG_ADC_2, 6, 0, NULL, 0), - /* ADC for button press detection */ - SND_SOC_DAPM_ADC("SAR", NULL, NAU8825_REG_SAR_CTRL, - NAU8825_SAR_ADC_EN_SFT, 0), + /* ADC for button press detection. A dapm supply widget is used to + * prevent dapm_power_widgets keeping the codec at SND_SOC_BIAS_ON + * during suspend. + */ + SND_SOC_DAPM_SUPPLY("SAR", NAU8825_REG_SAR_CTRL, + NAU8825_SAR_ADC_EN_SFT, 0, NULL, 0), SND_SOC_DAPM_PGA_S("ADACL", 2, NAU8825_REG_RDAC, 12, 0, NULL, 0), SND_SOC_DAPM_PGA_S("ADACR", 2, NAU8825_REG_RDAC, 13, 0, NULL, 0), @@ -607,6 +610,16 @@ static bool nau8825_is_jack_inserted(struct regmap *regmap) static void nau8825_restart_jack_detection(struct regmap *regmap) { + /* Chip needs one FSCLK cycle in order to generate interrupts, + * as we cannot guarantee one will be provided by the system. Turning + * master mode on then off enables us to generate that FSCLK cycle + * with a minimum of contention on the clock bus. + */ + regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2, + NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_MASTER); + regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2, + NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_SLAVE); + /* this will restart the entire jack detection process including MIC/GND * switching and create interrupts. We have to go from 0 to 1 and back * to 0 to restart. @@ -728,7 +741,10 @@ static irqreturn_t nau8825_interrupt(int irq, void *data) struct regmap *regmap = nau8825->regmap; int active_irq, clear_irq = 0, event = 0, event_mask = 0; - regmap_read(regmap, NAU8825_REG_IRQ_STATUS, &active_irq); + if (regmap_read(regmap, NAU8825_REG_IRQ_STATUS, &active_irq)) { + dev_err(nau8825->dev, "failed to read irq status\n"); + return IRQ_NONE; + } if ((active_irq & NAU8825_JACK_EJECTION_IRQ_MASK) == NAU8825_JACK_EJECTION_DETECTED) { @@ -1141,33 +1157,74 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec, return ret; } } - - ret = regcache_sync(nau8825->regmap); - if (ret) { - dev_err(codec->dev, - "Failed to sync cache: %d\n", ret); - return ret; - } } - break; case SND_SOC_BIAS_OFF: if (nau8825->mclk_freq) clk_disable_unprepare(nau8825->mclk); - - regcache_mark_dirty(nau8825->regmap); break; } return 0; } +#ifdef CONFIG_PM +static int nau8825_suspend(struct snd_soc_codec *codec) +{ + struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); + + disable_irq(nau8825->irq); + regcache_cache_only(nau8825->regmap, true); + regcache_mark_dirty(nau8825->regmap); + + return 0; +} + +static int nau8825_resume(struct snd_soc_codec *codec) +{ + struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); + + /* The chip may lose power and reset in S3. regcache_sync restores + * register values including configurations for sysclk, irq, and + * jack/button detection. + */ + regcache_cache_only(nau8825->regmap, false); + regcache_sync(nau8825->regmap); + + /* Check the jack plug status directly. If the headset is unplugged + * during S3 when the chip has no power, there will be no jack + * detection irq even after the nau8825_restart_jack_detection below, + * because the chip just thinks no headset has ever been plugged in. + */ + if (!nau8825_is_jack_inserted(nau8825->regmap)) { + nau8825_eject_jack(nau8825); + snd_soc_jack_report(nau8825->jack, 0, SND_JACK_HEADSET); + } + + enable_irq(nau8825->irq); + + /* Run jack detection to check the type (OMTP or CTIA) of the headset + * if there is one. This handles the case where a different type of + * headset is plugged in during S3. This triggers an IRQ iff a headset + * is already plugged in. + */ + nau8825_restart_jack_detection(nau8825->regmap); + + return 0; +} +#else +#define nau8825_suspend NULL +#define nau8825_resume NULL +#endif + static struct snd_soc_codec_driver nau8825_codec_driver = { .probe = nau8825_codec_probe, .set_sysclk = nau8825_set_sysclk, .set_pll = nau8825_set_pll, .set_bias_level = nau8825_set_bias_level, .suspend_bias_off = true, + .suspend = nau8825_suspend, + .resume = nau8825_resume, .controls = nau8825_controls, .num_controls = ARRAY_SIZE(nau8825_controls), @@ -1277,16 +1334,6 @@ static int nau8825_setup_irq(struct nau8825 *nau8825) regmap_update_bits(regmap, NAU8825_REG_ENA_CTRL, NAU8825_ENABLE_DACR, NAU8825_ENABLE_DACR); - /* Chip needs one FSCLK cycle in order to generate interrupts, - * as we cannot guarantee one will be provided by the system. Turning - * master mode on then off enables us to generate that FSCLK cycle - * with a minimum of contention on the clock bus. - */ - regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2, - NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_MASTER); - regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2, - NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_SLAVE); - ret = devm_request_threaded_irq(nau8825->dev, nau8825->irq, NULL, nau8825_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "nau8825", nau8825); @@ -1354,36 +1401,6 @@ static int nau8825_i2c_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int nau8825_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct nau8825 *nau8825 = dev_get_drvdata(dev); - - disable_irq(client->irq); - regcache_cache_only(nau8825->regmap, true); - regcache_mark_dirty(nau8825->regmap); - - return 0; -} - -static int nau8825_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct nau8825 *nau8825 = dev_get_drvdata(dev); - - regcache_cache_only(nau8825->regmap, false); - regcache_sync(nau8825->regmap); - enable_irq(client->irq); - - return 0; -} -#endif - -static const struct dev_pm_ops nau8825_pm = { - SET_SYSTEM_SLEEP_PM_OPS(nau8825_suspend, nau8825_resume) -}; - static const struct i2c_device_id nau8825_i2c_ids[] = { { "nau8825", 0 }, { } @@ -1410,7 +1427,6 @@ static struct i2c_driver nau8825_driver = { .name = "nau8825", .of_match_table = of_match_ptr(nau8825_of_ids), .acpi_match_table = ACPI_PTR(nau8825_acpi_match), - .pm = &nau8825_pm, }, .probe = nau8825_i2c_probe, .remove = nau8825_i2c_remove, -- cgit v1.2.3 From 45aa56cd0ffc2ebc2274f1bacc985b6f032c0120 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Mon, 21 Mar 2016 16:08:42 +0800 Subject: intel-hid: add a workaround to ignore an event after waking up from S4. This is the same as the original workaround from S3 but for S4. Without this workaround, a rfkill event will be received and it will toggle wireless devices when radio hotkey is not pressed. Signed-off-by: Alex Hung Signed-off-by: Darren Hart --- drivers/platform/x86/intel-hid.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c index f93abc8c1424..a818db6aa08f 100644 --- a/drivers/platform/x86/intel-hid.c +++ b/drivers/platform/x86/intel-hid.c @@ -91,6 +91,8 @@ static int intel_hid_pl_resume_handler(struct device *device) } static const struct dev_pm_ops intel_hid_pl_pm_ops = { + .freeze = intel_hid_pl_suspend_handler, + .restore = intel_hid_pl_resume_handler, .suspend = intel_hid_pl_suspend_handler, .resume = intel_hid_pl_resume_handler, }; -- cgit v1.2.3 From 00c9329ebe2d19a13afd86ba75218f868f2788ba Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 15 Feb 2016 11:11:06 -0300 Subject: rtc: s3c: Document in binding that only s3c6410 needs a src clk The S3C binding doc says that the RTC and RTC source clocks are required but the S3C driver supports different HW IP and only the s3c6410 needs a source clock. Fix the binding explaining that the source clock is only needed for the s3c6410-rtc compatible controller. Reported-by: Krzysztof Kozlowski Signed-off-by: Javier Martinez Canillas Acked-by: Alexandre Belloni Reviewed-by: Krzysztof Kozlowski Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/s3c-rtc.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/rtc/s3c-rtc.txt b/Documentation/devicetree/bindings/rtc/s3c-rtc.txt index 1068ffce9f91..fdde63a5419c 100644 --- a/Documentation/devicetree/bindings/rtc/s3c-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/s3c-rtc.txt @@ -15,9 +15,10 @@ Required properties: is the rtc tick interrupt. The number of cells representing a interrupt depends on the parent interrupt controller. - clocks: Must contain a list of phandle and clock specifier for the rtc - and source clocks. -- clock-names: Must contain "rtc" and "rtc_src" entries sorted in the - same order as the clocks property. + clock and in the case of a s3c6410 compatible controller, also + a source clock. +- clock-names: Must contain "rtc" and for a s3c6410 compatible controller, + a "rtc_src" sorted in the same order as the clocks property. Example: -- cgit v1.2.3 From 591b1d8d86074ac3a3163d89bcfe7b232cf83902 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Mon, 14 Dec 2015 11:06:34 -0800 Subject: x86/mm/pkeys: Add missing Documentation Stefan Richter noticed that the X86_INTEL_MEMORY_PROTECTION_KEYS option in arch/x86/Kconfig references Documentation/x86/protection-keys.txt, but the file does not exist. This is a patch merging mishap: the final (v8) version of the pkeys series did not include the documentation patch 32 and v7 included. Add it now. Reported-by: Stefan Richter Signed-off-by: Dave Hansen Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Hansen Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/20151214190634.426BEE41@viggo.jf.intel.com [ Added changelog. ] Signed-off-by: Ingo Molnar Signed-off-by: Ingo Molnar --- Documentation/x86/protection-keys.txt | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Documentation/x86/protection-keys.txt diff --git a/Documentation/x86/protection-keys.txt b/Documentation/x86/protection-keys.txt new file mode 100644 index 000000000000..c281ded1ba16 --- /dev/null +++ b/Documentation/x86/protection-keys.txt @@ -0,0 +1,27 @@ +Memory Protection Keys for Userspace (PKU aka PKEYs) is a CPU feature +which will be found on future Intel CPUs. + +Memory Protection Keys provides a mechanism for enforcing page-based +protections, but without requiring modification of the page tables +when an application changes protection domains. It works by +dedicating 4 previously ignored bits in each page table entry to a +"protection key", giving 16 possible keys. + +There is also a new user-accessible register (PKRU) with two separate +bits (Access Disable and Write Disable) for each key. Being a CPU +register, PKRU is inherently thread-local, potentially giving each +thread a different set of protections from every other thread. + +There are two new instructions (RDPKRU/WRPKRU) for reading and writing +to the new register. The feature is only available in 64-bit mode, +even though there is theoretically space in the PAE PTEs. These +permissions are enforced on data access only and have no effect on +instruction fetches. + +=========================== Config Option =========================== + +This config option adds approximately 1.5kb of text. and 50 bytes of +data to the executable. A workload which does large O_DIRECT reads +of holes in XFS files was run to exercise get_user_pages_fast(). No +performance delta was observed with the config option +enabled or disabled. -- cgit v1.2.3 From 6d92bc9d483aa1751755a66fee8fb39dffb088c0 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 16 Mar 2016 20:04:35 -0700 Subject: x86/build: Build compressed x86 kernels as PIE The 32-bit x86 assembler in binutils 2.26 will generate R_386_GOT32X relocation to get the symbol address in PIC. When the compressed x86 kernel isn't built as PIC, the linker optimizes R_386_GOT32X relocations to their fixed symbol addresses. However, when the compressed x86 kernel is loaded at a different address, it leads to the following load failure: Failed to allocate space for phdrs during the decompression stage. If the compressed x86 kernel is relocatable at run-time, it should be compiled with -fPIE, instead of -fPIC, if possible and should be built as Position Independent Executable (PIE) so that linker won't optimize R_386_GOT32X relocation to its fixed symbol address. Older linkers generate R_386_32 relocations against locally defined symbols, _bss, _ebss, _got and _egot, in PIE. It isn't wrong, just less optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle R_386_32 relocations when relocating the kernel. To generate R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as hidden in both 32-bit and 64-bit x86 kernels. To build a 64-bit compressed x86 kernel as PIE, we need to disable the relocation overflow check to avoid relocation overflow errors. We do this with a new linker command-line option, -z noreloc-overflow, which got added recently: commit 4c10bbaa0912742322f10d9d5bb630ba4e15dfa7 Author: H.J. Lu Date: Tue Mar 15 11:07:06 2016 -0700 Add -z noreloc-overflow option to x86-64 ld Add -z noreloc-overflow command-line option to the x86-64 ELF linker to disable relocation overflow check. This can be used to avoid relocation overflow check if there will be no dynamic relocation overflow at run-time. The 64-bit compressed x86 kernel is built as PIE only if the linker supports -z noreloc-overflow. So far 64-bit relocatable compressed x86 kernel boots fine even when it is built as a normal executable. Signed-off-by: H.J. Lu Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org [ Edited the changelog and comments. ] Signed-off-by: Ingo Molnar --- arch/x86/boot/compressed/Makefile | 14 +++++++++++++- arch/x86/boot/compressed/head_32.S | 28 ++++++++++++++++++++++++++++ arch/x86/boot/compressed/head_64.S | 8 ++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 6915ff2bd996..8774cb23064f 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -26,7 +26,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 -KBUILD_CFLAGS += -fno-strict-aliasing -fPIC +KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC) KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING cflags-$(CONFIG_X86_32) := -march=i386 cflags-$(CONFIG_X86_64) := -mcmodel=small @@ -40,6 +40,18 @@ GCOV_PROFILE := n UBSAN_SANITIZE :=n LDFLAGS := -m elf_$(UTS_MACHINE) +ifeq ($(CONFIG_RELOCATABLE),y) +# If kernel is relocatable, build compressed kernel as PIE. +ifeq ($(CONFIG_X86_32),y) +LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker) +else +# To build 64-bit compressed kernel as PIE, we disable relocation +# overflow check to avoid relocation overflow error with a new linker +# command-line option, -z noreloc-overflow. +LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \ + && echo "-z noreloc-overflow -pie --no-dynamic-linker") +endif +endif LDFLAGS_vmlinux := -T hostprogs-y := mkpiggy diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 8ef964ddc18e..0256064da8da 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -31,6 +31,34 @@ #include #include +/* + * The 32-bit x86 assembler in binutils 2.26 will generate R_386_GOT32X + * relocation to get the symbol address in PIC. When the compressed x86 + * kernel isn't built as PIC, the linker optimizes R_386_GOT32X + * relocations to their fixed symbol addresses. However, when the + * compressed x86 kernel is loaded at a different address, it leads + * to the following load failure: + * + * Failed to allocate space for phdrs + * + * during the decompression stage. + * + * If the compressed x86 kernel is relocatable at run-time, it should be + * compiled with -fPIE, instead of -fPIC, if possible and should be built as + * Position Independent Executable (PIE) so that linker won't optimize + * R_386_GOT32X relocation to its fixed symbol address. Older + * linkers generate R_386_32 relocations against locally defined symbols, + * _bss, _ebss, _got and _egot, in PIE. It isn't wrong, just less + * optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle + * R_386_32 relocations when relocating the kernel. To generate + * R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as + * hidden: + */ + .hidden _bss + .hidden _ebss + .hidden _got + .hidden _egot + __HEAD ENTRY(startup_32) #ifdef CONFIG_EFI_STUB diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index b0c0d16ef58d..86558a199139 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -33,6 +33,14 @@ #include #include +/* + * Locally defined symbols should be marked hidden: + */ + .hidden _bss + .hidden _ebss + .hidden _got + .hidden _egot + __HEAD .code32 ENTRY(startup_32) -- cgit v1.2.3 From ea36ae09105b7688225c02d33f1f3213299360f6 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Mon, 28 Mar 2016 09:22:14 -0400 Subject: HID: lenovo: Don't use stack variables for DMA buffers The lenovo_send_cmd_cptkbd function uses a stack variable to submit commands via hid_hw_raw_request. Eventually this gets to the usb_hcd_map_urb_for_dma function, which causes a warning to be thrown if the CONFIG_DMA_API_DEBUG option is enabled. Fix this by allocating a temporary buffer instead. [jkosina@suse.cz: no need to NULL-initialize buf, spotted by Benjamin] Reported-by: lejeczek Signed-off-by: Josh Boyer Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-lenovo.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 0125e356bd8d..1ac4ff4d57a6 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -184,21 +184,31 @@ static int lenovo_send_cmd_cptkbd(struct hid_device *hdev, unsigned char byte2, unsigned char byte3) { int ret; - unsigned char buf[] = {0x18, byte2, byte3}; + unsigned char *buf; + + buf = kzalloc(3, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf[0] = 0x18; + buf[1] = byte2; + buf[2] = byte3; switch (hdev->product) { case USB_DEVICE_ID_LENOVO_CUSBKBD: - ret = hid_hw_raw_request(hdev, 0x13, buf, sizeof(buf), + ret = hid_hw_raw_request(hdev, 0x13, buf, 3, HID_FEATURE_REPORT, HID_REQ_SET_REPORT); break; case USB_DEVICE_ID_LENOVO_CBTKBD: - ret = hid_hw_output_report(hdev, buf, sizeof(buf)); + ret = hid_hw_output_report(hdev, buf, 3); break; default: ret = -EINVAL; break; } + kfree(buf); + return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */ } -- cgit v1.2.3 From 580549ef6b3e3fb3b958de490ca99f43a089a2cf Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 25 Mar 2016 15:26:55 +0100 Subject: HID: wacom: fix Bamboo ONE oops Looks like recent changes in the Wacom driver made the Bamboo ONE crashes. The tablet behaves as if it was a regular Bamboo device with pen, touch and pad, but there is no physical pad connected to it. The weird part is that the pad is still sending events and given that there is no input node connected to it, we get anull pointer exception. Link: https://bugzilla.redhat.com/show_bug.cgi?id=1317116 Signed-off-by: Benjamin Tissoires Acked-by: Ping Cheng Cc: stable@vger.kernel.org Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bd198bbd4df0..02c4efea241c 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2425,6 +2425,17 @@ void wacom_setup_device_quirks(struct wacom *wacom) } } + /* + * Hack for the Bamboo One: + * the device presents a PAD/Touch interface as most Bamboos and even + * sends ghosts PAD data on it. However, later, we must disable this + * ghost interface, and we can not detect it unless we set it here + * to WACOM_DEVICETYPE_PAD or WACOM_DEVICETYPE_TOUCH. + */ + if (features->type == BAMBOO_PEN && + features->pktlen == WACOM_PKGLEN_BBTOUCH3) + features->device_type |= WACOM_DEVICETYPE_PAD; + /* * Raw Wacom-mode pen and touch events both come from interface * 0, whose HID descriptor has an application usage of 0xFF0D -- cgit v1.2.3 From 33362c69c8e68281633a7c3a1d5c840e940097b7 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 28 Mar 2016 10:47:34 +0100 Subject: ASoC: wm8962: Correct typo when setting DSPCLK rate The variable dspclk holds the rate of the DSPCLK, but the variable sysclk holds an identifier for the clock. Currently if read a non-sensical value from the DSPCLK_DIV register we assign sysclk to dspclk, clearly this was intended to be sysclk_rate. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8962.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 88223608a33f..720a14e0687d 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2471,7 +2471,7 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec) break; default: dev_warn(codec->dev, "Unknown DSPCLK divisor read back\n"); - dspclk = wm8962->sysclk; + dspclk = wm8962->sysclk_rate; } dev_dbg(codec->dev, "DSPCLK is %dHz, BCLK %d\n", dspclk, wm8962->bclk); -- cgit v1.2.3 From 4c35430ad18f5a034302cb90e559ede5a27f93b9 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Wed, 9 Mar 2016 00:46:11 +0100 Subject: ARM: pxa: fix the number of DMA requestor lines The number of requestor lines was clamped to 0 for all pxa architectures in the requestor declaration. Fix this by using the value. Fixes: 72b195cb7162 ("ARM: pxa: add the number of DMA requestor lines") Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/devices.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 913a319c7b00..fffb697bbf0e 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -1235,5 +1235,6 @@ static struct platform_device pxa2xx_pxa_dma = { void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors) { pxa_dma_pdata.dma_channels = nb_channels; + pxa_dma_pdata.nb_requestors = nb_requestors; pxa_register_device(&pxa2xx_pxa_dma, &pxa_dma_pdata); } -- cgit v1.2.3 From ef21b32a60fbfdf2370465e52036c1c5ed1f6b43 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 27 Mar 2016 16:57:23 +0000 Subject: sh: fix smp-shx3 build regression from removal of arch localtimer The removal was not complete and left behind one reference to a removed function in smp-shx3.c. For completeness, also remove declarations for functions that were removed. Fixes: 45624ac38926 "sh: remove arch-specific localtimer and use generic one" Reported-by: Geert Uytterhoeven Signed-off-by: Rich Felker --- arch/sh/include/asm/smp.h | 5 ----- arch/sh/kernel/cpu/sh4a/smp-shx3.c | 2 -- 2 files changed, 7 deletions(-) diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h index 1baf0ba96242..c9f8bbdb1bf8 100644 --- a/arch/sh/include/asm/smp.h +++ b/arch/sh/include/asm/smp.h @@ -34,11 +34,6 @@ enum { DECLARE_PER_CPU(int, cpu_state); void smp_message_recv(unsigned int msg); -void smp_timer_broadcast(const struct cpumask *mask); - -void local_timer_interrupt(void); -void local_timer_setup(unsigned int cpu); -void local_timer_stop(unsigned int cpu); void arch_send_call_function_single_ipi(int cpu); void arch_send_call_function_ipi_mask(const struct cpumask *mask); diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c index 4a298808789c..839612c8a0a0 100644 --- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c @@ -73,8 +73,6 @@ static void shx3_prepare_cpus(unsigned int max_cpus) { int i; - local_timer_setup(0); - BUILD_BUG_ON(SMP_MSG_NR >= 8); for (i = 0; i < SMP_MSG_NR; i++) -- cgit v1.2.3 From 427b1d3faa448212337c599e5454325af64e9a8e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 21 Mar 2016 09:50:37 +0100 Subject: ARM: u8500_defconfig: turn on the Synaptics RMI4 driver The Ux500 boards may have an RMI4 unit, and the DT fragments for them have been merged upstream. Add it to the defconfig. Signed-off-by: Linus Walleij Signed-off-by: Arnd Bergmann --- arch/arm/configs/u8500_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 07055eacbb0f..a691d590fbd1 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -63,6 +63,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_BU21013=y CONFIG_INPUT_MISC=y CONFIG_INPUT_AB8500_PONKEY=y +CONFIG_RMI4_CORE=y +CONFIG_RMI4_I2C=y +CONFIG_RMI4_F11=y # CONFIG_SERIO is not set CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_LEGACY_PTYS is not set -- cgit v1.2.3 From e6cc3be552f9fedf5fa6b37c285d7d27ffc08b03 Mon Sep 17 00:00:00 2001 From: Jayachandran C Date: Sun, 28 Feb 2016 13:07:17 +0530 Subject: arm64: dts: vulcan: Update PCI ranges The PCI memory windows available in vulcan.dtsi are limited to 128MB for 32-bit BARs, and 4GB for 64-bit BARs. Given the memory mapped IO space available in arm64, these windows can be increased substantially to support more use cases. The change increases the 32-bit window to 256MB and the 64-bit window to 128 GB. The firmware on vulcan boards will use these ranges as well. PCI IO windows are not supported on Vulcan, so remove them instead of keeping an unused value. Signed-off-by: Jayachandran C Signed-off-by: Florian Fainelli Signed-off-by: Arnd Bergmann --- arch/arm64/boot/dts/broadcom/vulcan.dtsi | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/broadcom/vulcan.dtsi b/arch/arm64/boot/dts/broadcom/vulcan.dtsi index c49b5a85809c..85820e2bca9d 100644 --- a/arch/arm64/boot/dts/broadcom/vulcan.dtsi +++ b/arch/arm64/boot/dts/broadcom/vulcan.dtsi @@ -108,12 +108,15 @@ reg = <0x0 0x30000000 0x0 0x10000000>; reg-names = "PCI ECAM"; - /* IO 0x4000_0000 - 0x4001_0000 */ - ranges = <0x01000000 0 0x40000000 0 0x40000000 0 0x00010000 - /* MEM 0x4800_0000 - 0x5000_0000 */ - 0x02000000 0 0x48000000 0 0x48000000 0 0x08000000 - /* MEM64 pref 0x6_0000_0000 - 0x7_0000_0000 */ - 0x43000000 6 0x00000000 6 0x00000000 1 0x00000000>; + /* + * PCI ranges: + * IO no supported + * MEM 0x4000_0000 - 0x6000_0000 + * MEM64 pref 0x40_0000_0000 - 0x60_0000_0000 + */ + ranges = + <0x02000000 0 0x40000000 0 0x40000000 0 0x20000000 + 0x43000000 0x40 0x00000000 0x40 0x00000000 0x20 0x00000000>; interrupt-map-mask = <0 0 0 7>; interrupt-map = /* addr pin ic icaddr icintr */ -- cgit v1.2.3 From ccc7d5a1cdae78ccd623540dc87e281135a1c053 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 29 Mar 2016 22:50:02 +0000 Subject: sh: fix function signature of cpu_coregroup_mask to match pointer type The signedness mismatch of the argument type produces an error compiling kernel/sched/core.c with -Werror=incompatible-pointer-types, which is now used by default. Fixes: ea8daa7b9784 "kbuild: Add option to turn incompatible pointer check into error" Signed-off-by: Rich Felker --- arch/sh/include/asm/topology.h | 2 +- arch/sh/kernel/topology.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h index b0a282d65f6a..358e3f516ef6 100644 --- a/arch/sh/include/asm/topology.h +++ b/arch/sh/include/asm/topology.h @@ -17,7 +17,7 @@ #define mc_capable() (1) -const struct cpumask *cpu_coregroup_mask(unsigned int cpu); +const struct cpumask *cpu_coregroup_mask(int cpu); extern cpumask_t cpu_core_map[NR_CPUS]; diff --git a/arch/sh/kernel/topology.c b/arch/sh/kernel/topology.c index 772caffba22f..c82912a61d74 100644 --- a/arch/sh/kernel/topology.c +++ b/arch/sh/kernel/topology.c @@ -21,7 +21,7 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); cpumask_t cpu_core_map[NR_CPUS]; EXPORT_SYMBOL(cpu_core_map); -static cpumask_t cpu_coregroup_map(unsigned int cpu) +static cpumask_t cpu_coregroup_map(int cpu) { /* * Presently all SH-X3 SMP cores are multi-cores, so just keep it @@ -30,7 +30,7 @@ static cpumask_t cpu_coregroup_map(unsigned int cpu) return *cpu_possible_mask; } -const struct cpumask *cpu_coregroup_mask(unsigned int cpu) +const struct cpumask *cpu_coregroup_mask(int cpu) { return &cpu_core_map[cpu]; } -- cgit v1.2.3 From d0c31e02005764dae0aab130a57e9794d06b824d Mon Sep 17 00:00:00 2001 From: Babu Moger Date: Thu, 24 Mar 2016 13:02:22 -0700 Subject: sparc/PCI: Fix for panic while enabling SR-IOV We noticed this panic while enabling SR-IOV in sparc. mlx4_core: Mellanox ConnectX core driver v2.2-1 (Jan 1 2015) mlx4_core: Initializing 0007:01:00.0 mlx4_core 0007:01:00.0: Enabling SR-IOV with 5 VFs mlx4_core: Initializing 0007:01:00.1 Unable to handle kernel NULL pointer dereference insmod(10010): Oops [#1] CPU: 391 PID: 10010 Comm: insmod Not tainted 4.1.12-32.el6uek.kdump2.sparc64 #1 TPC: I7: <__mlx4_init_one+0x324/0x500 [mlx4_core]> Call Trace: [00000000104c5ea4] __mlx4_init_one+0x324/0x500 [mlx4_core] [00000000104c613c] mlx4_init_one+0xbc/0x120 [mlx4_core] [0000000000725f14] local_pci_probe+0x34/0xa0 [0000000000726028] pci_call_probe+0xa8/0xe0 [0000000000726310] pci_device_probe+0x50/0x80 [000000000079f700] really_probe+0x140/0x420 [000000000079fa24] driver_probe_device+0x44/0xa0 [000000000079fb5c] __device_attach+0x3c/0x60 [000000000079d85c] bus_for_each_drv+0x5c/0xa0 [000000000079f588] device_attach+0x88/0xc0 [000000000071acd0] pci_bus_add_device+0x30/0x80 [0000000000736090] virtfn_add.clone.1+0x210/0x360 [00000000007364a4] sriov_enable+0x2c4/0x520 [000000000073672c] pci_enable_sriov+0x2c/0x40 [00000000104c2d58] mlx4_enable_sriov+0xf8/0x180 [mlx4_core] [00000000104c49ac] mlx4_load_one+0x42c/0xd40 [mlx4_core] Disabling lock debugging due to kernel taint Caller[00000000104c5ea4]: __mlx4_init_one+0x324/0x500 [mlx4_core] Caller[00000000104c613c]: mlx4_init_one+0xbc/0x120 [mlx4_core] Caller[0000000000725f14]: local_pci_probe+0x34/0xa0 Caller[0000000000726028]: pci_call_probe+0xa8/0xe0 Caller[0000000000726310]: pci_device_probe+0x50/0x80 Caller[000000000079f700]: really_probe+0x140/0x420 Caller[000000000079fa24]: driver_probe_device+0x44/0xa0 Caller[000000000079fb5c]: __device_attach+0x3c/0x60 Caller[000000000079d85c]: bus_for_each_drv+0x5c/0xa0 Caller[000000000079f588]: device_attach+0x88/0xc0 Caller[000000000071acd0]: pci_bus_add_device+0x30/0x80 Caller[0000000000736090]: virtfn_add.clone.1+0x210/0x360 Caller[00000000007364a4]: sriov_enable+0x2c4/0x520 Caller[000000000073672c]: pci_enable_sriov+0x2c/0x40 Caller[00000000104c2d58]: mlx4_enable_sriov+0xf8/0x180 [mlx4_core] Caller[00000000104c49ac]: mlx4_load_one+0x42c/0xd40 [mlx4_core] Caller[00000000104c5f90]: __mlx4_init_one+0x410/0x500 [mlx4_core] Caller[00000000104c613c]: mlx4_init_one+0xbc/0x120 [mlx4_core] Caller[0000000000725f14]: local_pci_probe+0x34/0xa0 Caller[0000000000726028]: pci_call_probe+0xa8/0xe0 Caller[0000000000726310]: pci_device_probe+0x50/0x80 Caller[000000000079f700]: really_probe+0x140/0x420 Caller[000000000079fa24]: driver_probe_device+0x44/0xa0 Caller[000000000079fb08]: __driver_attach+0x88/0xa0 Caller[000000000079d90c]: bus_for_each_dev+0x6c/0xa0 Caller[000000000079f29c]: driver_attach+0x1c/0x40 Caller[000000000079e35c]: bus_add_driver+0x17c/0x220 Caller[00000000007a02d4]: driver_register+0x74/0x120 Caller[00000000007263fc]: __pci_register_driver+0x3c/0x60 Caller[00000000104f62bc]: mlx4_init+0x60/0xcc [mlx4_core] Kernel panic - not syncing: Fatal exception Press Stop-A (L1-A) to return to the boot prom ---[ end Kernel panic - not syncing: Fatal exception Details: Here is the call sequence virtfn_add->__mlx4_init_one->dma_set_mask->dma_supported The panic happened at line 760(file arch/sparc/kernel/iommu.c) 758 int dma_supported(struct device *dev, u64 device_mask) 759 { 760 struct iommu *iommu = dev->archdata.iommu; 761 u64 dma_addr_mask = iommu->dma_addr_mask; 762 763 if (device_mask >= (1UL << 32UL)) 764 return 0; 765 766 if ((device_mask & dma_addr_mask) == dma_addr_mask) 767 return 1; 768 769 #ifdef CONFIG_PCI 770 if (dev_is_pci(dev)) 771 return pci64_dma_supported(to_pci_dev(dev), device_mask); 772 #endif 773 774 return 0; 775 } 776 EXPORT_SYMBOL(dma_supported); Same panic happened with Intel ixgbe driver also. SR-IOV code looks for arch specific data while enabling VFs. When VF device is added, driver probe function makes set of calls to initialize the pci device. Because the VF device is added different way than the normal PF device(which happens via of_create_pci_dev for sparc), some of the arch specific initialization does not happen for VF device. That causes panic when archdata is accessed. To fix this, I have used already defined weak function pcibios_setup_device to copy archdata from PF to VF. Also verified the fix. Signed-off-by: Babu Moger Signed-off-by: Sowmini Varadhan Reviewed-by: Ethan Zhao Signed-off-by: David S. Miller --- arch/sparc/kernel/pci.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index badf0951d73c..9f9614df9e1e 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -994,6 +994,23 @@ void pcibios_set_master(struct pci_dev *dev) /* No special bus mastering setup handling */ } +#ifdef CONFIG_PCI_IOV +int pcibios_add_device(struct pci_dev *dev) +{ + struct pci_dev *pdev; + + /* Add sriov arch specific initialization here. + * Copy dev_archdata from PF to VF + */ + if (dev->is_virtfn) { + pdev = dev->physfn; + memcpy(&dev->dev.archdata, &pdev->dev.archdata, + sizeof(struct dev_archdata)); + } + return 0; +} +#endif /* CONFIG_PCI_IOV */ + static int __init pcibios_init(void) { pci_dfl_cache_line_size = 64 >> 2; -- cgit v1.2.3 From b30a337ca27c4f40439e4bfb290cba5f88d73bb7 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 30 Mar 2016 08:46:31 +0800 Subject: block: partition: initialize percpuref before sending out KOBJ_ADD The initialization of partition's percpu_ref should have been done before sending out KOBJ_ADD uevent, which may cause userspace to read partition table. So the uninitialized percpu_ref may be accessed in data path. This patch fixes this issue reported by Naveen. Reported-by: Naveen Kaje Tested-by: Naveen Kaje Fixes: 6c71013ecb7e2(block: partition: convert percpu ref) Cc: # v4.3+ Signed-off-by: Ming Lei Signed-off-by: Jens Axboe --- block/partition-generic.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/block/partition-generic.c b/block/partition-generic.c index 5d8701941054..84c53f04777a 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c @@ -361,15 +361,20 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, goto out_del; } + err = hd_ref_init(p); + if (err) { + if (flags & ADDPART_FLAG_WHOLEDISK) + goto out_remove_file; + goto out_del; + } + /* everything is up and running, commence */ rcu_assign_pointer(ptbl->part[partno], p); /* suppress uevent if the disk suppresses it */ if (!dev_get_uevent_suppress(ddev)) kobject_uevent(&pdev->kobj, KOBJ_ADD); - - if (!hd_ref_init(p)) - return p; + return p; out_free_info: free_part_info(p); @@ -378,6 +383,8 @@ out_free_stats: out_free: kfree(p); return ERR_PTR(err); +out_remove_file: + device_remove_file(pdev, &dev_attr_whole_disk); out_del: kobject_put(p->holder_dir); device_del(pdev); -- cgit v1.2.3 From 5ec712934ce1ff6e33bf3878034a91ca9bd600c9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 29 Mar 2016 18:39:26 -0700 Subject: sparc: Write up preadv2/pwritev2 syscalls. Signed-off-by: David S. Miller --- arch/sparc/include/uapi/asm/unistd.h | 4 +++- arch/sparc/kernel/systbls_32.S | 2 +- arch/sparc/kernel/systbls_64.S | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index b6de8b10a55b..36eee8132c22 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h @@ -423,8 +423,10 @@ #define __NR_setsockopt 355 #define __NR_mlock2 356 #define __NR_copy_file_range 357 +#define __NR_preadv2 358 +#define __NR_pwritev2 359 -#define NR_syscalls 358 +#define NR_syscalls 360 /* Bitmask values returned from kern_features system call. */ #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 6c3dd6c52f8b..eac7f0db5c8c 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -88,4 +88,4 @@ sys_call_table: /*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr /*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf /*350*/ .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen -/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range +/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2 diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 12b524cfcfa0..b0f17ff2ddba 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -89,7 +89,7 @@ sys_call_table32: /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf /*350*/ .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen - .word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range + .word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range, compat_sys_preadv2, compat_sys_pwritev2 #endif /* CONFIG_COMPAT */ @@ -170,4 +170,4 @@ sys_call_table: /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf /*350*/ .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen - .word sys_setsockopt, sys_mlock2, sys_copy_file_range + .word sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2 -- cgit v1.2.3 From 77644ad86abd205742937010fa1cf4795e927212 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 15 Mar 2016 11:03:39 +0100 Subject: bus: mvebu-mbus: use %pa to print phys_addr_t A recent change to the mbus driver added a warning printk that prints a phys_addr_t using the %x format string, which fails in case we build with 64-bit phys_addr_t: drivers/bus/mvebu-mbus.c: In function 'mvebu_mbus_get_dram_win_info': drivers/bus/mvebu-mbus.c:975:9: error: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'phys_addr_t {aka long long unsigned int}' [-Werror=format=] This uses the special %pa format string instead, so we always print the correct type. Signed-off-by: Arnd Bergmann Fixes: f2900acea801 ("bus: mvebu-mbus: provide api for obtaining IO and DRAM window information") Signed-off-by: Gregory CLEMENT --- drivers/bus/mvebu-mbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index c2e52864bb03..ce54a0160faa 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -972,7 +972,7 @@ int mvebu_mbus_get_dram_win_info(phys_addr_t phyaddr, u8 *target, u8 *attr) } } - pr_err("invalid dram address 0x%x\n", phyaddr); + pr_err("invalid dram address %pa\n", &phyaddr); return -EINVAL; } EXPORT_SYMBOL_GPL(mvebu_mbus_get_dram_win_info); -- cgit v1.2.3 From 199831c77c50e6913e893b6bc268ba9f4a9a2bf8 Mon Sep 17 00:00:00 2001 From: Patrick Uiterwijk Date: Tue, 29 Mar 2016 16:57:40 +0000 Subject: ARM: mvebu: Correct unit address for linksys The USB2 port for Armada 38x is defined to be at 58000, not at 50000. Cc: Fixes: 2d0a7addbd10 ("ARM: Kirkwood: Add support for many Synology NAS devices") Signed-off-by: Patrick Uiterwijk Acked-by: Imre Kaloz Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-385-linksys.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/armada-385-linksys.dtsi b/arch/arm/boot/dts/armada-385-linksys.dtsi index 3710755c6d76..85d2c377c332 100644 --- a/arch/arm/boot/dts/armada-385-linksys.dtsi +++ b/arch/arm/boot/dts/armada-385-linksys.dtsi @@ -117,7 +117,7 @@ }; /* USB part of the eSATA/USB 2.0 port */ - usb@50000 { + usb@58000 { status = "okay"; }; -- cgit v1.2.3 From b60e1157d8faa7a44556fcda2d4f06e71e839fd3 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Wed, 23 Mar 2016 10:13:59 +0100 Subject: ARM: dts: amlogic: Split pinctrl device for Meson8 / Meson8b MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Carlo Caione Reviewed-by: Andreas Färber Tested-by: Kevin Hilman --- arch/arm/boot/dts/meson8.dtsi | 57 ++++++++++++++++++++++++------------------ arch/arm/boot/dts/meson8b.dtsi | 12 +++++++-- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi index a2ddcb8c545a..45619f6162c5 100644 --- a/arch/arm/boot/dts/meson8.dtsi +++ b/arch/arm/boot/dts/meson8.dtsi @@ -91,8 +91,8 @@ clock-frequency = <141666666>; }; - pinctrl: pinctrl@c1109880 { - compatible = "amlogic,meson8-pinctrl"; + pinctrl_cbus: pinctrl@c1109880 { + compatible = "amlogic,meson8-cbus-pinctrl"; reg = <0xc1109880 0x10>; #address-cells = <1>; #size-cells = <1>; @@ -108,29 +108,6 @@ #gpio-cells = <2>; }; - gpio_ao: ao-bank@c1108030 { - reg = <0xc8100014 0x4>, - <0xc810002c 0x4>, - <0xc8100024 0x8>; - reg-names = "mux", "pull", "gpio"; - gpio-controller; - #gpio-cells = <2>; - }; - - uart_ao_a_pins: uart_ao_a { - mux { - groups = "uart_tx_ao_a", "uart_rx_ao_a"; - function = "uart_ao"; - }; - }; - - i2c_ao_pins: i2c_mst_ao { - mux { - groups = "i2c_mst_sck_ao", "i2c_mst_sda_ao"; - function = "i2c_mst_ao"; - }; - }; - spi_nor_pins: nor { mux { groups = "nor_d", "nor_q", "nor_c", "nor_cs"; @@ -157,4 +134,34 @@ }; }; + pinctrl_aobus: pinctrl@c8100084 { + compatible = "amlogic,meson8-aobus-pinctrl"; + reg = <0xc8100084 0xc>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio_ao: ao-bank@c1108030 { + reg = <0xc8100014 0x4>, + <0xc810002c 0x4>, + <0xc8100024 0x8>; + reg-names = "mux", "pull", "gpio"; + gpio-controller; + #gpio-cells = <2>; + }; + + uart_ao_a_pins: uart_ao_a { + mux { + groups = "uart_tx_ao_a", "uart_rx_ao_a"; + function = "uart_ao"; + }; + }; + + i2c_ao_pins: i2c_mst_ao { + mux { + groups = "i2c_mst_sck_ao", "i2c_mst_sda_ao"; + function = "i2c_mst_ao"; + }; + }; + }; }; /* end of / */ diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi index 8bad5571af46..2bfe401a4da9 100644 --- a/arch/arm/boot/dts/meson8b.dtsi +++ b/arch/arm/boot/dts/meson8b.dtsi @@ -155,8 +155,8 @@ reg = <0xc1108000 0x4>, <0xc1104000 0x460>; }; - pinctrl: pinctrl@c1109880 { - compatible = "amlogic,meson8b-pinctrl"; + pinctrl_cbus: pinctrl@c1109880 { + compatible = "amlogic,meson8b-cbus-pinctrl"; reg = <0xc1109880 0x10>; #address-cells = <1>; #size-cells = <1>; @@ -171,6 +171,14 @@ gpio-controller; #gpio-cells = <2>; }; + }; + + pinctrl_aobus: pinctrl@c8100084 { + compatible = "amlogic,meson8b-aobus-pinctrl"; + reg = <0xc8100084 0xc>; + #address-cells = <1>; + #size-cells = <1>; + ranges; gpio_ao: ao-bank@c1108030 { reg = <0xc8100014 0x4>, -- cgit v1.2.3 From 11ca873574c2314de9f0cf1adf8b3be88e4e19ae Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Wed, 23 Mar 2016 10:14:00 +0100 Subject: documentation: Fix pinctrl documentation for Meson8 / Meson8b Fix pin controller documentation introducing the new compatibles for the pinctrl drivers specific for aobus / cbus. This is needed because we have changed the pin controller driver: we have now a single specialized pinctrl driver / compatible for each bus the controller is attached to, instead of one single driver dealing with all the controllers we have on different buses. Signed-off-by: Carlo Caione Acked-by: Rob Herring --- .../devicetree/bindings/pinctrl/meson,pinctrl.txt | 38 ++++------------------ 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt index 3f6a524cc5ff..32f4a2d6d0b3 100644 --- a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt @@ -1,13 +1,16 @@ == Amlogic Meson pinmux controller == Required properties for the root node: - - compatible: "amlogic,meson8-pinctrl" or "amlogic,meson8b-pinctrl" + - compatible: one of "amlogic,meson8-cbus-pinctrl" + "amlogic,meson8b-cbus-pinctrl" + "amlogic,meson8-aobus-pinctrl" + "amlogic,meson8b-aobus-pinctrl" - reg: address and size of registers controlling irq functionality === GPIO sub-nodes === -The 2 power domains of the controller (regular and always-on) are -represented as sub-nodes and each of them acts as a GPIO controller. +The GPIO bank for the controller is represented as a sub-node and it acts as a +GPIO controller. Required properties for sub-nodes are: - reg: should contain address and size for mux, pull-enable, pull and @@ -18,10 +21,6 @@ Required properties for sub-nodes are: - gpio-controller: identifies the node as a gpio controller - #gpio-cells: must be 2 -Valid sub-node names are: - - "banks" for the regular domain - - "ao-bank" for the always-on domain - === Other sub-nodes === Child nodes without the "gpio-controller" represent some desired @@ -45,7 +44,7 @@ pinctrl-bindings.txt === Example === pinctrl: pinctrl@c1109880 { - compatible = "amlogic,meson8-pinctrl"; + compatible = "amlogic,meson8-cbus-pinctrl"; reg = <0xc1109880 0x10>; #address-cells = <1>; #size-cells = <1>; @@ -61,15 +60,6 @@ pinctrl-bindings.txt #gpio-cells = <2>; }; - gpio_ao: ao-bank@c1108030 { - reg = <0xc8100014 0x4>, - <0xc810002c 0x4>, - <0xc8100024 0x8>; - reg-names = "mux", "pull", "gpio"; - gpio-controller; - #gpio-cells = <2>; - }; - nand { mux { groups = "nand_io", "nand_io_ce0", "nand_io_ce1", @@ -79,18 +69,4 @@ pinctrl-bindings.txt function = "nand"; }; }; - - uart_ao_a { - mux { - groups = "uart_tx_ao_a", "uart_rx_ao_a", - "uart_cts_ao_a", "uart_rts_ao_a"; - function = "uart_ao"; - }; - - conf { - pins = "GPIOAO_0", "GPIOAO_1", - "GPIOAO_2", "GPIOAO_3"; - bias-disable; - }; - }; }; -- cgit v1.2.3 From 456e8d53482537616899a146b706eccd095404e6 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 11 Mar 2016 10:12:28 -0600 Subject: ARM: OMAP2: Fix up interconnect barrier initialization for DRA7 The following commits: commit 3fa609755c11 ("ARM: omap2: restore OMAP4 barrier behaviour") commit f746929ffdc8 ("Revert "ARM: OMAP4: remove dead kconfig option OMAP4_ERRATA_I688"") and commit ea827ad5ffbb ("ARM: DRA7: Provide proper IO map table") came in around the same time, unfortunately this seem to have missed initializing the barrier for DRA7 platforms - omap5_map_io was reused for dra7 till it was split out by the last patch. barrier_init needs to be hence carried forward as it is valid for DRA7 family of processors as they are for OMAP5. Fixes: ea827ad5ffbb7 ("ARM: DRA7: Provide proper IO map table") Cc: stable@vger.kernel.org # v4.1+ Reported-by: Laurent Pinchart Reported-by: Tomi Valkeinen Cc: Russell King Signed-off-by: Nishanth Menon Reviewed-by: Laurent Pinchart Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/io.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 3c87e40650cf..9821be6dfd5e 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -368,6 +368,7 @@ void __init omap5_map_io(void) void __init dra7xx_map_io(void) { iotable_init(dra7xx_io_desc, ARRAY_SIZE(dra7xx_io_desc)); + omap_barriers_init(); } #endif /* -- cgit v1.2.3 From cfe1580a6415bc37fd62d79eb8102a618f7650b2 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Tue, 8 Mar 2016 12:24:35 +0530 Subject: ARM: dts: AM43x-epos: Fix clk parent for synctimer commit 55ee7017ee31 ("arm: omap2: board-generic: use omap4_local_timer_init for AM437x") makes synctimer32k as the clocksource on AM43xx. By default the synctimer32k is clocked by 32K RTC OSC on AM43xx. But this 32K RTC OSC is not available on epos boards which makes it fail to boot. Synctimer32k can also be clocked by a peripheral PLL, so making this as clock parent for synctimer3k on epos boards. Fixes: 55ee7017ee31 ("arm: omap2: board-generic: use omap4_local_timer_init for AM437x") Cc: stable@vger.kernel.org # v4.4+ Reported-by: Nishanth Menon Signed-off-by: Lokesh Vutla Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am43x-epos-evm.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index 83dfafaaba1b..d5dd72047a7e 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -794,3 +794,8 @@ tx-num-evt = <32>; rx-num-evt = <32>; }; + +&synctimer_32kclk { + assigned-clocks = <&mux_synctimer32k_ck>; + assigned-clock-parents = <&clkdiv32k_ick>; +}; -- cgit v1.2.3 From d41676ddddef27224a398609d874055866694cfa Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 14 Mar 2016 11:01:50 +0200 Subject: ARM: dts: am43xx: fix edma memcpy channel allocation EDMA was allocating DMA channels 32 and 33 for memcpy usage, out of which channel 33 is actually used by DES crypto engine. This bad allocation of the channel causes a crash in the DES crypto engine, as the channel gets configured for memcpy usage instead of hardware <-> memory DMA. Fixed by allocating DMA channels 58 and 59 for memcpy usage (I2C0 RX/TX), which are not used by anybody. Fixes: cce1ee000187 ("ARM: DTS: am437x: Use the new DT bindings for the eDMA3") Cc: stable@vger.kernel.org # v4.4+ Signed-off-by: Tero Kristo Suggested-by: Peter Ujfalusi Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am4372.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 6e4f5af3d8f8..344b861a55a5 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -207,7 +207,7 @@ ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>, <&edma_tptc2 0>; - ti,edma-memcpy-channels = <32 33>; + ti,edma-memcpy-channels = <58 59>; }; edma_tptc0: tptc@49800000 { -- cgit v1.2.3 From 6b532c4a66f44aaf5aa0dbea6aadd44981478025 Mon Sep 17 00:00:00 2001 From: Vishal Mahaveer Date: Wed, 9 Mar 2016 14:56:31 -0600 Subject: ARM: DRA722: Add ID detect for Silicon Rev 2.0 Silicon Rev 2.0 is a minor variant of Rev 1.0. Rev 2.0 is an incremental revision with various fixes including the following: - Reset logic fixes - Few asymmetric aging logic fixes - Ethernet speed fixes - EDMA fixes for McASP Signed-off-by: Vishal Mahaveer Acked-by: Nishanth Menon Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/id.c | 4 ++-- arch/arm/mach-omap2/soc.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index d85c24918c17..2abd53ae3e7a 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -669,9 +669,9 @@ void __init dra7xxx_check_revision(void) case 0: omap_revision = DRA722_REV_ES1_0; break; + case 1: default: - /* If we have no new revisions */ - omap_revision = DRA722_REV_ES1_0; + omap_revision = DRA722_REV_ES2_0; break; } break; diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 70df8f6cddcc..364418c78bf3 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -489,6 +489,7 @@ IS_OMAP_TYPE(3430, 0x3430) #define DRA752_REV_ES2_0 (DRA7XX_CLASS | (0x52 << 16) | (0x20 << 8)) #define DRA722_REV_ES1_0 (DRA7XX_CLASS | (0x22 << 16) | (0x10 << 8)) #define DRA722_REV_ES1_0 (DRA7XX_CLASS | (0x22 << 16) | (0x10 << 8)) +#define DRA722_REV_ES2_0 (DRA7XX_CLASS | (0x22 << 16) | (0x20 << 8)) void omap2xxx_check_revision(void); void omap3xxx_check_revision(void); -- cgit v1.2.3 From 6b4725743100ab9a0731b952aa64b29a5808070d Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 17 Mar 2016 14:19:06 +0000 Subject: ARM: OMAP: Correct interrupt type for ARM TWD The ARM TWD interrupt is a private peripheral interrupt (PPI) and per the ARM GIC documentation, whether the type for PPIs can be set is IMPLEMENTATION DEFINED. For OMAP4 devices the PPI type cannot be set and so when we attempt to set the type for the ARM TWD interrupt it fails. This has done unnoticed because it fails silently and because we cannot re-configure the type it has had no impact. Nevertheless fix the type for the TWD interrupt so that it matches the hardware configuration. Reported-by: Grygorii Strashko Signed-off-by: Jon Hunter Tested-by: Grygorii Strashko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap4.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 2bd9c83300b2..421fe9f8a9eb 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -70,7 +70,7 @@ compatible = "arm,cortex-a9-twd-timer"; clocks = <&mpu_periphclk>; reg = <0x48240600 0x20>; - interrupts = ; + interrupts = ; interrupt-parent = <&gic>; }; -- cgit v1.2.3 From 6f40fed1c911f218e1e189a404b26ef19effabb5 Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Fri, 18 Mar 2016 08:43:22 +0100 Subject: ARM: dts: am335x-baltos-ir5221: fix cpsw_emac0 link type In Baltos iR5221 cpsw_emac0 is connected directly to the switch IC and hence needs to be configured as "fixed-link". Signed-off-by: Yegor Yefremov Reviewed-by: Andrew Lunn Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-baltos-ir5221.dts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/am335x-baltos-ir5221.dts b/arch/arm/boot/dts/am335x-baltos-ir5221.dts index 6c667fb35449..4e28d87e9356 100644 --- a/arch/arm/boot/dts/am335x-baltos-ir5221.dts +++ b/arch/arm/boot/dts/am335x-baltos-ir5221.dts @@ -470,9 +470,12 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; phy-mode = "rmii"; dual_emac_res_vlan = <1>; + fixed-link { + speed = <100>; + full-duplex; + }; }; &cpsw_emac1 { -- cgit v1.2.3 From d59a1f71ff1aeda4b4630df92d3ad4e3b1dfc885 Mon Sep 17 00:00:00 2001 From: John Keeping Date: Wed, 18 Nov 2015 11:17:25 +0000 Subject: drm/qxl: fix cursor position with non-zero hotspot The SPICE protocol considers the position of a cursor to be the location of its active pixel on the display, so the cursor is drawn with its top-left corner at "(x - hot_spot_x, y - hot_spot_y)" but the DRM cursor position gives the location where the top-left corner should be drawn, with the hotspot being a hint for drivers that need it. This fixes the location of the window resize cursors when using Fluxbox with the QXL DRM driver and both the QXL and modesetting X drivers. Signed-off-by: John Keeping Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org Link: http://patchwork.freedesktop.org/patch/msgid/1447845445-2116-1-git-send-email-john@metanate.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/qxl/qxl_display.c | 13 +++++++++---- drivers/gpu/drm/qxl/qxl_drv.h | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 43e5f503d1c5..030409a3ee4e 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -375,10 +375,15 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, qxl_bo_kunmap(user_bo); + qcrtc->cur_x += qcrtc->hot_spot_x - hot_x; + qcrtc->cur_y += qcrtc->hot_spot_y - hot_y; + qcrtc->hot_spot_x = hot_x; + qcrtc->hot_spot_y = hot_y; + cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); cmd->type = QXL_CURSOR_SET; - cmd->u.set.position.x = qcrtc->cur_x; - cmd->u.set.position.y = qcrtc->cur_y; + cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x; + cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y; cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0); @@ -441,8 +446,8 @@ static int qxl_crtc_cursor_move(struct drm_crtc *crtc, cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); cmd->type = QXL_CURSOR_MOVE; - cmd->u.position.x = qcrtc->cur_x; - cmd->u.position.y = qcrtc->cur_y; + cmd->u.position.x = qcrtc->cur_x + qcrtc->hot_spot_x; + cmd->u.position.y = qcrtc->cur_y + qcrtc->hot_spot_y; qxl_release_unmap(qdev, release, &cmd->release_info); qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 6e6b9b1519b8..3f3897eb458c 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -135,6 +135,8 @@ struct qxl_crtc { int index; int cur_x; int cur_y; + int hot_spot_x; + int hot_spot_y; }; struct qxl_output { -- cgit v1.2.3 From c877ef8ae7b8edaedccad0fc8c23d4d1de7e2480 Mon Sep 17 00:00:00 2001 From: Kaixu Xia Date: Thu, 31 Mar 2016 13:19:41 +0000 Subject: writeback: fix the wrong congested state variable definition The right variable definition should be wb_congested_state that include WB_async_congested and WB_sync_congested. So fix it. Signed-off-by: Kaixu Xia Acked-by: Tejun Heo Signed-off-by: Jens Axboe --- mm/backing-dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/backing-dev.c b/mm/backing-dev.c index bfbd7096b6ed..0c6317b7db38 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -898,7 +898,7 @@ static atomic_t nr_wb_congested[2]; void clear_wb_congested(struct bdi_writeback_congested *congested, int sync) { wait_queue_head_t *wqh = &congestion_wqh[sync]; - enum wb_state bit; + enum wb_congested_state bit; bit = sync ? WB_sync_congested : WB_async_congested; if (test_and_clear_bit(bit, &congested->state)) @@ -911,7 +911,7 @@ EXPORT_SYMBOL(clear_wb_congested); void set_wb_congested(struct bdi_writeback_congested *congested, int sync) { - enum wb_state bit; + enum wb_congested_state bit; bit = sync ? WB_sync_congested : WB_async_congested; if (!test_and_set_bit(bit, &congested->state)) -- cgit v1.2.3 From 162f98dea487206d9ab79fc12ed64700667a894d Mon Sep 17 00:00:00 2001 From: Vladis Dronov Date: Thu, 31 Mar 2016 10:53:42 -0700 Subject: Input: gtco - fix crash on detecting device without endpoints The gtco driver expects at least one valid endpoint. If given malicious descriptors that specify 0 for the number of endpoints, it will crash in the probe function. Ensure there is at least one endpoint on the interface before using it. Also let's fix a minor coding style issue. The full correct report of this issue can be found in the public Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1283385 Reported-by: Ralf Spenneberg Signed-off-by: Vladis Dronov Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/gtco.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c index 3a7f3a4a4396..7c18249d6c8e 100644 --- a/drivers/input/tablet/gtco.c +++ b/drivers/input/tablet/gtco.c @@ -858,6 +858,14 @@ static int gtco_probe(struct usb_interface *usbinterface, goto err_free_buf; } + /* Sanity check that a device has an endpoint */ + if (usbinterface->altsetting[0].desc.bNumEndpoints < 1) { + dev_err(&usbinterface->dev, + "Invalid number of endpoints\n"); + error = -EINVAL; + goto err_free_urb; + } + /* * The endpoint is always altsetting 0, we know this since we know * this device only has one interrupt endpoint @@ -879,7 +887,7 @@ static int gtco_probe(struct usb_interface *usbinterface, * HID report descriptor */ if (usb_get_extra_descriptor(usbinterface->cur_altsetting, - HID_DEVICE_TYPE, &hid_desc) != 0){ + HID_DEVICE_TYPE, &hid_desc) != 0) { dev_err(&usbinterface->dev, "Can't retrieve exta USB descriptor to get hid report descriptor length\n"); error = -EIO; -- cgit v1.2.3 From 7cc8cbcf82d165dd658d89a7a287140948e76413 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 30 Mar 2016 09:46:23 +0200 Subject: efi/arm64: Don't apply MEMBLOCK_NOMAP to UEFI memory map mapping Commit 4dffbfc48d65 ("arm64/efi: mark UEFI reserved regions as MEMBLOCK_NOMAP") updated the mapping logic of both the RuntimeServices regions as well as the kernel's copy of the UEFI memory map to set the MEMBLOCK_NOMAP flag, which causes these regions to be omitted from the kernel direct mapping, and from being covered by a struct page. For the RuntimeServices regions, this is an obvious win, since the contents of these regions have significance to the firmware executable code itself, and are mapped in the EFI page tables using attributes that are described in the UEFI memory map, and which may differ from the attributes we use for mapping system RAM. It also prevents the contents from being modified inadvertently, since the EFI page tables are only live during runtime service invocations. None of these concerns apply to the allocation that covers the UEFI memory map, since it is entirely owned by the kernel. Setting the MEMBLOCK_NOMAP on the region did allow us to use ioremap_cache() to map it both on arm64 and on ARM, since the latter does not allow ioremap_cache() to be used on regions that are covered by a struct page. The ioremap_cache() on ARM restriction will be lifted in the v4.7 timeframe, but in the mean time, it has been reported that commit 4dffbfc48d65 causes a regression on 64k granule kernels. This is due to the fact that, given the 64 KB page size, the region that we end up removing from the kernel direct mapping is rounded up to 64 KB, and this 64 KB page frame may be shared with the initrd when booting via GRUB (which does not align its EFI_LOADER_DATA allocations to 64 KB like the stub does). This will crash the kernel as soon as it tries to access the initrd. Since the issue is specific to arm64, revert back to memblock_reserve()'ing the UEFI memory map when running on arm64. This is a temporary fix for v4.5 and v4.6, and will be superseded in the v4.7 timeframe when we will be able to move back to memblock_reserve() unconditionally. Fixes: 4dffbfc48d65 ("arm64/efi: mark UEFI reserved regions as MEMBLOCK_NOMAP") Reported-by: Mark Salter Signed-off-by: Ard Biesheuvel Acked-by: Will Deacon Cc: Leif Lindholm Cc: Mark Rutland Cc: Jeremy Linton Cc: Mark Langsdorf Cc: # v4.5 Signed-off-by: Matt Fleming --- drivers/firmware/efi/arm-init.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index aa1f743152a2..8714f8c271ba 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/arm-init.c @@ -203,7 +203,19 @@ void __init efi_init(void) reserve_regions(); early_memunmap(memmap.map, params.mmap_size); - memblock_mark_nomap(params.mmap & PAGE_MASK, - PAGE_ALIGN(params.mmap_size + - (params.mmap & ~PAGE_MASK))); + + if (IS_ENABLED(CONFIG_ARM)) { + /* + * ARM currently does not allow ioremap_cache() to be called on + * memory regions that are covered by struct page. So remove the + * UEFI memory map from the linear mapping. + */ + memblock_mark_nomap(params.mmap & PAGE_MASK, + PAGE_ALIGN(params.mmap_size + + (params.mmap & ~PAGE_MASK))); + } else { + memblock_reserve(params.mmap & PAGE_MASK, + PAGE_ALIGN(params.mmap_size + + (params.mmap & ~PAGE_MASK))); + } } -- cgit v1.2.3 From f87e0434a3bedeb5e4d75d96d9f3ad424dae6b33 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 1 Apr 2016 12:15:46 +1030 Subject: lguest, x86/entry/32: Fix handling of guest syscalls using interrupt gates In a798f091113e ("x86/entry/32: Change INT80 to be an interrupt gate") Andy broke lguest. This is because lguest had special code to allow the 0x80 trap gate go straight into the guest itself; interrupts gates (without more work, as mentioned in the file's comments) bounce via the hypervisor. His change made them go via the hypervisor, but as it's in the range of normal hardware interrupts, they were not directed through to the guest at all. Turns out the guest userspace isn't very effective if syscalls are all noops. I haven't ripped out all the now-useless trap-direct-to-guest-kernel code yet, since it will still be needed if someone decides to update this optimization. Signed-off-by: Rusty Russell Cc: Andy Lutomirski Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Weisbecker Cc: x86\@kernel.org Link: http://lkml.kernel.org/r/87fuv685kl.fsf@rustcorp.com.au Signed-off-by: Ingo Molnar --- drivers/lguest/interrupts_and_traps.c | 6 +++++- drivers/lguest/lg.h | 1 + drivers/lguest/x86/core.c | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c index eb934b0242e0..67392b6ab845 100644 --- a/drivers/lguest/interrupts_and_traps.c +++ b/drivers/lguest/interrupts_and_traps.c @@ -331,7 +331,7 @@ void set_interrupt(struct lg_cpu *cpu, unsigned int irq) * Actually now I think of it, it's possible that Ron *is* half the Plan 9 * userbase. Oh well. */ -static bool could_be_syscall(unsigned int num) +bool could_be_syscall(unsigned int num) { /* Normal Linux IA32_SYSCALL_VECTOR or reserved vector? */ return num == IA32_SYSCALL_VECTOR || num == syscall_vector; @@ -416,6 +416,10 @@ bool deliver_trap(struct lg_cpu *cpu, unsigned int num) * * This routine indicates if a particular trap number could be delivered * directly. + * + * Unfortunately, Linux 4.6 started using an interrupt gate instead of a + * trap gate for syscalls, so this trick is ineffective. See Mastery for + * how we could do this anyway... */ static bool direct_trap(unsigned int num) { diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index ac8ad0461e80..69b3814afd2f 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h @@ -167,6 +167,7 @@ void guest_set_clockevent(struct lg_cpu *cpu, unsigned long delta); bool send_notify_to_eventfd(struct lg_cpu *cpu); void init_clockdev(struct lg_cpu *cpu); bool check_syscall_vector(struct lguest *lg); +bool could_be_syscall(unsigned int num); int init_interrupts(void); void free_interrupts(void); diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index 6a4cd771a2be..adc162c7040d 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c @@ -429,8 +429,12 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu) return; break; case 32 ... 255: + /* This might be a syscall. */ + if (could_be_syscall(cpu->regs->trapnum)) + break; + /* - * These values mean a real interrupt occurred, in which case + * Other values mean a real interrupt occurred, in which case * the Host handler has already been run. We just do a * friendly check if another process should now be run, then * return to run the Guest again. -- cgit v1.2.3 From 0a0f5b7e5b56829b91d3637cf6999e0ade791ddb Mon Sep 17 00:00:00 2001 From: Gabriele Mazzotta Date: Tue, 29 Mar 2016 22:10:41 +0200 Subject: HID: multitouch: Synchronize MT frame on reset_resume input_mt_get_slot_by_key() requires input_mt_sync_frame() to be called at each frame. Do it when releasing the touches, or else we won't get a proper slot number after mt_reset_resume(). Signed-off-by: Gabriele Mazzotta Reviewed-by: Benson Leung Reviewed-by: Benjamin TIssoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 25d3c4330bf6..c741f5e50a66 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1169,6 +1169,7 @@ static void mt_release_contacts(struct hid_device *hid) MT_TOOL_FINGER, false); } + input_mt_sync_frame(input_dev); input_sync(input_dev); } } -- cgit v1.2.3 From 7d4bd1d2819ef1035ba1ed648358df37b51ade6f Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 1 Apr 2016 12:12:22 +0100 Subject: arm64: KVM: Add braces to multi-line if statement in virtual PMU code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kernel is written in C, not python, so we need braces around multi-line if statements. GCC 6 actually warns about this, thanks to the fantastic new "-Wmisleading-indentation" flag: | virt/kvm/arm/pmu.c: In function ‘kvm_pmu_overflow_status’: | virt/kvm/arm/pmu.c:198:3: warning: statement is indented as if it were guarded by... [-Wmisleading-indentation] | reg &= vcpu_sys_reg(vcpu, PMCNTENSET_EL0); | ^~~ | arch/arm64/kvm/../../../virt/kvm/arm/pmu.c:196:2: note: ...this ‘if’ clause, but it is not | if ((vcpu_sys_reg(vcpu, PMCR_EL0) & ARMV8_PMU_PMCR_E)) | ^~ As it turns out, this particular case is harmless (we just do some &= operations with 0), but worth fixing nonetheless. Signed-off-by: Will Deacon Signed-off-by: Christoffer Dall --- virt/kvm/arm/pmu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c index b5754c6c5508..575c7aa30d7e 100644 --- a/virt/kvm/arm/pmu.c +++ b/virt/kvm/arm/pmu.c @@ -193,11 +193,12 @@ static u64 kvm_pmu_overflow_status(struct kvm_vcpu *vcpu) { u64 reg = 0; - if ((vcpu_sys_reg(vcpu, PMCR_EL0) & ARMV8_PMU_PMCR_E)) + if ((vcpu_sys_reg(vcpu, PMCR_EL0) & ARMV8_PMU_PMCR_E)) { reg = vcpu_sys_reg(vcpu, PMOVSSET_EL0); reg &= vcpu_sys_reg(vcpu, PMCNTENSET_EL0); reg &= vcpu_sys_reg(vcpu, PMINTENSET_EL1); reg &= kvm_pmu_valid_counter_mask(vcpu); + } return reg; } -- cgit v1.2.3 From 2fd0f46cb1b82587c7ae4a616d69057fb9bd0af7 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 1 Apr 2016 08:52:56 +0100 Subject: libahci: save port map for forced port map In usecases where force_port_map is used saved_port_map is never set, resulting in not programming the PORTS_IMPL register as part of initial config. This patch fixes this by setting it to port_map even in case where force_port_map is used, making it more inline with other parts of the code. Fixes: 566d1827df2e ("libata: disable forced PORTS_IMPL for >= AHCI 1.3") Cc: stable@vger.kernel.org # v4.5+ Signed-off-by: Srinivas Kandagatla Acked-by: Tejun Heo Reviewed-by: Andy Gross Signed-off-by: Tejun Heo --- drivers/ata/libahci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 3982054060b8..a5d7c1c2a05e 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -507,6 +507,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) dev_info(dev, "forcing port_map 0x%x -> 0x%x\n", port_map, hpriv->force_port_map); port_map = hpriv->force_port_map; + hpriv->saved_port_map = port_map; } if (hpriv->mask_port_map) { -- cgit v1.2.3 From 17dcc37e3e847bc0e67a5b1ec52471fcc6c18682 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 1 Apr 2016 08:52:57 +0100 Subject: ata: ahci-platform: Add ports-implemented DT bindings. On some SOCs PORTS_IMPL register value is never programmed by the firmware and left at zero value. Which means that no sata ports are available for software. AHCI driver used to cope up with this by fabricating the port_map if the PORTS_IMPL register is read zero, but recent patch broke this workaround as zero value was valid for NVMe disks. This patch adds ports-implemented DT bindings as workaround for this issue in a way that DT can can override the PORTS_IMPL register in cases where the firmware did not program it already. Fixes: 566d1827df2e ("libata: disable forced PORTS_IMPL for >= AHCI 1.3") Cc: stable@vger.kernel.org # v4.5+ Signed-off-by: Srinivas Kandagatla Acked-by: Tejun Heo Reviewed-by: Andy Gross Signed-off-by: Tejun Heo --- Documentation/devicetree/bindings/ata/ahci-platform.txt | 4 ++++ drivers/ata/ahci_platform.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index 30df832a6f2f..87adfb227ca9 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt @@ -32,6 +32,10 @@ Optional properties: - target-supply : regulator for SATA target power - phys : reference to the SATA PHY node - phy-names : must be "sata-phy" +- ports-implemented : Mask that indicates which ports that the HBA supports + are available for software to use. Useful if PORTS_IMPL + is not programmed by the BIOS, which is true with + some embedded SOC's. Required properties when using sub-nodes: - #address-cells : number of cells to encode an address diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 40442332bfa7..62a04c8fb5c9 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -51,6 +51,9 @@ static int ahci_probe(struct platform_device *pdev) if (rc) return rc; + of_property_read_u32(dev->of_node, + "ports-implemented", &hpriv->force_port_map); + if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; -- cgit v1.2.3 From bb4add2ce991e4ec891b5a0287fd1ab77b631979 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 1 Apr 2016 08:52:58 +0100 Subject: ARM: dts: apq8064: add ahci ports-implemented mask This patch adds new ports-implemented mask, which is required to get achi working on the mainline. Without this patch value read from PORTS_IMPL register which is zero would not enable any ports for software to use. Fixes: 566d1827df2e ("libata: disable forced PORTS_IMPL for >= AHCI 1.3") Cc: stable@vger.kernel.org # v4.5+ Signed-off-by: Srinivas Kandagatla Reviewed-by: Andy Gross Signed-off-by: Tejun Heo --- arch/arm/boot/dts/qcom-apq8064.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index 65d0e8d98259..04f541bffbdd 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -666,7 +666,7 @@ }; sata0: sata@29000000 { - compatible = "generic-ahci"; + compatible = "qcom,apq8064-ahci", "generic-ahci"; status = "disabled"; reg = <0x29000000 0x180>; interrupts = ; @@ -688,6 +688,7 @@ phys = <&sata_phy0>; phy-names = "sata-phy"; + ports-implemented = <0x1>; }; /* Temporary fixed regulator */ -- cgit v1.2.3 From b707c65ae70e24c47a0ce4a7279224ce8f0ffb7f Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 22 Mar 2016 19:00:55 +0100 Subject: s390/scm_blk: fix deadlock for requests != REQ_TYPE_FS When we refuse a non REQ_TYPE_FS request in the build request function we already hold the queue lock. Thus we must not call blk_end_request_all but __blk_end_request_all. Reported-by: Peter Oberparleiter Fixes: de9587a ('s390/scm_blk: fix endless loop for requests != REQ_TYPE_FS') Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/block/scm_blk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c index 75d9896deccb..e6f54d3b8969 100644 --- a/drivers/s390/block/scm_blk.c +++ b/drivers/s390/block/scm_blk.c @@ -303,7 +303,7 @@ static void scm_blk_request(struct request_queue *rq) if (req->cmd_type != REQ_TYPE_FS) { blk_start_request(req); blk_dump_rq_flags(req, KMSG_COMPONENT " bad request"); - blk_end_request_all(req, -EIO); + __blk_end_request_all(req, -EIO); continue; } -- cgit v1.2.3 From 9d89d9e61d361f3adb75e1aebe4bb367faf16cfa Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Thu, 31 Mar 2016 11:48:31 +0200 Subject: s390/pci: add extra padding to function measurement block Newer machines might use a different (larger) format for function measurement blocks. To ensure that we comply with the alignment requirement on these machines and prevent memory corruption (when firmware writes more data than we expect) add 16 padding bytes at the end of the fmb. Cc: stable@vger.kernel.org # v4.1+ Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pci.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index b6bfa169a002..535a46d46d28 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -44,7 +44,8 @@ struct zpci_fmb { u64 rpcit_ops; u64 dma_rbytes; u64 dma_wbytes; -} __packed __aligned(64); + u64 pad[2]; +} __packed __aligned(128); enum zpci_state { ZPCI_FN_STATE_RESERVED, -- cgit v1.2.3 From 4f375903ccbff78e1da02133e51e37a097cd3313 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Fri, 1 Apr 2016 13:35:16 +0100 Subject: s390/seccomp: include generic seccomp header file Fixes this build error on linux-next: kernel/seccomp.c: In function '__secure_computing_strict': kernel/seccomp.c:526:3: error: implicit declaration of function 'get_compat_mode1_syscalls' The retrieval of compat syscall numbers were moved into inline function defined in asm-generic header but the asm-generic header is not being used by s390. [heiko.carstens@de.ibm.com]: even though the build error will trigger only in the next merge window it makes sense to include the generic header file already now. Fixes: ("seccomp: Get compat syscalls from asm-generic header") Cc: Matt Redfearn Signed-off-by: Sudip Mukherjee Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/seccomp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/s390/include/asm/seccomp.h b/arch/s390/include/asm/seccomp.h index 781a9cf9b002..e10f8337367b 100644 --- a/arch/s390/include/asm/seccomp.h +++ b/arch/s390/include/asm/seccomp.h @@ -13,4 +13,6 @@ #define __NR_seccomp_exit_32 __NR_exit #define __NR_seccomp_sigreturn_32 __NR_sigreturn +#include + #endif /* _ASM_S390_SECCOMP_H */ -- cgit v1.2.3 From 0fee1798af81b1428d8d5886ea48116444e635fc Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Fri, 1 Apr 2016 13:36:25 +0530 Subject: ASoC: hdac_hdmi: Fix to use dev_pm ops instead soc pm Use dev_pm ops feature instead of soc pm as core assumes system is capable of direct complete. Register with complete callback instead of resume to synchronize with Jack notification from display driver. This ensures correct Jack notification to user space. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/codecs/hdac_hdmi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 26f9459cb3bc..da3432c9f64d 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -1420,9 +1420,9 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int hdmi_codec_resume(struct snd_soc_codec *codec) +static void hdmi_codec_complete(struct device *dev) { - struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec); + struct hdac_ext_device *edev = to_hda_ext_device(dev); struct hdac_hdmi_priv *hdmi = edev->private_data; struct hdac_hdmi_pin *pin; struct hdac_device *hdac = &edev->hdac; @@ -1464,19 +1464,15 @@ static int hdmi_codec_resume(struct snd_soc_codec *codec) dev_err(bus->dev, "Cannot turn OFF display power on i915, err: %d\n", err); - return err; } - - return 0; } #else -#define hdmi_codec_resume NULL +#define hdmi_codec_complete NULL #endif static struct snd_soc_codec_driver hdmi_hda_codec = { .probe = hdmi_codec_probe, .remove = hdmi_codec_remove, - .resume = hdmi_codec_resume, .idle_bias_off = true, }; @@ -1629,6 +1625,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev) static const struct dev_pm_ops hdac_hdmi_pm = { SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL) + .complete = hdmi_codec_complete, }; static const struct hda_device_id hdmi_list[] = { -- cgit v1.2.3 From 1b377ccddd14cd04df4b9523a426b34f928002bc Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Fri, 1 Apr 2016 13:36:26 +0530 Subject: ASoC: hdac_hdmi: Fix codec power state in S3 during playback If the system enters S3 during a playback, codec power needs to be turned OFF during suspend and restored during resume. With this patch the AFG node is set to D3 and codec power is turned OFF during controller suspend call. During resume, the codec power is left in ON state if the playback was in progress while suspending. Also setting power state for AFG node is optimized. With this the loop with timeout is removed and codec_read is used instead. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/codecs/hdac_hdmi.c | 83 ++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index da3432c9f64d..aaa038ffc8a5 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -1420,32 +1420,39 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec) } #ifdef CONFIG_PM +static int hdmi_codec_prepare(struct device *dev) +{ + struct hdac_ext_device *edev = to_hda_ext_device(dev); + struct hdac_device *hdac = &edev->hdac; + + pm_runtime_get_sync(&edev->hdac.dev); + + /* + * Power down afg. + * codec_read is preferred over codec_write to set the power state. + * This way verb is send to set the power state and response + * is received. So setting power state is ensured without using loop + * to read the state. + */ + snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, + AC_PWRST_D3); + + return 0; +} + static void hdmi_codec_complete(struct device *dev) { struct hdac_ext_device *edev = to_hda_ext_device(dev); struct hdac_hdmi_priv *hdmi = edev->private_data; struct hdac_hdmi_pin *pin; struct hdac_device *hdac = &edev->hdac; - struct hdac_bus *bus = hdac->bus; - int err; - unsigned long timeout; - - hdac_hdmi_skl_enable_all_pins(&edev->hdac); - hdac_hdmi_skl_enable_dp12(&edev->hdac); /* Power up afg */ - if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0)) { - - snd_hdac_codec_write(hdac, hdac->afg, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, + AC_PWRST_D0); - /* Wait till power state is set to D0 */ - timeout = jiffies + msecs_to_jiffies(1000); - while (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0) - && time_before(jiffies, timeout)) { - msleep(50); - } - } + hdac_hdmi_skl_enable_all_pins(&edev->hdac); + hdac_hdmi_skl_enable_dp12(&edev->hdac); /* * As the ELD notify callback request is not entertained while the @@ -1455,18 +1462,10 @@ static void hdmi_codec_complete(struct device *dev) list_for_each_entry(pin, &hdmi->pin_list, head) hdac_hdmi_present_sense(pin, 1); - /* - * Codec power is turned ON during controller resume. - * Turn it OFF here - */ - err = snd_hdac_display_power(bus, false); - if (err < 0) { - dev_err(bus->dev, - "Cannot turn OFF display power on i915, err: %d\n", - err); - } + pm_runtime_put_sync(&edev->hdac.dev); } #else +#define hdmi_codec_prepare NULL #define hdmi_codec_complete NULL #endif @@ -1557,7 +1556,6 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) struct hdac_ext_device *edev = to_hda_ext_device(dev); struct hdac_device *hdac = &edev->hdac; struct hdac_bus *bus = hdac->bus; - unsigned long timeout; int err; dev_dbg(dev, "Enter: %s\n", __func__); @@ -1566,20 +1564,15 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) if (!bus) return 0; - /* Power down afg */ - if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3)) { - snd_hdac_codec_write(hdac, hdac->afg, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - - /* Wait till power state is set to D3 */ - timeout = jiffies + msecs_to_jiffies(1000); - while (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3) - && time_before(jiffies, timeout)) { - - msleep(50); - } - } - + /* + * Power down afg. + * codec_read is preferred over codec_write to set the power state. + * This way verb is send to set the power state and response + * is received. So setting power state is ensured without using loop + * to read the state. + */ + snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, + AC_PWRST_D3); err = snd_hdac_display_power(bus, false); if (err < 0) { dev_err(bus->dev, "Cannot turn on display power on i915\n"); @@ -1612,9 +1605,8 @@ static int hdac_hdmi_runtime_resume(struct device *dev) hdac_hdmi_skl_enable_dp12(&edev->hdac); /* Power up afg */ - if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0)) - snd_hdac_codec_write(hdac, hdac->afg, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, + AC_PWRST_D0); return 0; } @@ -1625,6 +1617,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev) static const struct dev_pm_ops hdac_hdmi_pm = { SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL) + .prepare = hdmi_codec_prepare, .complete = hdmi_codec_complete, }; -- cgit v1.2.3 From af037412629d8549e04039a57cf99a59b6e7a01b Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Fri, 1 Apr 2016 13:36:27 +0530 Subject: ASoC: Intel: Skylake: Fix to turn OFF codec power when entering S3 Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 07d9bc1cf3cb..3982f5536f2d 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -222,6 +222,7 @@ static int skl_suspend(struct device *dev) struct hdac_ext_bus *ebus = pci_get_drvdata(pci); struct skl *skl = ebus_to_skl(ebus); struct hdac_bus *bus = ebus_to_hbus(ebus); + int ret = 0; /* * Do not suspend if streams which are marked ignore suspend are @@ -232,10 +233,20 @@ static int skl_suspend(struct device *dev) enable_irq_wake(bus->irq); pci_save_state(pci); pci_disable_device(pci); - return 0; } else { - return _skl_suspend(ebus); + ret = _skl_suspend(ebus); + if (ret < 0) + return ret; } + + if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { + ret = snd_hdac_display_power(bus, false); + if (ret < 0) + dev_err(bus->dev, + "Cannot turn OFF display power on i915\n"); + } + + return ret; } static int skl_resume(struct device *dev) -- cgit v1.2.3 From 338d51889851cb2ac900d2ec75c8185afcde8caf Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Fri, 1 Apr 2016 15:00:25 -0500 Subject: Revert "dts: msm8974: Add blsp2_bam dma node" Revert this commit to fix regressions on non-dragonboard MSM8974 boards. This will be put back in after the correct fixes to the bam driver are accepted that allow remote processor control of the main control registers. This reverts commit 62bc8179222372624fd8a52b88327b962614d7b2. Signed-off-by: Andy Gross --- arch/arm/boot/dts/qcom-msm8974.dtsi | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index ef5330578431..d7eef2515deb 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1,6 +1,6 @@ /dts-v1/; -#include +#include #include #include "skeleton.dtsi" @@ -479,16 +479,6 @@ interrupt-controller; #interrupt-cells = <4>; }; - - blsp2_dma: dma-controller@f9944000 { - compatible = "qcom,bam-v1.4.0"; - reg = <0xf9944000 0x19000>; - interrupts = ; - clocks = <&gcc GCC_BLSP2_AHB_CLK>; - clock-names = "bam_clk"; - #dma-cells = <1>; - qcom,ee = <0>; - }; }; smd { -- cgit v1.2.3 From 10c0f0e92f019ab8d0c17da3696e35b0eef4ec16 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Fri, 1 Apr 2016 15:02:06 -0500 Subject: Revert "dts: msm8974: Add dma channels for blsp2_i2c1 node" Revert this commit to fix regressions on non-dragonboard MSM8974 boards. This will be put back in after the correct fixes to the bam driver are accepted that allow remote processor control of the main control registers. This reverts commit 0a5d0f85bba61d8643d78869c7c4214d6c2a7ce6. Signed-off-by: Andy Gross --- arch/arm/boot/dts/qcom-msm8974.dtsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index d7eef2515deb..8193139d0d87 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -460,8 +460,6 @@ clock-names = "core", "iface"; #address-cells = <1>; #size-cells = <0>; - dmas = <&blsp2_dma 20>, <&blsp2_dma 21>; - dma-names = "tx", "rx"; }; spmi_bus: spmi@fc4cf000 { -- cgit v1.2.3 From 20c07a5bf094198ff2382aa5e7c930b3c9807792 Mon Sep 17 00:00:00 2001 From: Ezequiel García Date: Fri, 1 Apr 2016 18:29:23 -0300 Subject: mtd: nand: Drop mtd.owner requirement in nand_scan Since commit 807f16d4db95 ("mtd: core: set some defaults when dev.parent is set"), it's now legal for drivers to call nand_scan and nand_scan_ident without setting mtd.owner. Drop the check and while at it remove the BUG() abuse. Fixes: 807f16d4db95 ("mtd: core: set some defaults when dev.parent is set") Signed-off-by: Ezequiel Garcia Acked-by: Boris Brezillon [Brian: editorial note - while commit 807f16d4db95 wasn't explicitly broken, some follow-up commits in the v4.4 release broke a few drivers, since they would hit this BUG() if they used nand_scan() and were built as modules] Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index b6facac54fc0..557b8462f55e 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -4009,7 +4009,6 @@ static int nand_dt_init(struct nand_chip *chip) * This is the first phase of the normal nand_scan() function. It reads the * flash ID and sets up MTD fields accordingly. * - * The mtd->owner field must be set to the module of the caller. */ int nand_scan_ident(struct mtd_info *mtd, int maxchips, struct nand_flash_dev *table) @@ -4429,19 +4428,12 @@ EXPORT_SYMBOL(nand_scan_tail); * * This fills out all the uninitialized function pointers with the defaults. * The flash ID is read and the mtd/chip structures are filled with the - * appropriate values. The mtd->owner field must be set to the module of the - * caller. + * appropriate values. */ int nand_scan(struct mtd_info *mtd, int maxchips) { int ret; - /* Many callers got this wrong, so check for it for a while... */ - if (!mtd->owner && caller_is_module()) { - pr_crit("%s called with NULL mtd->owner!\n", __func__); - BUG(); - } - ret = nand_scan_ident(mtd, maxchips, NULL); if (!ret) ret = nand_scan_tail(mtd); -- cgit v1.2.3 From f75587b8ca69768c6cf8a38a0b61e68e1bea3d36 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 1 Apr 2016 08:52:47 -0500 Subject: extcon: palmas: Drop stray IRQF_EARLY_RESUME flag Palmas extcon IRQs are nested threaded and wired to the Palmas interrupt controller. So, this flag is not required for nested IRQs anymore, since commit 3c646f2c6aa9 ("genirq: Don't suspend nested_thread irqs over system suspend") was merged. However, the fix in commit ae64e42cc2b3 ("extcon: palmas: Drop IRQF_EARLY_RESUME flag") missed a stray flag causing the following crash on resume on BeagleBoard-X15 platform: [ 53.670141] Unhandled fault: imprecise external abort (0x1406) at 0x00000000 [..] [ 53.670141] [] (omap_set_gpio_triggering) from [] (omap_gpio_unmask_irq+0xc0/0xc4) [ 53.670141] [] (omap_gpio_unmask_irq) from [] (irq_enable+0x30/0x44) [ 53.670141] [] (irq_enable) from [] (__enable_irq+0x54/0x78) [ 53.670141] [] (__enable_irq) from [] (resume_irqs+0xe8/0x100) [ 53.670141] [] (resume_irqs) from [] (syscore_resume+0x94/0x298) [ 53.670141] [] (syscore_resume) from [] (suspend_devices_and_enter+0x790/0x9e4) [ 53.670141] [] (suspend_devices_and_enter) from [] (pm_suspend+0x640/0x75c) [ 53.670141] [] (pm_suspend) from [] (state_store+0x64/0xb8) [ 53.670141] [] (state_store) from [] (kernfs_fop_write+0xc0/0x1bc) [ 53.670141] [] (kernfs_fop_write) from [] (__vfs_write+0x1c/0xd8) [ 53.670141] [] (__vfs_write) from [] (vfs_write+0x90/0x16c) [ 53.670141] [] (vfs_write) from [] (SyS_write+0x44/0x9c) [ 53.670141] [] (SyS_write) from [] (ret_fast_syscall+0x0/0x1c) [..] Fixes: ae64e42cc2b3 ("extcon: palmas: Drop IRQF_EARLY_RESUME flag") Cc: Grygorii Strashko Cc: MyungJoo Ham Cc: Chanwoo Choi Cc: Tony Lindgren Cc: Lee Jones Cc: Roger Quadros Reviewed-by: Grygorii Strashko Signed-off-by: Nishanth Menon Acked-by: Roger Quadros Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-palmas.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c index 841a4b586395..8b3226dca1d9 100644 --- a/drivers/extcon/extcon-palmas.c +++ b/drivers/extcon/extcon-palmas.c @@ -348,8 +348,7 @@ static int palmas_usb_probe(struct platform_device *pdev) palmas_vbus_irq_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | - IRQF_ONESHOT | - IRQF_EARLY_RESUME, + IRQF_ONESHOT, "palmas_usb_vbus", palmas_usb); if (status < 0) { -- cgit v1.2.3 From 5c8a010c2411729a07cb1b90c09fa978ac0ac6c0 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 4 Apr 2016 10:42:07 +0200 Subject: locking/lockdep: Fix print_collision() unused warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix this: kernel/locking/lockdep.c:2051:13: warning: ‘print_collision’ defined but not used [-Wunused-function] static void print_collision(struct task_struct *curr, ^ Signed-off-by: Borislav Petkov Cc: Andrew Morton Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1459759327-2880-1-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- kernel/locking/lockdep.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 2324ba5310db..ed9410936a22 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -1999,6 +1999,7 @@ static inline int get_first_held_lock(struct task_struct *curr, return ++i; } +#ifdef CONFIG_DEBUG_LOCKDEP /* * Returns the next chain_key iteration */ @@ -2069,6 +2070,7 @@ static void print_collision(struct task_struct *curr, printk("\nstack backtrace:\n"); dump_stack(); } +#endif /* * Checks whether the chain and the current held locks are consistent -- cgit v1.2.3 From bfa5fb14fb9e698ae2d9429a82ef0ab67a17df37 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 29 Mar 2016 15:03:06 +0200 Subject: ALSA: hda - Bind with i915 only when Intel graphics is present On Skylake and onwards, the HD-audio controller driver needs to bind with i915 for having the control of power well audio domain before actually probing the codec. This leads to the load of i915 driver from the audio driver side. But, there are systems that have no Intel graphics but Nvidia or AMD GPU, although they still use HD-audio bus for the onboard audio codecs. On these, loading the i915 driver is nothing but a useless memory and CPU consumption. A simple way to avoid it is just to look for the Intel graphics PCI entry beforehand, and try to bind with i915 only when such an entry is found. Currently, it assumes the PCI display class. If another class appears, this needs to be extended (although it's very unlikely). Signed-off-by: Takashi Iwai --- sound/hda/hdac_i915.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index fb96aead8257..54babe1c0b16 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -267,6 +267,18 @@ int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops } EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier); +/* check whether intel graphics is present */ +static bool i915_gfx_present(void) +{ + static struct pci_device_id ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16 }, + {} + }; + return pci_dev_present(ids); +} + /** * snd_hdac_i915_init - Initialize i915 audio component * @bus: HDA core bus @@ -286,6 +298,9 @@ int snd_hdac_i915_init(struct hdac_bus *bus) struct i915_audio_component *acomp; int ret; + if (!i915_gfx_present()) + return -ENODEV; + acomp = kzalloc(sizeof(*acomp), GFP_KERNEL); if (!acomp) return -ENOMEM; -- cgit v1.2.3 From f03b24a851d32ca85dacab01785b24a7ee717d37 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 4 Apr 2016 11:47:50 +0200 Subject: ALSA: usb-audio: Add a sample rate quirk for Phoenix Audio TMX320 Phoenix Audio TMX320 gives the similar error when the sample rate is asked: usb 2-1.3: 2:1: cannot get freq at ep 0x85 usb 2-1.3: 1:1: cannot get freq at ep 0x2 .... Add the corresponding USB-device ID (1de7:0014) to snd_usb_get_sample_rate_quirk() list. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=110221 Cc: Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 6178bb5d0731..24c7c2311b47 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1137,6 +1137,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */ case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ + case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */ case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */ return true; } -- cgit v1.2.3 From ef609c238a8ea163cb0af759cc73c9e2555c89da Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Apr 2016 12:37:15 +0800 Subject: sunrpc: Fix skcipher/shash conversion The skcpiher/shash conversion introduced a number of bugs in the sunrpc code: 1) Missing calls to skcipher_request_set_tfm lead to crashes. 2) The allocation size of shash_desc is too small which leads to memory corruption. Fixes: 3b5cf20cf439 ("sunrpc: Use skcipher and ahash/shash") Reported-by: J. Bruce Fields Tested-by: J. Bruce Fields Signed-off-by: Herbert Xu --- net/sunrpc/auth_gss/gss_krb5_crypto.c | 8 ++++++-- net/sunrpc/auth_gss/gss_krb5_mech.c | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index d94a8e1e9f05..da26455cf86c 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -78,6 +78,7 @@ krb5_encrypt( memcpy(out, in, length); sg_init_one(sg, out, length); + skcipher_request_set_tfm(req, tfm); skcipher_request_set_callback(req, 0, NULL, NULL); skcipher_request_set_crypt(req, sg, sg, length, local_iv); @@ -115,6 +116,7 @@ krb5_decrypt( memcpy(out, in, length); sg_init_one(sg, out, length); + skcipher_request_set_tfm(req, tfm); skcipher_request_set_callback(req, 0, NULL, NULL); skcipher_request_set_crypt(req, sg, sg, length, local_iv); @@ -946,7 +948,8 @@ krb5_rc4_setup_seq_key(struct krb5_ctx *kctx, struct crypto_skcipher *cipher, return PTR_ERR(hmac); } - desc = kmalloc(sizeof(*desc), GFP_KERNEL); + desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac), + GFP_KERNEL); if (!desc) { dprintk("%s: failed to allocate shash descriptor for '%s'\n", __func__, kctx->gk5e->cksum_name); @@ -1012,7 +1015,8 @@ krb5_rc4_setup_enc_key(struct krb5_ctx *kctx, struct crypto_skcipher *cipher, return PTR_ERR(hmac); } - desc = kmalloc(sizeof(*desc), GFP_KERNEL); + desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac), + GFP_KERNEL); if (!desc) { dprintk("%s: failed to allocate shash descriptor for '%s'\n", __func__, kctx->gk5e->cksum_name); diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 71341ccb9890..65427492b1c9 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -451,7 +451,8 @@ context_derive_keys_rc4(struct krb5_ctx *ctx) goto out_err_free_hmac; - desc = kmalloc(sizeof(*desc), GFP_KERNEL); + desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac), + GFP_KERNEL); if (!desc) { dprintk("%s: failed to allocate hash descriptor for '%s'\n", __func__, ctx->gk5e->cksum_name); -- cgit v1.2.3 From c847a89a871e1ea21d45120c3045c9b443e258f5 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 4 Apr 2016 20:51:40 +1000 Subject: HID: microsoft: add support for 3 more devices Adds support for the Micrsift Digital 4K, Media 600 and Media 3000 V1 Keyboards, which have the same quirks as the already existing hardware MS_NE4K. Fixes https://bugzilla.kernel.org/show_bug.cgi?id=52841 [jkosina@suse.cz: rephrase changelog] Signed-off-by: Alistair Leslie-Hughes Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 3 +++ drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-microsoft.c | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bdb8cc89cacc..4f9c5c6deaed 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1979,6 +1979,9 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5c0e43ed5c53..c6eaff5f8845 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -676,6 +676,7 @@ #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b #define USB_DEVICE_ID_MS_OFFICE_KB 0x0048 #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d +#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K 0x00b4 #define USB_DEVICE_ID_MS_NE4K 0x00db #define USB_DEVICE_ID_MS_NE4K_JP 0x00dc #define USB_DEVICE_ID_MS_LK6K 0x00f9 @@ -683,6 +684,8 @@ #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 #define USB_DEVICE_ID_MS_NE7K 0x071d #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 +#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1 0x0732 +#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_600 0x0750 #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c #define USB_DEVICE_ID_MS_COMFORT_KEYBOARD 0x00e3 #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 75cd3bc59c54..e924d555536c 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -272,6 +272,12 @@ static const struct hid_device_id ms_devices[] = { .driver_data = MS_PRESENTER }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), .driver_data = MS_ERGONOMY | MS_RDESC_3K }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K), + .driver_data = MS_ERGONOMY }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600), + .driver_data = MS_ERGONOMY }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1), + .driver_data = MS_ERGONOMY }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), .driver_data = MS_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), -- cgit v1.2.3 From 080edf75d337d35faa6fc3df99342b10d2848d16 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 18 Mar 2016 14:26:31 +0200 Subject: dmaengine: hsu: set HSU_CH_MTSR to memory width HSU_CH_MTSR register should be programmed to a minimum size to transfer. This size on a memory side of the transfer. Program it accordingly. Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/hsu/hsu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index eef145edb936..c7643e022578 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -64,10 +64,10 @@ static void hsu_dma_chan_start(struct hsu_dma_chan *hsuc) if (hsuc->direction == DMA_MEM_TO_DEV) { bsr = config->dst_maxburst; - mtsr = config->dst_addr_width; + mtsr = config->src_addr_width; } else if (hsuc->direction == DMA_DEV_TO_MEM) { bsr = config->src_maxburst; - mtsr = config->src_addr_width; + mtsr = config->dst_addr_width; } hsu_chan_disable(hsuc); -- cgit v1.2.3 From a197f3c7d48c0c1f45076ea47533a76ba9b1a959 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 18 Mar 2016 14:26:33 +0200 Subject: dmaengine: hsu: correct residue calculation of active descriptor The commit f0579c8ceaf1 ("dmaengine: hsu: speed up residue calculation") speeded up calculation of the queued descriptor but broke the initial residue value for active descriptor. In accordance with documentation the hardware descriptor is updated each time DMA transfered some bytes. It means we have to calculate a sum of lengths of non-submitted hardware descriptors and whatever current values in the hardware. Do this straightforward. Fixes: f0579c8ceaf1 ("dmaengine: hsu: speed up residue calculation") Cc: stable@vger.kernel.org Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/hsu/hsu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index c7643e022578..b3b212146620 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -254,10 +254,13 @@ static void hsu_dma_issue_pending(struct dma_chan *chan) static size_t hsu_dma_active_desc_size(struct hsu_dma_chan *hsuc) { struct hsu_dma_desc *desc = hsuc->desc; - size_t bytes = desc->length; + size_t bytes = 0; int i; - i = desc->active % HSU_DMA_CHAN_NR_DESC; + for (i = desc->active; i < desc->nents; i++) + bytes += desc->sg[i].len; + + i = HSU_DMA_CHAN_NR_DESC - 1; do { bytes += hsu_chan_readl(hsuc, HSU_CH_DxTSR(i)); } while (--i >= 0); -- cgit v1.2.3 From 4f4bc0abff79dc9d7ccbd3143adbf8ad1f4fe6ab Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 18 Mar 2016 14:26:32 +0200 Subject: dmaengine: hsu: correct use of channel status register There is a typo in documentation regarding to descriptor empty bit (DESCE) which is set to 1 when descriptor is empty. Thus, status register at the end of a transfer usually returns all DESCE bits set and thus it will never be zero. Moreover, there are 2 bits (CDESC) that encode current descriptor, on which interrupt has been asserted. In case when we have few descriptors programmed we might have non-zero value. Remove DESCE and CDESC bits from DMA channel status register (HSU_CH_SR) when reading it. Fixes: 2b49e0c56741 ("dmaengine: append hsu DMA driver") Cc: stable@vger.kernel.org Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/hsu/hsu.c | 2 +- drivers/dma/hsu/hsu.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index b3b212146620..ee510515ce18 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -135,7 +135,7 @@ static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc) sr = hsu_chan_readl(hsuc, HSU_CH_SR); spin_unlock_irqrestore(&hsuc->vchan.lock, flags); - return sr; + return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY); } irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr) diff --git a/drivers/dma/hsu/hsu.h b/drivers/dma/hsu/hsu.h index 578a8ee8cd05..6b070c22b1df 100644 --- a/drivers/dma/hsu/hsu.h +++ b/drivers/dma/hsu/hsu.h @@ -41,6 +41,9 @@ #define HSU_CH_SR_DESCTO(x) BIT(8 + (x)) #define HSU_CH_SR_DESCTO_ANY (BIT(11) | BIT(10) | BIT(9) | BIT(8)) #define HSU_CH_SR_CHE BIT(15) +#define HSU_CH_SR_DESCE(x) BIT(16 + (x)) +#define HSU_CH_SR_DESCE_ANY (BIT(19) | BIT(18) | BIT(17) | BIT(16)) +#define HSU_CH_SR_CDESC_ANY (BIT(31) | BIT(30)) /* Bits in HSU_CH_CR */ #define HSU_CH_CR_CHA BIT(0) -- cgit v1.2.3 From 87707cfdc387681dc702f00dfcffc26ca0bc5f71 Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Sat, 2 Apr 2016 11:08:06 +0100 Subject: drm/edid: Fix EDID Established Timings I and II MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three of the VESA DMT timings in edid_est_modes[] are slightly off. 1. 640x480@72Hz vsync_end should be 492, not 491. 2. 640x480@60Hz clock should be 25175, not 25200. 3. 1024x768@75Hz clock should be 78750, not 78800. This patch corrects those timings per the VESA DMT specification, and thus brings them into line with the identical timings in drm_dmt_modes[]. Signed-off-by: Paul Parsons Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/20160402100817.B60776E23A@gabe.freedesktop.org --- drivers/gpu/drm/drm_edid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 414d7f61aa05..94541187c62a 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -522,12 +522,12 @@ static const struct drm_display_mode edid_est_modes[] = { 720, 840, 0, 480, 481, 484, 500, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664, - 704, 832, 0, 480, 489, 491, 520, 0, + 704, 832, 0, 480, 489, 492, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656, + { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */ { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738, @@ -539,7 +539,7 @@ static const struct drm_display_mode edid_est_modes[] = { { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040, + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048, -- cgit v1.2.3 From f3a32d74ef733e1ed1a0b804c17ec27081e0ff37 Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Sat, 26 Mar 2016 13:18:38 +0000 Subject: drm/edid: Fix parsing of EDID 1.4 Established Timings III descriptor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EDID 1.4 specification section 3.10.3.9 defines an Established Timings III descriptor (tag #F7h). The parsing of this descriptor by drm_est3_modes() is off by one byte: the offset of the first timing bitmap is 6, not 5. Signed-off-by: Paul Parsons Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/20160328002258.E75DF6E35D@gabe.freedesktop.org --- drivers/gpu/drm/drm_edid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 94541187c62a..c33edb0f23b2 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2241,7 +2241,7 @@ drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing) { int i, j, m, modes = 0; struct drm_display_mode *mode; - u8 *est = ((u8 *)timing) + 5; + u8 *est = ((u8 *)timing) + 6; for (i = 0; i < 6; i++) { for (j = 7; j >= 0; j--) { -- cgit v1.2.3 From 9e60290dbafdf577766e5fc5f2fdb3be450cf9a6 Mon Sep 17 00:00:00 2001 From: Lyude Date: Wed, 16 Mar 2016 15:18:04 -0400 Subject: drm/i915: Fix race condition in intel_dp_destroy_mst_connector() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After unplugging a DP MST display from the system, we have to go through and destroy all of the DRM connectors associated with it since none of them are valid anymore. Unfortunately, intel_dp_destroy_mst_connector() doesn't do a good enough job of ensuring that throughout the destruction process that no modesettings can be done with the connectors. As it is right now, intel_dp_destroy_mst_connector() works like this: * Take all modeset locks * Clear the configuration of the crtc on the connector, if there is one * Drop all modeset locks, this is required because of circular dependency issues that arise with trying to remove the connector from sysfs with modeset locks held * Unregister the connector * Take all modeset locks, again * Do the rest of the required cleaning for destroying the connector * Finally drop all modeset locks for good This only works sometimes. During the destruction process, it's very possible that a userspace application will attempt to do a modesetting using the connector. When we drop the modeset locks, an ioctl handler such as drm_mode_setcrtc has the oppurtunity to take all of the modeset locks from us. When this happens, one thing leads to another and eventually we end up committing a mode with the non-existent connector: [drm:intel_dp_link_training_clock_recovery [i915]] *ERROR* failed to enable link training [drm:intel_dp_aux_ch] dp_aux_ch timeout status 0x7cf0001f [drm:intel_dp_start_link_train [i915]] *ERROR* failed to start channel equalization [drm:intel_dp_aux_ch] dp_aux_ch timeout status 0x7cf0001f [drm:intel_mst_pre_enable_dp [i915]] *ERROR* failed to allocate vcpi And in some cases, such as with the T460s using an MST dock, this results in breaking modesetting and/or panicking the system. To work around this, we now unregister the connector at the very beginning of intel_dp_destroy_mst_connector(), grab all the modesetting locks, and then hold them until we finish the rest of the function. CC: stable@vger.kernel.org Signed-off-by: Lyude Signed-off-by: Rob Clark Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1458155884-13877-1-git-send-email-cpaul@redhat.com (cherry picked from commit 1f7717552ef1306be3b7ed28c66c6eff550e3a23) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dp_mst.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index a2bd698fe2f7..937e77228466 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -506,6 +506,8 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_device *dev = connector->dev; + intel_connector->unregister(intel_connector); + /* need to nuke the connector */ drm_modeset_lock_all(dev); if (connector->state->crtc) { @@ -519,11 +521,7 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, WARN(ret, "Disabling mst crtc failed with %i\n", ret); } - drm_modeset_unlock_all(dev); - intel_connector->unregister(intel_connector); - - drm_modeset_lock_all(dev); intel_connector_remove_from_fbdev(intel_connector); drm_connector_cleanup(connector); drm_modeset_unlock_all(dev); -- cgit v1.2.3 From 1e8817b7f603464369b3f70895946254bf62ba8e Mon Sep 17 00:00:00 2001 From: Lyude Date: Fri, 11 Mar 2016 10:57:01 -0500 Subject: drm/i915: Call intel_dp_mst_resume() before resuming displays Since we need MST devices ready before we try to resume displays, calling this after intel_display_resume() can result in some issues with various laptop docks where the monitor won't turn back on after suspending the system. This order was originally changed in commit e7d6f7d70829 ("drm/i915: resume MST after reading back hw state") In order to fix some unclaimed register errors, however the actual cause of those has since been fixed. CC: stable@vger.kernel.org Signed-off-by: Lyude [danvet: Resolve conflicts with locking changes.] Signed-off-by: Daniel Vetter (cherry picked from commit a16b7658f4e0d4aec9bc3e75a5f0cc3f7a3a0422) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 20e82008b8b6..30798cbc6fc0 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -758,10 +758,10 @@ static int i915_drm_resume(struct drm_device *dev) dev_priv->display.hpd_irq_setup(dev); spin_unlock_irq(&dev_priv->irq_lock); - intel_display_resume(dev); - intel_dp_mst_resume(dev); + intel_display_resume(dev); + /* * ... but also need to make sure that hotplug processing * doesn't cause havoc. Like in the driver load code we don't -- cgit v1.2.3 From 9dbaab56ac09f07a73fe83bf69bec3e31060080a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 14 Mar 2016 09:01:57 +0000 Subject: drm/i915: Exit cherryview_irq_handler() after one pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This effectively reverts commit 8e5fd599eb219f1054e39b40d18b217af669eea9 Author: Ville Syrjälä Date: Wed Apr 9 13:28:50 2014 +0300 drm/i915/chv: Make CHV irq handler loop until all interrupts are consumed as under continuous execlists load we can saturate the IRQ handler, destablising the tsc clock and triggering the NMI watchdog to declare a hung CPU. [ 552.756051] clocksource: timekeeping watchdog on CPU0: Marking clocksource 'tsc' as unstable because the skew is too large: [ 552.756080] clocksource: 'refined-jiffies' wd_now: 10003b480 wd_last: 10003b28c mask: ffffffff [ 552.756091] clocksource: 'tsc' cs_now: d55d31aa50 cs_last: d17446166c mask: ffffffffffffffff [ 552.756210] clocksource: Switched to clocksource refined-jiffies [ 575.217870] NMI watchdog: Watchdog detected hard LOCKUP on cpu 1 [ 575.217893] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.5.0-rc7+ #18 [ 575.217905] Hardware name: /NUC5CPYB, BIOS PYBSWCEL.86A.0027.2015.0507.1758 05/07/2015 [ 575.217915] 0000000000000000 ffff88027fd05bc0 ffffffff81288c6d 0000000000000000 [ 575.217935] 0000000000000001 ffff88027fd05be0 ffffffff810e72d1 0000000000000000 [ 575.217951] ffff88027fd05c80 ffff88027fd05c20 ffffffff81114b60 0000000181015f1e [ 575.217967] Call Trace: [ 575.217973] [] dump_stack+0x4f/0x72 [ 575.217994] [] watchdog_overflow_callback+0x151/0x160 [ 575.218003] [] __perf_event_overflow+0xa0/0x1e0 [ 575.218016] [] perf_event_overflow+0x14/0x20 [ 575.218028] [] intel_pmu_handle_irq+0x1da/0x460 [ 575.218042] [] ? poll_idle+0x3e/0x70 [ 575.218052] [] ? poll_idle+0x3e/0x70 [ 575.218064] [] perf_event_nmi_handler+0x28/0x50 [ 575.218075] [] nmi_handle+0x60/0x130 [ 575.218086] [] ? poll_idle+0x3e/0x70 [ 575.218096] [] do_nmi+0x140/0x470 [ 575.218108] [] end_repeat_nmi+0x1a/0x1e [ 575.218119] [] ? poll_idle+0x3e/0x70 [ 575.218129] [] ? poll_idle+0x3e/0x70 [ 575.218139] [] ? poll_idle+0x3e/0x70 [ 575.218148] <> [] cpuidle_enter_state+0xf3/0x2f0 [ 575.218164] [] cpuidle_enter+0x17/0x20 [ 575.218175] [] call_cpuidle+0x2a/0x40 [ 575.218185] [] cpu_startup_entry+0x273/0x330 [ 575.218196] [] start_secondary+0x10e/0x130 However, not servicing all available IIR within the handler does hurt the throughput of pathological nop execbuf by about 20%, with a similar effect upon the dispatch latency of a series of execbuf. v2: use do {} while(0) for a smaller patch, and easier to revert again I have reasonable confidence that we do not miss GT interrupts (as execlists provides a stress case with a failure mechanism easily detected by igt), however I have less confidence about all the other sources of interrupts and worry that may lose a display hotplug interrupt, for example. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93467 Testcase: igt/gem_exec_nop/basic # requires NMI watchdog Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Antti Koskipää Cc: Tvrtko Ursulin Cc: stable@vger.kernel.org Reviewed-by: Tvrtko Ursulin Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1457946117-6714-1-git-send-email-chris@chris-wilson.co.uk (cherry picked from commit 579de73b048a0a4c66c25a033ac76a2836e0cf73) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d1a46ef5ab3f..1c212205d0e7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1829,7 +1829,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); - for (;;) { + do { master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; iir = I915_READ(VLV_IIR); @@ -1857,7 +1857,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL); POSTING_READ(GEN8_MASTER_IRQ); - } + } while (0); enable_rpm_wakeref_asserts(dev_priv); -- cgit v1.2.3 From 735b100f6d84b60da68e81e0bcb953d2021e0aa8 Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Mon, 4 Apr 2016 20:36:34 +0100 Subject: drm/edid: Fix DMT 1024x768@43Hz (interlaced) timings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One of the VESA DMT timings in drm_dmt_modes[] is slightly off. 1024x768@43Hz (interlaced) vsync_end should be 776, not 772. This brings it into line with the identical timings in edid_est_modes[]. Signed-off-by: Paul Parsons Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/20160404193639.8631D6E66B@gabe.freedesktop.org --- drivers/gpu/drm/drm_edid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c33edb0f23b2..558ef9fc39e6 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -205,7 +205,7 @@ static const struct drm_display_mode drm_dmt_modes[] = { DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 0x0f - 1024x768@43Hz, interlace */ { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032, - 1208, 1264, 0, 768, 768, 772, 817, 0, + 1208, 1264, 0, 768, 768, 776, 817, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 0x10 - 1024x768@60Hz */ -- cgit v1.2.3 From 47cd30608f3fc3dbb4fdf37300baca911e2dde34 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sun, 3 Apr 2016 14:18:22 +0200 Subject: hwrng: bcm63xx - fix device tree compilation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds missing include that resulted in implicit device tree functions errors. Fixes: 7b651706712b ("hwrng: bcm63xx - add device tree support") Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Herbert Xu --- drivers/char/hw_random/bcm63xx-rng.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c index ca9c40309757..5132c9cde50d 100644 --- a/drivers/char/hw_random/bcm63xx-rng.c +++ b/drivers/char/hw_random/bcm63xx-rng.c @@ -12,6 +12,7 @@ #include #include #include +#include #define RNG_CTRL 0x00 #define RNG_EN (1 << 0) -- cgit v1.2.3 From c6fa1aeba02111ed8676494ac7cd453a03efef3c Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 4 Apr 2016 11:26:51 -0700 Subject: HID: wacom: Initialize hid_data.inputmode to -1 Commit 5ae6e89 introduced hid_data.inputmode with a comment that it would have the value -1 if undefined, but then forgot to actually perform the initialization. Although this doesn't appear to have caused any problems in practice, it should still be remedied. Signed-off-by: Jason Gerecke Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 68a560957871..b338bbf8e626 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1817,6 +1817,8 @@ static int wacom_probe(struct hid_device *hdev, goto fail_type; } + wacom_wac->hid_data.inputmode = -1; + wacom->usbdev = dev; wacom->intf = intf; mutex_init(&wacom->lock); -- cgit v1.2.3 From 326ea2a90500fe4add86c5fb95d914d46910e780 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 4 Apr 2016 11:26:52 -0700 Subject: HID: wacom: Support switching from vendor-defined device mode on G9 and G11 A tablet PC booted into Windows may have its pen/touch hardware switched into "Wacom mode" similar to what we do with explicitly-supported hardware. Some devices appear to maintain this state across reboots, preventing their use with the generic HID driver. This patch adds support for detecting the presence of the mode switch feature report used by devices based on the G9 and G11 chips and has the HID codepath always attempt to reset the device back to sending standard HID reports. Fixes: https://sourceforge.net/p/linuxwacom/bugs/307/ Fixes: https://sourceforge.net/p/linuxwacom/bugs/310/ Fixes: https://github.com/linuxwacom/input-wacom/issues/15 Co-authored-by: Benjamin Tissoires Signed-off-by: Jason Gerecke Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 100 ++++++++++++++++++++++++++++++++++-------------- drivers/hid/wacom_wac.h | 8 ++++ 2 files changed, 80 insertions(+), 28 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index b338bbf8e626..ccf1883318c3 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -152,6 +152,25 @@ static void wacom_feature_mapping(struct hid_device *hdev, hid_data->inputmode = field->report->id; hid_data->inputmode_index = usage->usage_index; break; + + case HID_UP_DIGITIZER: + if (field->report->id == 0x0B && + (field->application == WACOM_G9_DIGITIZER || + field->application == WACOM_G11_DIGITIZER)) { + wacom->wacom_wac.mode_report = field->report->id; + wacom->wacom_wac.mode_value = 0; + } + break; + + case WACOM_G9_PAGE: + case WACOM_G11_PAGE: + if (field->report->id == 0x03 && + (field->application == WACOM_G9_TOUCHSCREEN || + field->application == WACOM_G11_TOUCHSCREEN)) { + wacom->wacom_wac.mode_report = field->report->id; + wacom->wacom_wac.mode_value = 0; + } + break; } } @@ -322,26 +341,41 @@ static int wacom_hid_set_device_mode(struct hid_device *hdev) return 0; } -static int wacom_set_device_mode(struct hid_device *hdev, int report_id, - int length, int mode) +static int wacom_set_device_mode(struct hid_device *hdev, + struct wacom_wac *wacom_wac) { - unsigned char *rep_data; + u8 *rep_data; + struct hid_report *r; + struct hid_report_enum *re; + int length; int error = -ENOMEM, limit = 0; - rep_data = kzalloc(length, GFP_KERNEL); + if (wacom_wac->mode_report < 0) + return 0; + + re = &(hdev->report_enum[HID_FEATURE_REPORT]); + r = re->report_id_hash[wacom_wac->mode_report]; + if (!r) + return -EINVAL; + + rep_data = hid_alloc_report_buf(r, GFP_KERNEL); if (!rep_data) - return error; + return -ENOMEM; + + length = hid_report_len(r); do { - rep_data[0] = report_id; - rep_data[1] = mode; + rep_data[0] = wacom_wac->mode_report; + rep_data[1] = wacom_wac->mode_value; error = wacom_set_report(hdev, HID_FEATURE_REPORT, rep_data, length, 1); if (error >= 0) error = wacom_get_report(hdev, HID_FEATURE_REPORT, rep_data, length, 1); - } while (error >= 0 && rep_data[1] != mode && limit++ < WAC_MSG_RETRIES); + } while (error >= 0 && + rep_data[1] != wacom_wac->mode_report && + limit++ < WAC_MSG_RETRIES); kfree(rep_data); @@ -411,32 +445,41 @@ static int wacom_bt_query_tablet_data(struct hid_device *hdev, u8 speed, static int wacom_query_tablet_data(struct hid_device *hdev, struct wacom_features *features) { + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + if (hdev->bus == BUS_BLUETOOTH) return wacom_bt_query_tablet_data(hdev, 1, features); - if (features->type == HID_GENERIC) - return wacom_hid_set_device_mode(hdev); - - if (features->device_type & WACOM_DEVICETYPE_TOUCH) { - if (features->type > TABLETPC) { - /* MT Tablet PC touch */ - return wacom_set_device_mode(hdev, 3, 4, 4); - } - else if (features->type == WACOM_24HDT) { - return wacom_set_device_mode(hdev, 18, 3, 2); - } - else if (features->type == WACOM_27QHDT) { - return wacom_set_device_mode(hdev, 131, 3, 2); - } - else if (features->type == BAMBOO_PAD) { - return wacom_set_device_mode(hdev, 2, 2, 2); - } - } else if (features->device_type & WACOM_DEVICETYPE_PEN) { - if (features->type <= BAMBOO_PT) { - return wacom_set_device_mode(hdev, 2, 2, 2); + if (features->type != HID_GENERIC) { + if (features->device_type & WACOM_DEVICETYPE_TOUCH) { + if (features->type > TABLETPC) { + /* MT Tablet PC touch */ + wacom_wac->mode_report = 3; + wacom_wac->mode_value = 4; + } else if (features->type == WACOM_24HDT) { + wacom_wac->mode_report = 18; + wacom_wac->mode_value = 2; + } else if (features->type == WACOM_27QHDT) { + wacom_wac->mode_report = 131; + wacom_wac->mode_value = 2; + } else if (features->type == BAMBOO_PAD) { + wacom_wac->mode_report = 2; + wacom_wac->mode_value = 2; + } + } else if (features->device_type & WACOM_DEVICETYPE_PEN) { + if (features->type <= BAMBOO_PT) { + wacom_wac->mode_report = 2; + wacom_wac->mode_value = 2; + } } } + wacom_set_device_mode(hdev, wacom_wac); + + if (features->type == HID_GENERIC) + return wacom_hid_set_device_mode(hdev); + return 0; } @@ -1818,6 +1861,7 @@ static int wacom_probe(struct hid_device *hdev, } wacom_wac->hid_data.inputmode = -1; + wacom_wac->mode_report = -1; wacom->usbdev = dev; wacom->intf = intf; diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 25baa7f29599..e2084d914c14 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -84,6 +84,12 @@ #define WACOM_DEVICETYPE_WL_MONITOR 0x0008 #define WACOM_VENDORDEFINED_PEN 0xff0d0001 +#define WACOM_G9_PAGE 0xff090000 +#define WACOM_G9_DIGITIZER (WACOM_G9_PAGE | 0x02) +#define WACOM_G9_TOUCHSCREEN (WACOM_G9_PAGE | 0x11) +#define WACOM_G11_PAGE 0xff110000 +#define WACOM_G11_DIGITIZER (WACOM_G11_PAGE | 0x02) +#define WACOM_G11_TOUCHSCREEN (WACOM_G11_PAGE | 0x11) #define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ ((f)->physical == HID_DG_STYLUS) || \ @@ -238,6 +244,8 @@ struct wacom_wac { int ps_connected; u8 bt_features; u8 bt_high_speed; + int mode_report; + int mode_value; struct hid_data hid_data; }; -- cgit v1.2.3 From 689d3c5ecc9e2eac714d32ca152b72988bc2a67b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 5 Apr 2016 15:20:20 +0300 Subject: dmaengine: omap-dma: Fix polled channel completion detection and handling When based on the CCR_ENABLE bit the channel is stopped we should not call omap_dma_callback(), only change the return value to DMA_COMPLETE. Client drivers will do the right thing to clean up the channel after the transfer has been completed. Check the CCR_ENABLE only if the channel is running and not paused since pause in sDMA means that the channel is stopped. This will fix one hard to reproduce race condition when the channel is terminated during transfer (affecting cyclic operation). Fixes: 1a7cf7b26f25 ("dmaengine: omap-dma: Handle cases when the channel is polled for completion") Signed-off-by: Peter Ujfalusi Signed-off-by: Vinod Koul --- drivers/dma/omap-dma.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 43bd5aee7ffe..6ea9044d8b71 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -48,6 +48,7 @@ struct omap_chan { unsigned dma_sig; bool cyclic; bool paused; + bool running; int dma_ch; struct omap_desc *desc; @@ -294,6 +295,8 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d) /* Enable channel */ omap_dma_chan_write(c, CCR, d->ccr | CCR_ENABLE); + + c->running = true; } static void omap_dma_stop(struct omap_chan *c) @@ -355,6 +358,8 @@ static void omap_dma_stop(struct omap_chan *c) omap_dma_chan_write(c, CLNK_CTRL, val); } + + c->running = false; } static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d, @@ -673,15 +678,20 @@ static enum dma_status omap_dma_tx_status(struct dma_chan *chan, struct omap_chan *c = to_omap_dma_chan(chan); struct virt_dma_desc *vd; enum dma_status ret; - uint32_t ccr; unsigned long flags; - ccr = omap_dma_chan_read(c, CCR); - /* The channel is no longer active, handle the completion right away */ - if (!(ccr & CCR_ENABLE)) - omap_dma_callback(c->dma_ch, 0, c); - ret = dma_cookie_status(chan, cookie, txstate); + + if (!c->paused && c->running) { + uint32_t ccr = omap_dma_chan_read(c, CCR); + /* + * The channel is no longer active, set the return value + * accordingly + */ + if (!(ccr & CCR_ENABLE)) + ret = DMA_COMPLETE; + } + if (ret == DMA_COMPLETE || !txstate) return ret; -- cgit v1.2.3 From b96c033cc8fa6484b1771d43e2fcce61e1fa5097 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 5 Apr 2016 15:20:21 +0300 Subject: dmaengine: omap-dma: Do not suppress interrupts for memcpy If the client queues up more transfers the driver will not able to move to the next transfer without knowing that the previous descriptor is completed. Signed-off-by: Peter Ujfalusi Signed-off-by: Vinod Koul --- drivers/dma/omap-dma.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 6ea9044d8b71..1e984e18c126 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -955,9 +955,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_memcpy( d->ccr = c->ccr; d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_POSTINC; - d->cicr = CICR_DROP_IE; - if (tx_flags & DMA_PREP_INTERRUPT) - d->cicr |= CICR_FRAME_IE; + d->cicr = CICR_DROP_IE | CICR_FRAME_IE; d->csdp = data_type; -- cgit v1.2.3 From d63b0f0c0f19dc8687387ead5a28148dcad1a4b9 Mon Sep 17 00:00:00 2001 From: Silvan Jegen Date: Thu, 17 Mar 2016 17:15:01 -0700 Subject: Input: xpad - add Mad Catz FightStick TE 2 VID/PID This adds the VID/PID combination for the Xbox One version of the Mad Catz FightStick TE 2. The functionality that this provides is about on par with what the Windows drivers for the stick manage to deliver. What works: - Digital stick - 6 main buttons - Xbox button - The two buttons on the back - The locking buttons (preventing accidental Xbox button press) What doesn't work: - Two of the main buttons (don't work on Windows either) - The "Haptic" button setting does not have an effect (not sure if it works on Windows) I added the MAP_TRIGGERS_TO_BUTTONS option but in my (limited) testing there was no practical difference with or without. The FightStick does not have triggers though so adding it makes sense. Signed-off-by: Silvan Jegen Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index e8a84d12b7ff..1142a93dd90b 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -153,6 +153,7 @@ static const struct xpad_device { { 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x0738, 0x4740, "Mad Catz Beat Pad", 0, XTYPE_XBOX360 }, + { 0x0738, 0x4a01, "Mad Catz FightStick TE 2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x0738, 0xb726, "Mad Catz Xbox controller - MW2", 0, XTYPE_XBOX360 }, { 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", XTYPE_XBOX360 }, @@ -304,6 +305,7 @@ static struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ + XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */ XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */ XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ -- cgit v1.2.3 From 330ed4da2c8eb821e70b1366a7af53eb1c7421fb Mon Sep 17 00:00:00 2001 From: Franck Jullien Date: Tue, 22 Mar 2016 11:52:22 +0100 Subject: dmaengine: vdma: don't crash when bad channel is requested When client request a non existing channel from of_dma_xilinx_xlate we get a NULL pointer dereferencing. This patch fix this problem. Signed-off-by: Franck Jullien Acked-by: Laurent Pinchart Signed-off-by: Vinod Koul --- drivers/dma/xilinx/xilinx_vdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c index 0ee0321868d3..ef67f278e076 100644 --- a/drivers/dma/xilinx/xilinx_vdma.c +++ b/drivers/dma/xilinx/xilinx_vdma.c @@ -1236,7 +1236,7 @@ static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec, struct xilinx_vdma_device *xdev = ofdma->of_dma_data; int chan_id = dma_spec->args[0]; - if (chan_id >= XILINX_VDMA_MAX_CHANS_PER_DEVICE) + if (chan_id >= XILINX_VDMA_MAX_CHANS_PER_DEVICE || !xdev->chan[chan_id]) return NULL; return dma_get_slave_channel(&xdev->chan[chan_id]->common); -- cgit v1.2.3 From b2d7a9cd3ff8ec561348267c2ef7d47b2b91e801 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 28 Mar 2016 18:45:36 -0300 Subject: Revert "PCI: imx6: Add support for active-low reset GPIO" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 5c5fb40de8f1 ("PCI: imx6: Add support for active-low reset GPIO") cause regressions on some boards like MX6 Gateworks Ventana, for example. The reason for the breakage is that this commit sets the GPIO polarity in the wrong logic level. Also, the commit log is wrong because active-low reset GPIO is what the driver used to support since the beginning. So keep the old behavior that ignores the GPIO polarity specified in the device tree and treat the PCI reset GPIO as active-low. Reported-by: Krzysztof Hałasa Tested-by: Tim Harvey # Gateworks Ventana Signed-off-by: Fabio Estevam Signed-off-by: Bjorn Helgaas Acked-by: Tim Harvey Acked-by: Lucas Stach CC: stable@vger.kernel.org # v4.5+ --- drivers/pci/host/pci-imx6.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index eb5a2755a164..2f817fa4c661 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -32,7 +32,7 @@ #define to_imx6_pcie(x) container_of(x, struct imx6_pcie, pp) struct imx6_pcie { - struct gpio_desc *reset_gpio; + int reset_gpio; struct clk *pcie_bus; struct clk *pcie_phy; struct clk *pcie; @@ -309,10 +309,10 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) usleep_range(200, 500); /* Some boards don't have PCIe reset GPIO. */ - if (imx6_pcie->reset_gpio) { - gpiod_set_value_cansleep(imx6_pcie->reset_gpio, 0); + if (gpio_is_valid(imx6_pcie->reset_gpio)) { + gpio_set_value_cansleep(imx6_pcie->reset_gpio, 0); msleep(100); - gpiod_set_value_cansleep(imx6_pcie->reset_gpio, 1); + gpio_set_value_cansleep(imx6_pcie->reset_gpio, 1); } return 0; @@ -523,6 +523,7 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) { struct imx6_pcie *imx6_pcie; struct pcie_port *pp; + struct device_node *np = pdev->dev.of_node; struct resource *dbi_base; struct device_node *node = pdev->dev.of_node; int ret; @@ -544,8 +545,15 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) return PTR_ERR(pp->dbi_base); /* Fetch GPIOs */ - imx6_pcie->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", - GPIOD_OUT_LOW); + imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); + if (gpio_is_valid(imx6_pcie->reset_gpio)) { + ret = devm_gpio_request_one(&pdev->dev, imx6_pcie->reset_gpio, + GPIOF_OUT_INIT_LOW, "PCIe reset"); + if (ret) { + dev_err(&pdev->dev, "unable to get reset gpio\n"); + return ret; + } + } /* Fetch clocks */ imx6_pcie->pcie_phy = devm_clk_get(&pdev->dev, "pcie_phy"); -- cgit v1.2.3 From b4203ff5464da00b7812e7b480192745b0d66bbf Mon Sep 17 00:00:00 2001 From: Dennis Kadioglu Date: Wed, 6 Apr 2016 08:39:01 +0200 Subject: ALSA: usb-audio: Add a quirk for Plantronics BT300 Plantronics BT300 does not support reading the sample rate which leads to many lines of "cannot get freq at ep 0x1". This patch adds the USB ID of the BT300 to quirks.c and avoids those error messages. Signed-off-by: Dennis Kadioglu Cc: Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 24c7c2311b47..0adfd9537cf7 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1134,6 +1134,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */ case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */ case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */ + case USB_ID(0x047F, 0x0415): /* Plantronics BT-300 */ case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */ case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ -- cgit v1.2.3 From 60901df3aed230d4565dca003f11b6a95fbf30d9 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Thu, 17 Mar 2016 16:51:59 +0000 Subject: xen: Fix page <-> pfn conversion on 32 bit systems Commit 1084b1988d22dc165c9dbbc2b0e057f9248ac4db (xen: Add Xen specific page definition) caused a regression in 4.4. The xen functions to convert between pages and pfns fail due to an overflow on systems where a physical address may not fit in an unsigned long (e.g. x86 32 bit PAE systems). Rework the conversion to avoid overflow. This should also result in simpler object code. This bug manifested itself as disk corruption with Linux 4.4 when using blkfront in a Xen HVM x86 32 bit guest with more than 4 GiB of memory. Signed-off-by: Ross Lagerwall Cc: # 4.4+ Signed-off-by: David Vrabel --- include/xen/page.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/xen/page.h b/include/xen/page.h index 96294ac93755..9dc46cb8a0fd 100644 --- a/include/xen/page.h +++ b/include/xen/page.h @@ -15,9 +15,9 @@ */ #define xen_pfn_to_page(xen_pfn) \ - ((pfn_to_page(((unsigned long)(xen_pfn) << XEN_PAGE_SHIFT) >> PAGE_SHIFT))) + (pfn_to_page((unsigned long)(xen_pfn) >> (PAGE_SHIFT - XEN_PAGE_SHIFT))) #define page_to_xen_pfn(page) \ - (((page_to_pfn(page)) << PAGE_SHIFT) >> XEN_PAGE_SHIFT) + ((page_to_pfn(page)) << (PAGE_SHIFT - XEN_PAGE_SHIFT)) #define XEN_PFN_PER_PAGE (PAGE_SIZE / XEN_PAGE_SIZE) -- cgit v1.2.3 From dfd74a1edfaba5864276a2859190a8d242d18952 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Thu, 17 Mar 2016 16:52:00 +0000 Subject: xen/balloon: Fix crash when ballooning on x86 32 bit PAE Commit 55b3da98a40dbb3776f7454daf0d95dde25c33d2 (xen/balloon: find non-conflicting regions to place hotplugged memory) caused a regression in 4.4. When ballooning on an x86 32 bit PAE system with close to 64 GiB of memory, the address returned by allocate_resource may be above 64 GiB. When using CONFIG_SPARSEMEM, this setup is limited to using physical addresses < 64 GiB. When adding memory at this address, it runs off the end of the mem_section array and causes a crash. Instead, fail the ballooning request. Signed-off-by: Ross Lagerwall Cc: # 4.4+ Signed-off-by: David Vrabel --- drivers/xen/balloon.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 9781e0dd59d6..d46839f51e73 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -151,6 +151,8 @@ static DECLARE_WAIT_QUEUE_HEAD(balloon_wq); static void balloon_process(struct work_struct *work); static DECLARE_DELAYED_WORK(balloon_worker, balloon_process); +static void release_memory_resource(struct resource *resource); + /* When ballooning out (allocating memory to return to Xen) we don't really want the kernel to try too hard since that can trigger the oom killer. */ #define GFP_BALLOON \ @@ -267,6 +269,20 @@ static struct resource *additional_memory_resource(phys_addr_t size) return NULL; } +#ifdef CONFIG_SPARSEMEM + { + unsigned long limit = 1UL << (MAX_PHYSMEM_BITS - PAGE_SHIFT); + unsigned long pfn = res->start >> PAGE_SHIFT; + + if (pfn > limit) { + pr_err("New System RAM resource outside addressable RAM (%lu > %lu)\n", + pfn, limit); + release_memory_resource(res); + return NULL; + } + } +#endif + return res; } -- cgit v1.2.3 From 1c5631c73fc2261a5df64a72c155cb53dcdc0c45 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 6 Apr 2016 09:37:22 +0100 Subject: KVM: arm/arm64: Handle forward time correction gracefully On a host that runs NTP, corrections can have a direct impact on the background timer that we program on the behalf of a vcpu. In particular, NTP performing a forward correction will result in a timer expiring sooner than expected from a guest point of view. Not a big deal, we kick the vcpu anyway. But on wake-up, the vcpu thread is going to perform a check to find out whether or not it should block. And at that point, the timer check is going to say "timer has not expired yet, go back to sleep". This results in the timer event being lost forever. There are multiple ways to handle this. One would be record that the timer has expired and let kvm_cpu_has_pending_timer return true in that case, but that would be fairly invasive. Another is to check for the "short sleep" condition in the hrtimer callback, and restart the timer for the remaining time when the condition is detected. This patch implements the latter, with a bit of refactoring in order to avoid too much code duplication. Cc: Reported-by: Alexander Graf Reviewed-by: Alexander Graf Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall --- virt/kvm/arm/arch_timer.c | 49 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index a9ad4fe3f68f..9aaa35dd9144 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@ -91,6 +91,8 @@ static void kvm_timer_inject_irq_work(struct work_struct *work) vcpu = container_of(work, struct kvm_vcpu, arch.timer_cpu.expired); vcpu->arch.timer_cpu.armed = false; + WARN_ON(!kvm_timer_should_fire(vcpu)); + /* * If the vcpu is blocked we want to wake it up so that it will see * the timer has expired when entering the guest. @@ -98,10 +100,46 @@ static void kvm_timer_inject_irq_work(struct work_struct *work) kvm_vcpu_kick(vcpu); } +static u64 kvm_timer_compute_delta(struct kvm_vcpu *vcpu) +{ + cycle_t cval, now; + + cval = vcpu->arch.timer_cpu.cntv_cval; + now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; + + if (now < cval) { + u64 ns; + + ns = cyclecounter_cyc2ns(timecounter->cc, + cval - now, + timecounter->mask, + &timecounter->frac); + return ns; + } + + return 0; +} + static enum hrtimer_restart kvm_timer_expire(struct hrtimer *hrt) { struct arch_timer_cpu *timer; + struct kvm_vcpu *vcpu; + u64 ns; + timer = container_of(hrt, struct arch_timer_cpu, timer); + vcpu = container_of(timer, struct kvm_vcpu, arch.timer_cpu); + + /* + * Check that the timer has really expired from the guest's + * PoV (NTP on the host may have forced it to expire + * early). If we should have slept longer, restart it. + */ + ns = kvm_timer_compute_delta(vcpu); + if (unlikely(ns)) { + hrtimer_forward_now(hrt, ns_to_ktime(ns)); + return HRTIMER_RESTART; + } + queue_work(wqueue, &timer->expired); return HRTIMER_NORESTART; } @@ -176,8 +214,6 @@ static int kvm_timer_update_state(struct kvm_vcpu *vcpu) void kvm_timer_schedule(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; - u64 ns; - cycle_t cval, now; BUG_ON(timer_is_armed(timer)); @@ -197,14 +233,7 @@ void kvm_timer_schedule(struct kvm_vcpu *vcpu) return; /* The timer has not yet expired, schedule a background timer */ - cval = timer->cntv_cval; - now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; - - ns = cyclecounter_cyc2ns(timecounter->cc, - cval - now, - timecounter->mask, - &timecounter->frac); - timer_arm(timer, ns); + timer_arm(timer, kvm_timer_compute_delta(vcpu)); } void kvm_timer_unschedule(struct kvm_vcpu *vcpu) -- cgit v1.2.3 From 6141570c36f0c937d5deff20d9cf08cbd8d8ed48 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 5 Apr 2016 16:11:47 +0100 Subject: arm64: KVM: Warn when PARange is less than 40 bits We always thought that 40bits of PA range would be the minimum people would actually build. Anything less is terrifyingly small. Turns out that we were both right and wrong. Nobody has ever built such a system, but the ARM Foundation Model has a PARange set to 36bits. Just because we can. Oh well. Now, the KVM API explicitely says that we offer a 40bit PA space to the VM, so we shouldn't run KVM on the Foundation Model at all. That being said, this patch offers a less agressive alternative, and loudly warns about the configuration being unsupported. You'll still be able to run VMs (at your own risks, though). This is just a workaround until we have a proper userspace API where we report the PARange to userspace. Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall --- arch/arm64/include/asm/kvm_arm.h | 6 ++---- arch/arm64/include/asm/kvm_asm.h | 2 +- arch/arm64/include/asm/kvm_host.h | 7 ++++--- arch/arm64/kvm/hyp/s2-setup.c | 39 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 4150fd8bae01..3f29887995bc 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -151,8 +151,7 @@ */ #define VTCR_EL2_FLAGS (VTCR_EL2_TG0_64K | VTCR_EL2_SH0_INNER | \ VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \ - VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \ - VTCR_EL2_RES1) + VTCR_EL2_SL0_LVL1 | VTCR_EL2_RES1) #define VTTBR_X (38 - VTCR_EL2_T0SZ_40B) #else /* @@ -163,8 +162,7 @@ */ #define VTCR_EL2_FLAGS (VTCR_EL2_TG0_4K | VTCR_EL2_SH0_INNER | \ VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \ - VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \ - VTCR_EL2_RES1) + VTCR_EL2_SL0_LVL1 | VTCR_EL2_RES1) #define VTTBR_X (37 - VTCR_EL2_T0SZ_40B) #endif diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index eb7490d232a0..40a0a24e6c98 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -54,7 +54,7 @@ extern void __vgic_v3_init_lrs(void); extern u32 __kvm_get_mdcr_el2(void); -extern void __init_stage2_translation(void); +extern u32 __init_stage2_translation(void); #endif diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 227ed475dbd3..4cd4196e94a9 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -370,11 +370,12 @@ int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu, int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); -/* #define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__) */ - static inline void __cpu_init_stage2(void) { - kvm_call_hyp(__init_stage2_translation); + u32 parange = kvm_call_hyp(__init_stage2_translation); + + WARN_ONCE(parange < 40, + "PARange is %d bits, unsupported configuration!", parange); } #endif /* __ARM64_KVM_HOST_H__ */ diff --git a/arch/arm64/kvm/hyp/s2-setup.c b/arch/arm64/kvm/hyp/s2-setup.c index 5a9f3bf542b0..bcbe761a5a3d 100644 --- a/arch/arm64/kvm/hyp/s2-setup.c +++ b/arch/arm64/kvm/hyp/s2-setup.c @@ -20,9 +20,10 @@ #include #include -void __hyp_text __init_stage2_translation(void) +u32 __hyp_text __init_stage2_translation(void) { u64 val = VTCR_EL2_FLAGS; + u64 parange; u64 tmp; /* @@ -30,7 +31,39 @@ void __hyp_text __init_stage2_translation(void) * bits in VTCR_EL2. Amusingly, the PARange is 4 bits, while * PS is only 3. Fortunately, bit 19 is RES0 in VTCR_EL2... */ - val |= (read_sysreg(id_aa64mmfr0_el1) & 7) << 16; + parange = read_sysreg(id_aa64mmfr0_el1) & 7; + val |= parange << 16; + + /* Compute the actual PARange... */ + switch (parange) { + case 0: + parange = 32; + break; + case 1: + parange = 36; + break; + case 2: + parange = 40; + break; + case 3: + parange = 42; + break; + case 4: + parange = 44; + break; + case 5: + default: + parange = 48; + break; + } + + /* + * ... and clamp it to 40 bits, unless we have some braindead + * HW that implements less than that. In all cases, we'll + * return that value for the rest of the kernel to decide what + * to do. + */ + val |= 64 - (parange > 40 ? 40 : parange); /* * Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS @@ -42,4 +75,6 @@ void __hyp_text __init_stage2_translation(void) VTCR_EL2_VS_8BIT; write_sysreg(val, vtcr_el2); + + return parange; } -- cgit v1.2.3 From 06a71a24bae57a07afee9cda6b00495347d8a448 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Mon, 4 Apr 2016 14:46:51 +0100 Subject: arm64: KVM: unregister notifiers in hyp mode teardown path Commit 1e947bad0b63 ("arm64: KVM: Skip HYP setup when already running in HYP") re-organized the hyp init code and ended up leaving the CPU hotplug and PM notifier even if hyp mode initialization fails. Since KVM is not yet supported with ACPI, the above mentioned commit breaks CPU hotplug in ACPI boot. This patch fixes teardown_hyp_mode to properly unregister both CPU hotplug and PM notifiers in the teardown path. Fixes: 1e947bad0b63 ("arm64: KVM: Skip HYP setup when already running in HYP") Cc: Christoffer Dall Cc: Marc Zyngier Signed-off-by: Sudeep Holla Signed-off-by: Christoffer Dall --- arch/arm/kvm/arm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index b5384311dec4..dded1b763c16 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -1112,10 +1112,17 @@ static void __init hyp_cpu_pm_init(void) { cpu_pm_register_notifier(&hyp_init_cpu_pm_nb); } +static void __init hyp_cpu_pm_exit(void) +{ + cpu_pm_unregister_notifier(&hyp_init_cpu_pm_nb); +} #else static inline void hyp_cpu_pm_init(void) { } +static inline void hyp_cpu_pm_exit(void) +{ +} #endif static void teardown_common_resources(void) @@ -1141,9 +1148,7 @@ static int init_subsystems(void) /* * Register CPU Hotplug notifier */ - cpu_notifier_register_begin(); - err = __register_cpu_notifier(&hyp_init_cpu_nb); - cpu_notifier_register_done(); + err = register_cpu_notifier(&hyp_init_cpu_nb); if (err) { kvm_err("Cannot register KVM init CPU notifier (%d)\n", err); return err; @@ -1193,6 +1198,8 @@ static void teardown_hyp_mode(void) free_hyp_pgds(); for_each_possible_cpu(cpu) free_page(per_cpu(kvm_arm_hyp_stack_page, cpu)); + unregister_cpu_notifier(&hyp_init_cpu_nb); + hyp_cpu_pm_exit(); } static int init_vhe_mode(void) -- cgit v1.2.3 From 8d4a2ec1e0b41b0cf9a0c5cd4511da7f8e4f3de2 Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Wed, 6 Apr 2016 14:06:48 +0100 Subject: assoc_array: don't call compare_object() on a node Changes since V1: fixed the description and added KASan warning. In assoc_array_insert_into_terminal_node(), we call the compare_object() method on all non-empty slots, even when they're not leaves, passing a pointer to an unexpected structure to compare_object(). Currently it causes an out-of-bound read access in keyring_compare_object detected by KASan (see below). The issue is easily reproduced with keyutils testsuite. Only call compare_object() when the slot is a leave. KASan warning: ================================================================== BUG: KASAN: slab-out-of-bounds in keyring_compare_object+0x213/0x240 at addr ffff880060a6f838 Read of size 8 by task keyctl/1655 ============================================================================= BUG kmalloc-192 (Not tainted): kasan: bad access detected ----------------------------------------------------------------------------- Disabling lock debugging due to kernel taint INFO: Allocated in assoc_array_insert+0xfd0/0x3a60 age=69 cpu=1 pid=1647 ___slab_alloc+0x563/0x5c0 __slab_alloc+0x51/0x90 kmem_cache_alloc_trace+0x263/0x300 assoc_array_insert+0xfd0/0x3a60 __key_link_begin+0xfc/0x270 key_create_or_update+0x459/0xaf0 SyS_add_key+0x1ba/0x350 entry_SYSCALL_64_fastpath+0x12/0x76 INFO: Slab 0xffffea0001829b80 objects=16 used=8 fp=0xffff880060a6f550 flags=0x3fff8000004080 INFO: Object 0xffff880060a6f740 @offset=5952 fp=0xffff880060a6e5d1 Bytes b4 ffff880060a6f730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f740: d1 e5 a6 60 00 88 ff ff 0e 00 00 00 00 00 00 00 ...`............ Object ffff880060a6f750: 02 cf 8e 60 00 88 ff ff 02 c0 8e 60 00 88 ff ff ...`.......`.... Object ffff880060a6f760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7d0: 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ CPU: 0 PID: 1655 Comm: keyctl Tainted: G B 4.5.0-rc4-kasan+ #291 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 0000000000000000 000000001b2800b4 ffff880060a179e0 ffffffff81b60491 ffff88006c802900 ffff880060a6f740 ffff880060a17a10 ffffffff815e2969 ffff88006c802900 ffffea0001829b80 ffff880060a6f740 ffff880060a6e650 Call Trace: [] dump_stack+0x85/0xc4 [] print_trailer+0xf9/0x150 [] object_err+0x34/0x40 [] kasan_report_error+0x230/0x550 [] ? keyring_get_key_chunk+0x13e/0x210 [] __asan_report_load_n_noabort+0x5d/0x70 [] ? keyring_compare_object+0x213/0x240 [] keyring_compare_object+0x213/0x240 [] assoc_array_insert+0x86c/0x3a60 [] ? assoc_array_cancel_edit+0x70/0x70 [] ? __key_link_begin+0x20d/0x270 [] __key_link_begin+0xfc/0x270 [] key_create_or_update+0x459/0xaf0 [] ? trace_hardirqs_on+0xd/0x10 [] ? key_type_lookup+0xc0/0xc0 [] ? lookup_user_key+0x13d/0xcd0 [] ? memdup_user+0x53/0x80 [] SyS_add_key+0x1ba/0x350 [] ? key_get_type_from_user.constprop.6+0xa0/0xa0 [] ? retint_user+0x18/0x23 [] ? trace_hardirqs_on_caller+0x3fe/0x580 [] ? trace_hardirqs_on_thunk+0x17/0x19 [] entry_SYSCALL_64_fastpath+0x12/0x76 Memory state around the buggy address: ffff880060a6f700: fc fc fc fc fc fc fc fc 00 00 00 00 00 00 00 00 ffff880060a6f780: 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc >ffff880060a6f800: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ^ ffff880060a6f880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff880060a6f900: fc fc fc fc fc fc 00 00 00 00 00 00 00 00 00 00 ================================================================== Signed-off-by: Jerome Marchand Signed-off-by: David Howells cc: stable@vger.kernel.org --- lib/assoc_array.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/assoc_array.c b/lib/assoc_array.c index 03dd576e6773..59fd7c0b119c 100644 --- a/lib/assoc_array.c +++ b/lib/assoc_array.c @@ -524,7 +524,9 @@ static bool assoc_array_insert_into_terminal_node(struct assoc_array_edit *edit, free_slot = i; continue; } - if (ops->compare_object(assoc_array_ptr_to_leaf(ptr), index_key)) { + if (assoc_array_ptr_is_leaf(ptr) && + ops->compare_object(assoc_array_ptr_to_leaf(ptr), + index_key)) { pr_devel("replace in slot %d\n", i); edit->leaf_p = &node->slots[i]; edit->dead_leaf = node->slots[i]; -- cgit v1.2.3 From 952cca6a724c420a1efb6025e41862dfd2c1edc3 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 6 Apr 2016 14:06:48 +0100 Subject: ASN.1: fix open failure check on headername The check for a failed open on headername is incorrectly checking on the out FILE pointer rather than the hdr. Fix this. Signed-off-by: Colin Ian King Signed-off-by: David Howells --- scripts/asn1_compiler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c index e000f44e37b8..c1b7ef3e24c1 100644 --- a/scripts/asn1_compiler.c +++ b/scripts/asn1_compiler.c @@ -650,7 +650,7 @@ int main(int argc, char **argv) } hdr = fopen(headername, "w"); - if (!out) { + if (!hdr) { perror(headername); exit(1); } -- cgit v1.2.3 From 23f49fd2ea9bc8e1c8cff0126cd71b071ea9e91f Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 6 Apr 2016 13:01:46 +0300 Subject: dmaengine: edma: Remove dynamic TPTC power management feature The dynamic or on demand pm_runtime does not work correctly on am335x and am437x due to interference with hwmod. Fall back using the pm_runtime usage as it was in the old driver stack, meaning that at probe time call pm_runtime_enable() and pm_runtime_get_sync() for the TPTCs as well. Fixes: 1be5336bc7ba ("dmaengine: edma: New device tree binding") Signed-off-by: Peter Ujfalusi Reported-by: Tero Kristo Signed-off-by: Vinod Koul --- drivers/dma/edma.c | 38 +++----------------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index ee3463e774f8..13b6a23dc06b 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -1570,32 +1570,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) return IRQ_HANDLED; } -static void edma_tc_set_pm_state(struct edma_tc *tc, bool enable) -{ - struct platform_device *tc_pdev; - int ret; - - if (!IS_ENABLED(CONFIG_OF) || !tc) - return; - - tc_pdev = of_find_device_by_node(tc->node); - if (!tc_pdev) { - pr_err("%s: TPTC device is not found\n", __func__); - return; - } - if (!pm_runtime_enabled(&tc_pdev->dev)) - pm_runtime_enable(&tc_pdev->dev); - - if (enable) - ret = pm_runtime_get_sync(&tc_pdev->dev); - else - ret = pm_runtime_put_sync(&tc_pdev->dev); - - if (ret < 0) - pr_err("%s: pm_runtime_%s_sync() failed for %s\n", __func__, - enable ? "get" : "put", dev_name(&tc_pdev->dev)); -} - /* Alloc channel resources */ static int edma_alloc_chan_resources(struct dma_chan *chan) { @@ -1632,8 +1606,6 @@ static int edma_alloc_chan_resources(struct dma_chan *chan) EDMA_CHAN_SLOT(echan->ch_num), chan->chan_id, echan->hw_triggered ? "HW" : "SW"); - edma_tc_set_pm_state(echan->tc, true); - return 0; err_slot: @@ -1670,7 +1642,6 @@ static void edma_free_chan_resources(struct dma_chan *chan) echan->alloced = false; } - edma_tc_set_pm_state(echan->tc, false); echan->tc = NULL; echan->hw_triggered = false; @@ -2417,10 +2388,8 @@ static int edma_pm_suspend(struct device *dev) int i; for (i = 0; i < ecc->num_channels; i++) { - if (echan[i].alloced) { + if (echan[i].alloced) edma_setup_interrupt(&echan[i], false); - edma_tc_set_pm_state(echan[i].tc, false); - } } return 0; @@ -2450,8 +2419,6 @@ static int edma_pm_resume(struct device *dev) /* Set up channel -> slot mapping for the entry slot */ edma_set_chmap(&echan[i], echan[i].slot[0]); - - edma_tc_set_pm_state(echan[i].tc, true); } } @@ -2475,7 +2442,8 @@ static struct platform_driver edma_driver = { static int edma_tptc_probe(struct platform_device *pdev) { - return 0; + pm_runtime_enable(&pdev->dev); + return pm_runtime_get_sync(&pdev->dev); } static struct platform_driver edma_tptc_driver = { -- cgit v1.2.3 From a482f4e0d848d0914ff119ef32fe1d11434d570c Mon Sep 17 00:00:00 2001 From: John Ogness Date: Wed, 6 Apr 2016 13:01:47 +0300 Subject: dmaengine: edma: special case slot limit workaround Currently drivers are limited to 19 slots for cyclic transfers. However, if the DMA burst size is the same as the period size, the period size can be changed to the full buffer size and intermediate interrupts activated. Since intermediate interrupts will trigger for each burst and the burst size is the same as the period size, the driver will get interrupts each period as expected. This has the benefit of allowing the functionality of many more slots, but only uses 2 slots. This workaround is only active if more than 19 slots are needed and the burst size matches the period size. Acked-by: Peter Ujfalusi Signed-off-by: John Ogness Signed-off-by: Sekhar Nori Signed-off-by: Vinod Koul --- drivers/dma/edma.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 13b6a23dc06b..04070baab78a 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -1238,6 +1238,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( struct edma_desc *edesc; dma_addr_t src_addr, dst_addr; enum dma_slave_buswidth dev_width; + bool use_intermediate = false; u32 burst; int i, ret, nslots; @@ -1279,8 +1280,21 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( * but the synchronization is difficult to achieve with Cyclic and * cannot be guaranteed, so we error out early. */ - if (nslots > MAX_NR_SG) - return NULL; + if (nslots > MAX_NR_SG) { + /* + * If the burst and period sizes are the same, we can put + * the full buffer into a single period and activate + * intermediate interrupts. This will produce interrupts + * after each burst, which is also after each desired period. + */ + if (burst == period_len) { + period_len = buf_len; + nslots = 2; + use_intermediate = true; + } else { + return NULL; + } + } edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]), GFP_ATOMIC); @@ -1358,8 +1372,13 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( /* * Enable period interrupt only if it is requested */ - if (tx_flags & DMA_PREP_INTERRUPT) + if (tx_flags & DMA_PREP_INTERRUPT) { edesc->pset[i].param.opt |= TCINTEN; + + /* Also enable intermediate interrupts if necessary */ + if (use_intermediate) + edesc->pset[i].param.opt |= ITCINTEN; + } } /* Place the cyclic channel to highest priority queue */ -- cgit v1.2.3 From b8af8b1d80db13dd4f5e5a3698180bd9c14aee03 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 6 Apr 2016 14:36:06 +0300 Subject: ASoC: Intel: sst: fix a loop timeout in sst_hsw_stream_reset() In the original code we ended the loop with tries set to -1 instead of zero. Signed-off-by: Dan Carpenter Signed-off-by: Mark Brown --- sound/soc/intel/haswell/sst-haswell-ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c index ac60f1301e21..91565229d074 100644 --- a/sound/soc/intel/haswell/sst-haswell-ipc.c +++ b/sound/soc/intel/haswell/sst-haswell-ipc.c @@ -1345,7 +1345,7 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream) return 0; /* wait for pause to complete before we reset the stream */ - while (stream->running && tries--) + while (stream->running && --tries) msleep(1); if (!tries) { dev_err(hsw->dev, "error: reset stream %d still running\n", -- cgit v1.2.3 From 7eb5ca09e48ec671586218ec4f381c43d534f2f4 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 6 Apr 2016 10:14:46 -0700 Subject: Input: clarify we want BTN_TOOL_ on proximity This explicitly states behavior we already use for some touchpads and tablet devices. Signed-off-by: Peter Hutterer Signed-off-by: Dmitry Torokhov --- Documentation/input/event-codes.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/input/event-codes.txt b/Documentation/input/event-codes.txt index 3f0f5ce3338b..36ea940e5bb9 100644 --- a/Documentation/input/event-codes.txt +++ b/Documentation/input/event-codes.txt @@ -173,6 +173,10 @@ A few EV_ABS codes have special meanings: proximity of the device and while the value of the BTN_TOUCH code is 0. If the input device may be used freely in three dimensions, consider ABS_Z instead. + - BTN_TOOL_ should be set to 1 when the tool comes into detectable + proximity and set to 0 when the tool leaves detectable proximity. + BTN_TOOL_ signals the type of tool that is currently detected by the + hardware and is otherwise independent of ABS_DISTANCE and/or BTN_TOUCH. * ABS_MT_: - Used to describe multitouch input events. Please see -- cgit v1.2.3 From e131b914c15aa70b2d8a5f3dbbaeec151ea17e7e Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Tue, 5 Apr 2016 10:48:48 +0800 Subject: drm/amdgpu: add invisible pin size statistic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Chunming Zhou Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 ++++++++---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 62a778012fe0..b77489dec6e8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -2034,6 +2034,7 @@ struct amdgpu_device { /* tracking pinned memory */ u64 vram_pin_size; + u64 invisible_pin_size; u64 gart_pin_size; /* amdkfd interface */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 598eb0cd5aab..aef70db16832 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -384,7 +384,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file vram_gtt.vram_size = adev->mc.real_vram_size; vram_gtt.vram_size -= adev->vram_pin_size; vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size; - vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size; + vram_gtt.vram_cpu_accessible_size -= (adev->vram_pin_size - adev->invisible_pin_size); vram_gtt.gtt_size = adev->mc.gtt_size; vram_gtt.gtt_size -= adev->gart_pin_size; return copy_to_user(out, &vram_gtt, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 5b6639faa731..e557fc1f17c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -424,9 +424,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, bo->pin_count = 1; if (gpu_addr != NULL) *gpu_addr = amdgpu_bo_gpu_offset(bo); - if (domain == AMDGPU_GEM_DOMAIN_VRAM) + if (domain == AMDGPU_GEM_DOMAIN_VRAM) { bo->adev->vram_pin_size += amdgpu_bo_size(bo); - else + if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) + bo->adev->invisible_pin_size += amdgpu_bo_size(bo); + } else bo->adev->gart_pin_size += amdgpu_bo_size(bo); } else { dev_err(bo->adev->dev, "%p pin failed\n", bo); @@ -456,9 +458,11 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo) } r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); if (likely(r == 0)) { - if (bo->tbo.mem.mem_type == TTM_PL_VRAM) + if (bo->tbo.mem.mem_type == TTM_PL_VRAM) { bo->adev->vram_pin_size -= amdgpu_bo_size(bo); - else + if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) + bo->adev->invisible_pin_size -= amdgpu_bo_size(bo); + } else bo->adev->gart_pin_size -= amdgpu_bo_size(bo); } else { dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo); -- cgit v1.2.3 From 4b814aace1f77e1a690d3ab0d30c0882f9c1f731 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 6 Apr 2016 09:24:48 +1000 Subject: drm/radeon/mst: port some MST setup code from DAL. This ports the DAL timeouts and MST rate calculations for the hw from the DAL codebase. Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ni_reg.h | 2 ++ drivers/gpu/drm/radeon/radeon_dp_mst.c | 23 +++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/ni_reg.h b/drivers/gpu/drm/radeon/ni_reg.h index da310a70c0f0..827ccc87cbc3 100644 --- a/drivers/gpu/drm/radeon/ni_reg.h +++ b/drivers/gpu/drm/radeon/ni_reg.h @@ -109,6 +109,8 @@ #define NI_DP_MSE_SAT2 0x7398 #define NI_DP_MSE_SAT_UPDATE 0x739c +# define NI_DP_MSE_SAT_UPDATE_MASK 0x3 +# define NI_DP_MSE_16_MTP_KEEPOUT 0x100 #define NI_DIG_BE_CNTL 0x7140 # define NI_DIG_FE_SOURCE_SELECT(x) (((x) & 0x7f) << 8) diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index 43cffb526b0c..b3b2d058f3d8 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c @@ -89,8 +89,16 @@ static int radeon_dp_mst_set_stream_attrib(struct radeon_encoder *primary, WREG32(NI_DP_MSE_SAT_UPDATE + primary->offset, 1); do { + unsigned value1, value2; + udelay(10); temp = RREG32(NI_DP_MSE_SAT_UPDATE + primary->offset); - } while ((temp & 0x1) && retries++ < 10000); + + value1 = temp & NI_DP_MSE_SAT_UPDATE_MASK; + value2 = temp & NI_DP_MSE_16_MTP_KEEPOUT; + + if (!value1 && !value2) + break; + } while (retries++ < 50); if (retries == 10000) DRM_ERROR("timed out waitin for SAT update %d\n", primary->offset); @@ -150,7 +158,7 @@ static int radeon_dp_mst_update_stream_attribs(struct radeon_connector *mst_conn return 0; } -static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, uint32_t y) +static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, s64 avg_time_slots_per_mtp) { struct drm_device *dev = mst->base.dev; struct radeon_device *rdev = dev->dev_private; @@ -158,6 +166,8 @@ static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, ui uint32_t val, temp; uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe); int retries = 0; + uint32_t x = drm_fixp2int(avg_time_slots_per_mtp); + uint32_t y = drm_fixp2int_ceil((avg_time_slots_per_mtp - x) << 26); val = NI_DP_MSE_RATE_X(x) | NI_DP_MSE_RATE_Y(y); @@ -165,6 +175,7 @@ static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, ui do { temp = RREG32(NI_DP_MSE_RATE_UPDATE + offset); + udelay(10); } while ((temp & 0x1) && (retries++ < 10000)); if (retries >= 10000) @@ -394,7 +405,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode) struct drm_crtc *crtc; struct radeon_crtc *radeon_crtc; int ret, slots; - + s64 fixed_pbn, fixed_pbn_per_slot, avg_time_slots_per_mtp; if (!ASIC_IS_DCE5(rdev)) { DRM_ERROR("got mst dpms on non-DCE5\n"); return; @@ -456,7 +467,11 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode) mst_enc->enc_active = true; radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary); - radeon_dp_mst_set_vcp_size(radeon_encoder, slots, 0); + + fixed_pbn = drm_int2fixp(mst_enc->pbn); + fixed_pbn_per_slot = drm_int2fixp(radeon_connector->mst_port->mst_mgr.pbn_div); + avg_time_slots_per_mtp = drm_fixp_div(fixed_pbn, fixed_pbn_per_slot); + radeon_dp_mst_set_vcp_size(radeon_encoder, avg_time_slots_per_mtp); atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0, mst_enc->fe); -- cgit v1.2.3 From f3d58dccdbf9f8c0a229d555d4b295d52e743039 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 6 Apr 2016 09:24:49 +1000 Subject: drm/radeon: use helper for mst connector dpms. I noticed my monitor didn't power off when it should, this should fix it. Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_dp_mst.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index b3b2d058f3d8..de504ea29c06 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c @@ -257,14 +257,8 @@ radeon_dp_mst_connector_destroy(struct drm_connector *connector) kfree(radeon_connector); } -static int radeon_connector_dpms(struct drm_connector *connector, int mode) -{ - DRM_DEBUG_KMS("\n"); - return 0; -} - static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = { - .dpms = radeon_connector_dpms, + .dpms = drm_helper_connector_dpms, .detect = radeon_dp_mst_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = radeon_dp_mst_connector_destroy, -- cgit v1.2.3 From 50fbd977733d1cbafe75baf4b50424434dcfea8c Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 5 Apr 2016 22:41:05 +0530 Subject: lkdtm: fix memory leak of val This case is supposed to read from a page after after it is freed, but it missed freeing val if we are not able to get a free page. Signed-off-by: Sudip Mukherjee Signed-off-by: Kees Cook --- drivers/misc/lkdtm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 5f1a36b8fbb0..2f0b02248761 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c @@ -498,12 +498,13 @@ static void lkdtm_do_action(enum ctype which) } case CT_READ_BUDDY_AFTER_FREE: { unsigned long p = __get_free_page(GFP_KERNEL); - int saw, *val = kmalloc(1024, GFP_KERNEL); + int saw, *val; int *base; if (!p) break; + val = kmalloc(1024, GFP_KERNEL); if (!val) break; -- cgit v1.2.3 From d2e10088ce01191748857296999b8c24a9a51959 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 5 Apr 2016 22:41:06 +0530 Subject: lkdtm: fix memory leak of base This case is supposed to read from a memory after it has been freed, but we missed freeing base if the memory 'val' could not be allocated. Signed-off-by: Sudip Mukherjee Signed-off-by: Kees Cook --- drivers/misc/lkdtm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 2f0b02248761..5b3a63c87ec9 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c @@ -458,8 +458,10 @@ static void lkdtm_do_action(enum ctype which) break; val = kmalloc(len, GFP_KERNEL); - if (!val) + if (!val) { + kfree(base); break; + } *val = 0x12345678; base[offset] = *val; -- cgit v1.2.3 From 3d085c7413d32bb6895e5b9b5ee6a7d2180159c5 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 6 Apr 2016 15:53:27 -0700 Subject: lkdtm: do not leak free page on kmalloc failure This frees the allocated page if there is a kmalloc failure. Signed-off-by: Kees Cook --- drivers/misc/lkdtm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 5b3a63c87ec9..0a5cbbe12452 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c @@ -507,8 +507,10 @@ static void lkdtm_do_action(enum ctype which) break; val = kmalloc(1024, GFP_KERNEL); - if (!val) + if (!val) { + free_page(p); break; + } base = (int *)p; -- cgit v1.2.3 From 42bf7b46a5de03c8e2dd28a1f105bc28b6485243 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 30 Mar 2016 11:08:33 +0200 Subject: drm/i915: fix deadlock on lid open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e2c8b8701e2d moved modeset locking inside resume/suspend functions, but missed a code path only executed on lid close/open on older hardware. The result was a deadlock when closing and opening the lid without suspending on such hardware: ============================================= [ INFO: possible recursive locking detected ] 4.6.0-rc1 #385 Not tainted --------------------------------------------- kworker/0:3/88 is trying to acquire lock: (&dev->mode_config.mutex){+.+.+.}, at: [] intel_display_resume+0x4a/0x12f [i915] but task is already holding lock: (&dev->mode_config.mutex){+.+.+.}, at: [] drm_modeset_lock_all+0x3e/0xa6 [drm] other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&dev->mode_config.mutex); lock(&dev->mode_config.mutex); *** DEADLOCK *** May be due to missing lock nesting notation 7 locks held by kworker/0:3/88: #0: ("kacpi_notify"){++++.+}, at: [] process_one_work+0x14a/0x50b #1: ((&dpc->work)#2){+.+.+.}, at: [] process_one_work+0x14a/0x50b #2: ((acpi_lid_notifier).rwsem){++++.+}, at: [] __blocking_notifier_call_chain+0x34/0x65 #3: (&dev_priv->modeset_restore_lock){+.+.+.}, at: [] intel_lid_notify+0x3c/0xd9 [i915] #4: (&dev->mode_config.mutex){+.+.+.}, at: [] drm_modeset_lock_all+0x3e/0xa6 [drm] #5: (crtc_ww_class_acquire){+.+.+.}, at: [] drm_modeset_lock_all+0x48/0xa6 [drm] #6: (crtc_ww_class_mutex){+.+.+.}, at: [] modeset_lock+0x13c/0x1cd [drm] stack backtrace: CPU: 0 PID: 88 Comm: kworker/0:3 Not tainted 4.6.0-rc1 #385 Hardware name: LENOVO 2776LEG/2776LEG, BIOS 6EET55WW (3.15 ) 12/19/2011 Workqueue: kacpi_notify acpi_os_execute_deferred 0000000000000000 ffff88022fd5f990 ffffffff8124af06 ffffffff825b39c0 ffffffff825b39c0 ffff88022fd5fa60 ffffffff8108f547 ffff88022fd5fa70 000000008108e817 ffff880230236cc0 0000000000000000 ffffffff825b39c0 Call Trace: [] dump_stack+0x67/0x90 [] __lock_acquire+0xdb5/0xf71 [] ? look_up_lock_class+0xbe/0x10a [] lock_acquire+0x137/0x1cb [] ? lock_acquire+0x137/0x1cb [] ? intel_display_resume+0x4a/0x12f [i915] [] mutex_lock_nested+0x7e/0x3a4 [] ? intel_display_resume+0x4a/0x12f [i915] [] ? intel_display_resume+0x4a/0x12f [i915] [] ? modeset_lock+0x13c/0x1cd [drm] [] intel_display_resume+0x4a/0x12f [i915] [] ? intel_display_resume+0x4a/0x12f [i915] [] ? modeset_lock+0x13c/0x1cd [drm] [] ? modeset_lock+0x13c/0x1cd [drm] [] ? drm_modeset_lock+0x17/0x24 [drm] [] ? drm_modeset_lock_all_ctx+0x87/0xa1 [drm] [] intel_lid_notify+0xb0/0xd9 [i915] [] notifier_call_chain+0x4a/0x6c [] __blocking_notifier_call_chain+0x4d/0x65 [] blocking_notifier_call_chain+0x14/0x16 [] acpi_lid_send_state+0x83/0xad [button] [] acpi_button_notify+0x41/0x132 [button] [] acpi_device_notify+0x19/0x1b [] acpi_ev_notify_dispatch+0x49/0x64 [] acpi_os_execute_deferred+0x14/0x20 [] process_one_work+0x265/0x50b [] worker_thread+0x1fc/0x2dd [] ? rescuer_thread+0x309/0x309 [] ? rescuer_thread+0x309/0x309 [] kthread+0xe0/0xe8 [] ? local_clock+0x19/0x22 [] ret_from_fork+0x22/0x40 [] ? kthread_create_on_node+0x1b5/0x1b5 Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") Cc: Maarten Lankhorst Signed-off-by: Bjørn Mork Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1459328913-13719-1-git-send-email-bjorn@mork.no (cherry picked from commit 9f54d4bd5808b5c892a44c539c126b71d299f341) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_lvds.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 30a8403a8f4f..cd9fe609aefb 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -478,11 +478,8 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, * and as part of the cleanup in the hw state restore we also redisable * the vga plane. */ - if (!HAS_PCH_SPLIT(dev)) { - drm_modeset_lock_all(dev); + if (!HAS_PCH_SPLIT(dev)) intel_display_resume(dev); - drm_modeset_unlock_all(dev); - } dev_priv->modeset_restore = MODESET_DONE; -- cgit v1.2.3 From c12d2da56d0e07d230968ee2305aaa86b93a6832 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 4 Apr 2016 10:24:58 +0200 Subject: mm/gup: Remove the macro overload API migration helpers from the get_user*() APIs The pkeys changes brought about a truly hideous set of macros in: cde70140fed8 ("mm/gup: Overload get_user_pages() functions") ... which macros are (ab-)using the fact that __VA_ARGS__ can be used to shift parameter positions in macro arguments without breaking the build and so can be used to call separate C functions depending on the number of arguments of the macro. This allowed easy migration of these 3 GUP APIs, as both these variants worked at the C level: old: ret = get_user_pages(current, current->mm, address, 1, 1, 0, &page, NULL); new: ret = get_user_pages(address, 1, 1, 0, &page, NULL); ... while we also generated a (functionally harmless but noticeable) build time warning if the old API was used. As there are over 300 uses of these APIs, this trick eased the migration of the API and avoided excessive migration pain in linux-next. Now, with its work done, get rid of all of that complication and ugliness: 3 files changed, 16 insertions(+), 140 deletions(-) ... where the linecount of the migration hack was further inflated by the fact that there are NOMMU variants of these GUP APIs as well. Much of the conversion was done in linux-next over the past couple of months, and Linus recently removed all remaining old API uses from the upstream tree in the following upstrea commit: cb107161df3c ("Convert straggling drivers to new six-argument get_user_pages()") There was one more old-API usage in mm/gup.c, in the CONFIG_HAVE_GENERIC_RCU_GUP code path that ARM, ARM64 and PowerPC uses. After this commit any old API usage will break the build. [ Also fixed a PowerPC/HAVE_GENERIC_RCU_GUP warning reported by Stephen Rothwell. ] Cc: Andrew Morton Cc: Dave Hansen Cc: Dave Hansen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephen Rothwell Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Cc: linux-mm@kvack.org Signed-off-by: Ingo Molnar --- include/linux/mm.h | 64 +++--------------------------------------------------- mm/gup.c | 52 ++++++-------------------------------------- mm/nommu.c | 44 ++++++------------------------------- 3 files changed, 17 insertions(+), 143 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index ed6407d1b7b5..d6508a025a31 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1250,78 +1250,20 @@ long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages, struct vm_area_struct **vmas); -long get_user_pages6(unsigned long start, unsigned long nr_pages, +long get_user_pages(unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages, struct vm_area_struct **vmas); -long get_user_pages_locked6(unsigned long start, unsigned long nr_pages, +long get_user_pages_locked(unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages, int *locked); long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages, unsigned int gup_flags); -long get_user_pages_unlocked5(unsigned long start, unsigned long nr_pages, +long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages); int get_user_pages_fast(unsigned long start, int nr_pages, int write, struct page **pages); -/* suppress warnings from use in EXPORT_SYMBOL() */ -#ifndef __DISABLE_GUP_DEPRECATED -#define __gup_deprecated __deprecated -#else -#define __gup_deprecated -#endif -/* - * These macros provide backward-compatibility with the old - * get_user_pages() variants which took tsk/mm. These - * functions/macros provide both compile-time __deprecated so we - * can catch old-style use and not break the build. The actual - * functions also have WARN_ON()s to let us know at runtime if - * the get_user_pages() should have been the "remote" variant. - * - * These are hideous, but temporary. - * - * If you run into one of these __deprecated warnings, look - * at how you are calling get_user_pages(). If you are calling - * it with current/current->mm as the first two arguments, - * simply remove those arguments. The behavior will be the same - * as it is now. If you are calling it on another task, use - * get_user_pages_remote() instead. - * - * Any questions? Ask Dave Hansen - */ -long -__gup_deprecated -get_user_pages8(struct task_struct *tsk, struct mm_struct *mm, - unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages, - struct vm_area_struct **vmas); -#define GUP_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, get_user_pages, ...) \ - get_user_pages -#define get_user_pages(...) GUP_MACRO(__VA_ARGS__, \ - get_user_pages8, x, \ - get_user_pages6, x, x, x, x, x)(__VA_ARGS__) - -__gup_deprecated -long get_user_pages_locked8(struct task_struct *tsk, struct mm_struct *mm, - unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages, - int *locked); -#define GUPL_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, get_user_pages_locked, ...) \ - get_user_pages_locked -#define get_user_pages_locked(...) GUPL_MACRO(__VA_ARGS__, \ - get_user_pages_locked8, x, \ - get_user_pages_locked6, x, x, x, x)(__VA_ARGS__) - -__gup_deprecated -long get_user_pages_unlocked7(struct task_struct *tsk, struct mm_struct *mm, - unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages); -#define GUPU_MACRO(_1, _2, _3, _4, _5, _6, _7, get_user_pages_unlocked, ...) \ - get_user_pages_unlocked -#define get_user_pages_unlocked(...) GUPU_MACRO(__VA_ARGS__, \ - get_user_pages_unlocked7, x, \ - get_user_pages_unlocked5, x, x, x, x)(__VA_ARGS__) - /* Container for pinned pfns / pages */ struct frame_vector { unsigned int nr_allocated; /* Number of frames we have space for */ diff --git a/mm/gup.c b/mm/gup.c index 7f1c4fb77cfa..63d5e002768b 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1,4 +1,3 @@ -#define __DISABLE_GUP_DEPRECATED 1 #include #include #include @@ -839,7 +838,7 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, * if (locked) * up_read(&mm->mmap_sem); */ -long get_user_pages_locked6(unsigned long start, unsigned long nr_pages, +long get_user_pages_locked(unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages, int *locked) { @@ -847,7 +846,7 @@ long get_user_pages_locked6(unsigned long start, unsigned long nr_pages, write, force, pages, NULL, locked, true, FOLL_TOUCH); } -EXPORT_SYMBOL(get_user_pages_locked6); +EXPORT_SYMBOL(get_user_pages_locked); /* * Same as get_user_pages_unlocked(...., FOLL_TOUCH) but it allows to @@ -892,13 +891,13 @@ EXPORT_SYMBOL(__get_user_pages_unlocked); * or if "force" shall be set to 1 (get_user_pages_fast misses the * "force" parameter). */ -long get_user_pages_unlocked5(unsigned long start, unsigned long nr_pages, +long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages) { return __get_user_pages_unlocked(current, current->mm, start, nr_pages, write, force, pages, FOLL_TOUCH); } -EXPORT_SYMBOL(get_user_pages_unlocked5); +EXPORT_SYMBOL(get_user_pages_unlocked); /* * get_user_pages_remote() - pin user pages in memory @@ -972,7 +971,7 @@ EXPORT_SYMBOL(get_user_pages_remote); * and mm being operated on are the current task's. We also * obviously don't pass FOLL_REMOTE in here. */ -long get_user_pages6(unsigned long start, unsigned long nr_pages, +long get_user_pages(unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages, struct vm_area_struct **vmas) { @@ -980,7 +979,7 @@ long get_user_pages6(unsigned long start, unsigned long nr_pages, write, force, pages, vmas, NULL, false, FOLL_TOUCH); } -EXPORT_SYMBOL(get_user_pages6); +EXPORT_SYMBOL(get_user_pages); /** * populate_vma_page_range() - populate a range of pages in the vma. @@ -1491,7 +1490,6 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, int get_user_pages_fast(unsigned long start, int nr_pages, int write, struct page **pages) { - struct mm_struct *mm = current->mm; int nr, ret; start &= PAGE_MASK; @@ -1503,8 +1501,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, start += nr << PAGE_SHIFT; pages += nr; - ret = get_user_pages_unlocked(current, mm, start, - nr_pages - nr, write, 0, pages); + ret = get_user_pages_unlocked(start, nr_pages - nr, write, 0, pages); /* Have to be a bit careful with return values */ if (nr > 0) { @@ -1519,38 +1516,3 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, } #endif /* CONFIG_HAVE_GENERIC_RCU_GUP */ - -long get_user_pages8(struct task_struct *tsk, struct mm_struct *mm, - unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages, - struct vm_area_struct **vmas) -{ - WARN_ONCE(tsk != current, "get_user_pages() called on remote task"); - WARN_ONCE(mm != current->mm, "get_user_pages() called on remote mm"); - - return get_user_pages6(start, nr_pages, write, force, pages, vmas); -} -EXPORT_SYMBOL(get_user_pages8); - -long get_user_pages_locked8(struct task_struct *tsk, struct mm_struct *mm, - unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages, int *locked) -{ - WARN_ONCE(tsk != current, "get_user_pages_locked() called on remote task"); - WARN_ONCE(mm != current->mm, "get_user_pages_locked() called on remote mm"); - - return get_user_pages_locked6(start, nr_pages, write, force, pages, locked); -} -EXPORT_SYMBOL(get_user_pages_locked8); - -long get_user_pages_unlocked7(struct task_struct *tsk, struct mm_struct *mm, - unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages) -{ - WARN_ONCE(tsk != current, "get_user_pages_unlocked() called on remote task"); - WARN_ONCE(mm != current->mm, "get_user_pages_unlocked() called on remote mm"); - - return get_user_pages_unlocked5(start, nr_pages, write, force, pages); -} -EXPORT_SYMBOL(get_user_pages_unlocked7); - diff --git a/mm/nommu.c b/mm/nommu.c index de8b6b6580c1..bf94913dbbb6 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -15,8 +15,6 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#define __DISABLE_GUP_DEPRECATED - #include #include #include @@ -161,7 +159,7 @@ finish_or_fault: * slab page or a secondary page from a compound page * - don't permit access to VMAs that don't support it, such as I/O mappings */ -long get_user_pages6(unsigned long start, unsigned long nr_pages, +long get_user_pages(unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages, struct vm_area_struct **vmas) { @@ -175,15 +173,15 @@ long get_user_pages6(unsigned long start, unsigned long nr_pages, return __get_user_pages(current, current->mm, start, nr_pages, flags, pages, vmas, NULL); } -EXPORT_SYMBOL(get_user_pages6); +EXPORT_SYMBOL(get_user_pages); -long get_user_pages_locked6(unsigned long start, unsigned long nr_pages, +long get_user_pages_locked(unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages, int *locked) { - return get_user_pages6(start, nr_pages, write, force, pages, NULL); + return get_user_pages(start, nr_pages, write, force, pages, NULL); } -EXPORT_SYMBOL(get_user_pages_locked6); +EXPORT_SYMBOL(get_user_pages_locked); long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, @@ -199,13 +197,13 @@ long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, } EXPORT_SYMBOL(__get_user_pages_unlocked); -long get_user_pages_unlocked5(unsigned long start, unsigned long nr_pages, +long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages) { return __get_user_pages_unlocked(current, current->mm, start, nr_pages, write, force, pages, 0); } -EXPORT_SYMBOL(get_user_pages_unlocked5); +EXPORT_SYMBOL(get_user_pages_unlocked); /** * follow_pfn - look up PFN at a user virtual address @@ -1989,31 +1987,3 @@ static int __meminit init_admin_reserve(void) return 0; } subsys_initcall(init_admin_reserve); - -long get_user_pages8(struct task_struct *tsk, struct mm_struct *mm, - unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages, - struct vm_area_struct **vmas) -{ - return get_user_pages6(start, nr_pages, write, force, pages, vmas); -} -EXPORT_SYMBOL(get_user_pages8); - -long get_user_pages_locked8(struct task_struct *tsk, struct mm_struct *mm, - unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages, - int *locked) -{ - return get_user_pages_locked6(start, nr_pages, write, - force, pages, locked); -} -EXPORT_SYMBOL(get_user_pages_locked8); - -long get_user_pages_unlocked7(struct task_struct *tsk, struct mm_struct *mm, - unsigned long start, unsigned long nr_pages, - int write, int force, struct page **pages) -{ - return get_user_pages_unlocked5(start, nr_pages, write, force, pages); -} -EXPORT_SYMBOL(get_user_pages_unlocked7); - -- cgit v1.2.3 From 732dc97baec006c118bf49d52dd1c0b91b388497 Mon Sep 17 00:00:00 2001 From: Andreas Ziegler Date: Tue, 15 Mar 2016 12:16:55 +0100 Subject: ARC: Don't source drivers/pci/pcie/Kconfig ourselves Commit 5f8fc43217a0 ("PCI: Include pci/pcie/Kconfig directly from pci/Kconfig") in linux-next changed drivers/pci/Kconfig to include drivers/pci/pcie/Kconfig itself, so that architectures do not need to source both files themselves. ARC just recently gained PCI support through commit 6b3fb77998dd ("ARC: Add PCI support"), but this change was based on the old behaviour of the Kconfig files. This makes Kconfig now spit out the following warnings: drivers/pci/pcie/Kconfig:61:warning: choice value used outside its choice group drivers/pci/pcie/Kconfig:67:warning: choice value used outside its choice group drivers/pci/pcie/Kconfig:74:warning: choice value used outside its choice group This change updates the Kconfig file for ARC, dropping the now unnecessary 'source' statement, which makes the warning disappear. Signed-off-by: Andreas Ziegler Signed-off-by: Vineet Gupta --- arch/arc/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 208aae071b37..12d0284a46e5 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -593,7 +593,6 @@ config PCI_SYSCALL def_bool PCI source "drivers/pci/Kconfig" -source "drivers/pci/pcie/Kconfig" endmenu -- cgit v1.2.3 From e5e0a65cd20a7a892a87e6bd73bdc3d83726d725 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Mon, 28 Mar 2016 14:36:38 +0300 Subject: arc: Add our own implementation of fb_pgprotect() During mmaping of frame-buffer pages to user-space fb_protect() is called to set proper page settings. In case of ARC we need to mark pages that are mmaped to user as uncached because of 2 reasons: * Huge amount of data if passing through data cache will thrash cache a lot making cache almost useless for other less traffic hungry processes. * Data written by user in FB will be immediately available for hardware (such as PGU etc) without requirements to flush data cache regularly. Signed-off-by: Alexey Brodkin Cc: linux-snps-arc@lists.infradead.org Signed-off-by: Vineet Gupta --- arch/arc/include/asm/fb.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 arch/arc/include/asm/fb.h diff --git a/arch/arc/include/asm/fb.h b/arch/arc/include/asm/fb.h new file mode 100644 index 000000000000..bd3f68c9ddfc --- /dev/null +++ b/arch/arc/include/asm/fb.h @@ -0,0 +1,19 @@ +#ifndef _ASM_FB_H_ +#define _ASM_FB_H_ + +#include +#include +#include + +static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, + unsigned long off) +{ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +} + +static inline int fb_is_primary_device(struct fb_info *info) +{ + return 0; +} + +#endif /* _ASM_FB_H_ */ -- cgit v1.2.3 From 6dc97ee6d983cb4730a8d036344fa7b0a08760b0 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Wed, 6 Apr 2016 17:28:11 +0530 Subject: Revert "ARC: [plat-axs10x] add Ethernet PHY description in .dts" This reverts commit 667a490bdb6e27db0887d2ca515b907d6aa87118. This is needed to get ethernet(stmmac) working in 4.6-rc2 on axs103. 4.5 needed this fix, but apprently stmmac has gained some fixes which warrant reversal of this. Signed-off-by: Vineet Gupta --- arch/arc/boot/dts/axs10x_mb.dtsi | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi index ab5d5701e11d..44a578c10732 100644 --- a/arch/arc/boot/dts/axs10x_mb.dtsi +++ b/arch/arc/boot/dts/axs10x_mb.dtsi @@ -47,14 +47,6 @@ clocks = <&apbclk>; clock-names = "stmmaceth"; max-speed = <100>; - mdio0 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "snps,dwmac-mdio"; - phy1: ethernet-phy@1 { - reg = <1>; - }; - }; }; ehci@0x40000 { -- cgit v1.2.3 From 0dee6c82c2aa5342357dabd0e536a97f72039f0b Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Thu, 3 Mar 2016 20:01:48 +0300 Subject: ARC: [plat-axs103] Enable loop block devices As mentioned in LTP's README.ARC: ------------->8------------ Requirements for the environment * Linux must be built with support of loop block devices. Thus it's necessary to enable these Linux kernel options: CONFIG_BLK_DEV CONFIG_BLK_DEV_LOOP ------------->8------------ enabling loop block devices. That among other things lead to additional 10 fatal signals appearing during LTP run. Signed-off-by: Alexey Brodkin Signed-off-by: Vineet Gupta --- arch/arc/configs/axs103_defconfig | 1 + arch/arc/configs/axs103_smp_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig index f8b396c9aedb..491b3b5f22bd 100644 --- a/arch/arc/configs/axs103_defconfig +++ b/arch/arc/configs/axs103_defconfig @@ -42,6 +42,7 @@ CONFIG_DEVTMPFS=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_BLK_DEV_LOOP=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig index 56128ea2b748..b25ee73b2e79 100644 --- a/arch/arc/configs/axs103_smp_defconfig +++ b/arch/arc/configs/axs103_smp_defconfig @@ -43,6 +43,7 @@ CONFIG_DEVTMPFS=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_BLK_DEV_LOOP=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y -- cgit v1.2.3 From 0eb2c80c393d3b179244e6d485891ca8bd45aeba Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 21 Mar 2016 11:29:12 +0100 Subject: m68k: Wire up preadv2 and pwritev2 Signed-off-by: Geert Uytterhoeven --- arch/m68k/include/asm/unistd.h | 2 +- arch/m68k/include/uapi/asm/unistd.h | 2 ++ arch/m68k/kernel/syscalltable.S | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index bafaff6dcd7b..a857d82ec509 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -4,7 +4,7 @@ #include -#define NR_syscalls 377 +#define NR_syscalls 379 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT diff --git a/arch/m68k/include/uapi/asm/unistd.h b/arch/m68k/include/uapi/asm/unistd.h index 0ca729665f29..9fe674bf911f 100644 --- a/arch/m68k/include/uapi/asm/unistd.h +++ b/arch/m68k/include/uapi/asm/unistd.h @@ -382,5 +382,7 @@ #define __NR_membarrier 374 #define __NR_mlock2 375 #define __NR_copy_file_range 376 +#define __NR_preadv2 377 +#define __NR_pwritev2 378 #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 8bb94261ff97..d6fd6d9ced24 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S @@ -397,3 +397,5 @@ ENTRY(sys_call_table) .long sys_membarrier .long sys_mlock2 /* 375 */ .long sys_copy_file_range + .long sys_preadv2 + .long sys_pwritev2 -- cgit v1.2.3 From 7b8ba82ad4ada669c564ec8ccba9cadc6e8abfb1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 27 Mar 2016 11:11:09 +0200 Subject: m68k/defconfig: Update defconfigs for v4.6-rc2 Signed-off-by: Geert Uytterhoeven --- arch/m68k/configs/amiga_defconfig | 13 ++++++------- arch/m68k/configs/apollo_defconfig | 13 ++++++------- arch/m68k/configs/atari_defconfig | 13 ++++++------- arch/m68k/configs/bvme6000_defconfig | 13 ++++++------- arch/m68k/configs/hp300_defconfig | 13 ++++++------- arch/m68k/configs/mac_defconfig | 13 ++++++------- arch/m68k/configs/multi_defconfig | 13 ++++++------- arch/m68k/configs/mvme147_defconfig | 13 ++++++------- arch/m68k/configs/mvme16x_defconfig | 13 ++++++------- arch/m68k/configs/q40_defconfig | 13 ++++++------- arch/m68k/configs/sun3_defconfig | 13 ++++++------- arch/m68k/configs/sun3x_defconfig | 13 ++++++------- 12 files changed, 72 insertions(+), 84 deletions(-) diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index d1fc4796025e..3ee6976f6088 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-amiga" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -64,7 +63,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -285,7 +283,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -359,6 +359,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -452,6 +453,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -468,6 +470,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -549,6 +552,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -557,7 +561,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -565,12 +568,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -594,7 +594,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index 9bfe8be3658c..e96787ffcbce 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-apollo" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -62,7 +61,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -283,7 +281,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -341,6 +341,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -411,6 +412,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -427,6 +429,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -508,6 +511,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -516,7 +520,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -524,12 +527,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -553,7 +553,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index ebdcfae55580..083fe6beac14 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-atari" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -62,7 +61,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -283,7 +281,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -350,6 +350,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -432,6 +433,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -448,6 +450,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -529,6 +532,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -537,7 +541,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -545,12 +548,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -574,7 +574,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index 8acc65e54995..475130c06dcb 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-bvme6000" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -60,7 +59,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -281,7 +279,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -340,6 +340,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -403,6 +404,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -419,6 +421,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -500,6 +503,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -508,7 +512,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -516,12 +519,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -545,7 +545,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index 0c6a3d52b26e..4339658c200f 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-hp300" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -62,7 +61,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -283,7 +281,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -341,6 +341,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -413,6 +414,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -429,6 +431,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -510,6 +513,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -518,7 +522,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -526,12 +529,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -555,7 +555,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 12a8a6cb32f4..831cc8c3a2e2 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-mac" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -61,7 +60,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -285,7 +283,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -357,6 +357,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -435,6 +436,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -451,6 +453,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -532,6 +535,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -540,7 +544,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -548,12 +551,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -577,7 +577,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index 64ff2dcb34c8..6377afeb522b 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-multi" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -71,7 +70,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -295,7 +293,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -390,6 +390,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -515,6 +516,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -531,6 +533,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -612,6 +615,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -620,7 +624,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -628,12 +631,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -657,7 +657,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 07fc6abcfe0c..4304b3d56262 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-mvme147" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -59,7 +58,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -280,7 +278,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -339,6 +339,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -403,6 +404,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -419,6 +421,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -500,6 +503,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -508,7 +512,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -516,12 +519,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -545,7 +545,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 69903ded88f7..074bda4094ff 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-mvme16x" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -60,7 +59,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -281,7 +279,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -340,6 +340,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -403,6 +404,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -419,6 +421,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -500,6 +503,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -508,7 +512,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -516,12 +519,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -545,7 +545,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index bd8401686dde..07b9fa8d7f2e 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-q40" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -60,7 +59,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -281,7 +279,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -346,6 +346,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -426,6 +427,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -442,6 +444,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -523,6 +526,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -531,7 +535,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -539,12 +542,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -568,7 +568,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 5f9fb3ab9636..36e6fae02d45 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-sun3" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -57,7 +56,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -278,7 +276,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -337,6 +337,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -405,6 +406,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -421,6 +423,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -502,6 +505,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -509,7 +513,6 @@ CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -517,12 +520,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -546,7 +546,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index 5d1c674530e2..903acf929511 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-sun3x" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -57,7 +56,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -278,7 +276,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -337,6 +337,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -405,6 +406,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -421,6 +423,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -502,6 +505,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -510,7 +514,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -518,12 +521,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -547,7 +547,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m -- cgit v1.2.3 From ff76def3bd7e816fe0ca7f0840065c566a42ba2f Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 29 Mar 2016 11:05:16 +0200 Subject: netfilter: arp_tables: register table in initns arptables is broken since we didn't register the table anymore -- even 'arptables -L' fails. Fixes: b9e69e127397187b ("netfilter: xtables: don't hook tables by default") Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/ipv4/netfilter/arptable_filter.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index dd8c80dc32a2..8f8713b4388f 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c @@ -81,6 +81,12 @@ static int __init arptable_filter_init(void) return ret; } + ret = arptable_filter_table_init(&init_net); + if (ret) { + unregister_pernet_subsys(&arptable_filter_net_ops); + kfree(arpfilter_ops); + } + return ret; } -- cgit v1.2.3 From 303f551c8e8dfca4df4e01612f0f393c2e5744e4 Mon Sep 17 00:00:00 2001 From: Junwei Zhang Date: Wed, 6 Apr 2016 16:01:19 +0800 Subject: drm/amd/amdgpu: fix irq domain remove for tonga ih MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Junwei Zhang Reviewed-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index b6f7d7bff929..0f14199cf716 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c @@ -307,7 +307,7 @@ static int tonga_ih_sw_fini(void *handle) amdgpu_irq_fini(adev); amdgpu_ih_ring_fini(adev); - amdgpu_irq_add_domain(adev); + amdgpu_irq_remove_domain(adev); return 0; } -- cgit v1.2.3 From 3d8e15dd6de644736916c8ba012c1cc6b356d4ba Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 7 Apr 2016 17:21:43 +0200 Subject: KVM: new maintainer on the block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avi has kept Gleb busy enough, and Radim has been helping me for a while, so let's "reward" him with an entry in MAINTAINERS. Acked-by: Gleb Natapov Cc: Radim Krčmář Signed-off-by: Paolo Bonzini Signed-off-by: Radim Krčmář --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 40eb1dbe2ae5..7f9f4bda9d15 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6252,8 +6252,8 @@ S: Maintained F: tools/testing/selftests KERNEL VIRTUAL MACHINE (KVM) -M: Gleb Natapov M: Paolo Bonzini +M: Radim Krčmář L: kvm@vger.kernel.org W: http://www.linux-kvm.org T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git -- cgit v1.2.3 From 644c7e48cb59cfc6988ddc7bf3d3b1ba5fe7fa9d Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Wed, 30 Mar 2016 11:34:35 +0200 Subject: netfilter: nf_conntrack_tcp: Fix stack out of bounds when parsing TCP options Baozeng Ding reported a KASAN stack out of bounds issue - it uncovered that the TCP option parsing routines in netfilter TCP connection tracking could read one byte out of the buffer of the TCP options. Therefore in the patch we check that the available data length is large enough to parse both TCP option code and size. Reported-by: Baozeng Ding Tested-by: Baozeng Ding Signed-off-by: Jozsef Kadlecsik Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_tcp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 278f3b9356ef..7cc1d9c22a9f 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -410,6 +410,8 @@ static void tcp_options(const struct sk_buff *skb, length--; continue; default: + if (length < 2) + return; opsize=*ptr++; if (opsize < 2) /* "silly options" */ return; @@ -470,6 +472,8 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff, length--; continue; default: + if (length < 2) + return; opsize = *ptr++; if (opsize < 2) /* "silly options" */ return; -- cgit v1.2.3 From a61b37ead51488e321fe559a4edd0325c6d4c937 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 21 Mar 2016 20:12:20 +0800 Subject: mailbox: xgene-slimpro: Fix wrong test for devm_kzalloc devm_kzalloc() returns NULL on failure. Signed-off-by: Axel Lin Signed-off-by: Jassi Brar --- drivers/mailbox/mailbox-xgene-slimpro.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mailbox/mailbox-xgene-slimpro.c b/drivers/mailbox/mailbox-xgene-slimpro.c index bd07f39f0692..dd2afbca51c9 100644 --- a/drivers/mailbox/mailbox-xgene-slimpro.c +++ b/drivers/mailbox/mailbox-xgene-slimpro.c @@ -189,8 +189,8 @@ static int slimpro_mbox_probe(struct platform_device *pdev) int i; ctx = devm_kzalloc(&pdev->dev, sizeof(struct slimpro_mbox), GFP_KERNEL); - if (IS_ERR(ctx)) - return PTR_ERR(ctx); + if (!ctx) + return -ENOMEM; platform_set_drvdata(pdev, ctx); -- cgit v1.2.3 From c783e6fd7fe4d34f0231d0d8da36497404aa6d93 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 1 Apr 2016 17:53:05 -0500 Subject: ARM: OMAP: DRA7: wakeupgen: Skip SAR save for wakeupgen DRA7 has no SAR region for automated save and restore of wakeupgen, which does not make real since the SoC really does not do legacy OFF mode anymore. Further wakeupgen should never loose context in CSWR retention mode for MPU domain on DRA7 since that is the deepest state we will enter. So, just skip, instead of oopsing as follows while attemptint to enter suspend on BeagleBoard-X15. [ 55.589771] Unable to handle kernel paging request at virtual address 00002684 [ 55.589771] pgd = ec69c000 [...] [ 55.589771] [] (irq_notifier) from [] (notifier_call_chain+0x4c/0x8c) [ 55.589771] [] (notifier_call_chain) from [] (cpu_cluster_pm_enter+0x2c/0x78) [ 55.589771] [] (cpu_cluster_pm_enter) from [] (syscore_suspend+0xb8/0x31c) [ 55.589771] [] (syscore_suspend) from [] (suspend_devices_and_enter+0x308/0x9e4) [ 55.589771] [] (suspend_devices_and_enter) from [] (pm_suspend+0x640/0x75c) [ 55.589771] [] (pm_suspend) from [] (state_store+0x64/0xb8) [ 55.589771] [] (state_store) from [] (kernfs_fop_write+0xc0/0x1bc) [ 55.589771] [] (kernfs_fop_write) from [] (__vfs_write+0x1c/0xd8) [ 55.589771] [] (__vfs_write) from [] (vfs_write+0x90/0x16c) [ 55.589771] [] (vfs_write) from [] (SyS_write+0x44/0x9c) [ 55.589771] [] (SyS_write) from [] (ret_fast_syscall+0x0/0x1c) [...] Signed-off-by: Nishanth Menon Tested-by: Keerthy Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap-wakeupgen.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index f397bd6bd6e3..2c04f2741476 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -274,6 +274,10 @@ static inline void omap5_irq_save_context(void) */ static void irq_save_context(void) { + /* DRA7 has no SAR to save */ + if (soc_is_dra7xx()) + return; + if (!sar_base) sar_base = omap4_get_sar_ram_base(); @@ -290,6 +294,9 @@ static void irq_sar_clear(void) { u32 val; u32 offset = SAR_BACKUP_STATUS_OFFSET; + /* DRA7 has no SAR to save */ + if (soc_is_dra7xx()) + return; if (soc_is_omap54xx()) offset = OMAP5_SAR_BACKUP_STATUS_OFFSET; -- cgit v1.2.3 From ec490f6f600f93236f1ad439b9809de563343b2c Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 1 Apr 2016 17:53:06 -0500 Subject: ARM: OMAP: DRA7: Provide proper class to omap2_set_globals_tap When commit 06c2d368fc36 ("ARM: OMAP: DRA7: Make use of omap_revision information for soc_is* calls") introduced SoC check using omap_revision, it missed providing DRA7 as class for initializing the omap_version variable. Without doing this, soc_is_dra7xx() will fail and as a result, omap4_pm_init_early never initializes the dra7 erratum for CPU power state. This causes the suspend path to fail on DRA7 devices. Fixes: 06c2d368fc36 ("ARM: OMAP: DRA7: Make use of omap_revision information for soc_is* calls") Signed-off-by: Nishanth Menon Tested-by: Keerthy Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 3c87e40650cf..2b86b25bcb83 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -736,7 +736,8 @@ void __init omap5_init_late(void) #ifdef CONFIG_SOC_DRA7XX void __init dra7xx_init_early(void) { - omap2_set_globals_tap(-1, OMAP2_L4_IO_ADDRESS(DRA7XX_TAP_BASE)); + omap2_set_globals_tap(DRA7XX_CLASS, + OMAP2_L4_IO_ADDRESS(DRA7XX_TAP_BASE)); omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE)); omap2_control_base_init(); omap4_pm_init_early(); -- cgit v1.2.3 From eea08802f586acd6aef377d1b4a541821013cc0b Mon Sep 17 00:00:00 2001 From: Keerthy Date: Mon, 4 Apr 2016 11:07:15 +0530 Subject: ARM: dts: dra7: Correct clock tree for sys_32k_ck This is w.r.t J6/J6eco: 32clk is pseudo (erratum i856) - clock source. Errata i856 for the AM572x (DRA7xx) points out that the 32.768KHz external crystal is not enabled at power up. Instead the CPU falls back to using an emulation for the 32KHz clock which is SYSCLK1/610. SYSCLK1 is usually 20MHz on boards so far (which gives an emulated frequency of 32.786KHz) Modelling the same in device tree. Acked-by: Tero Kristo Signed-off-by: Keerthy Signed-off-by: Lokesh Vutla Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dra7xx-clocks.dtsi | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi index d0bae06b7eb7..ef2164a99d0f 100644 --- a/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi @@ -98,12 +98,20 @@ clock-frequency = <32768>; }; - sys_32k_ck: sys_32k_ck { + sys_clk32_crystal_ck: sys_clk32_crystal_ck { #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <32768>; }; + sys_clk32_pseudo_ck: sys_clk32_pseudo_ck { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sys_clkin1>; + clock-mult = <1>; + clock-div = <610>; + }; + virt_12000000_ck: virt_12000000_ck { #clock-cells = <0>; compatible = "fixed-clock"; @@ -2170,4 +2178,12 @@ ti,bit-shift = <22>; reg = <0x0558>; }; + + sys_32k_ck: sys_32k_ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&sys_clk32_crystal_ck>, <&sys_clk32_pseudo_ck>, <&sys_clk32_pseudo_ck>, <&sys_clk32_pseudo_ck>; + ti,bit-shift = <8>; + reg = <0x6c4>; + }; }; -- cgit v1.2.3 From 571afb4c8a4bbe88541364e7f6827340562f2736 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 1 Apr 2016 17:53:07 -0500 Subject: ARM: OMAP: Catch callers of revision information prior to it being populated omap_rev is used to detect various SoC types, however any misuse of the usage by invoking it earlier than it being populated will result in invalid results. Lets flag them as early as possible to prevent unintended side effects taking place. We get 0 if it is uninitialized and -1 when detection is done using device tree (as the case was for DRA7 as the case was prior to commit 06c2d368fc36 ("ARM: OMAP: DRA7: Make use of omap_revision information for soc_is* calls") Signed-off-by: Nishanth Menon Tested-by: Keerthy Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/id.c | 1 + arch/arm/mach-omap2/id.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c index 52de382fc804..bfabc065d331 100644 --- a/arch/arm/mach-omap1/id.c +++ b/arch/arm/mach-omap1/id.c @@ -65,6 +65,7 @@ static struct omap_id omap_ids[] __initdata = { unsigned int omap_rev(void) { + WARN_ON_ONCE(!omap_revision || omap_revision == -1); return omap_revision; } EXPORT_SYMBOL(omap_rev); diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index d85c24918c17..75fb6c006e86 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -46,6 +46,7 @@ u32 omap_features; unsigned int omap_rev(void) { + WARN_ON_ONCE(!omap_revision || omap_revision == -1); return omap_revision; } EXPORT_SYMBOL(omap_rev); -- cgit v1.2.3 From 49dd48dafec64fe99bdcc518092c5db4bffaa8a9 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 10 Apr 2016 02:28:41 +0300 Subject: sh_eth: re-enable-E-MAC interrupts in sh_eth_set_ringparam() The E-MAC interrupts are left disabled when the ring parameters are changed via 'ethtool'. In order to fix this, it's enough to call sh_eth_dev_init() with 'true' instead of 'false' for the second argument (which conveniently allows us to remove the following code re-enabling E-DMAC interrupts and reception). Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 004e2d7560fd..ceea74cc2229 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2194,17 +2194,13 @@ static int sh_eth_set_ringparam(struct net_device *ndev, __func__); return ret; } - ret = sh_eth_dev_init(ndev, false); + ret = sh_eth_dev_init(ndev, true); if (ret < 0) { netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", __func__); return ret; } - mdp->irq_enabled = true; - sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); - /* Setting the Rx mode will start the Rx process. */ - sh_eth_write(ndev, EDRRR_R, EDRRR); netif_device_attach(ndev); } -- cgit v1.2.3 From ffb810563c0c049872a504978e06c8892104fb6c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 10 Apr 2016 05:59:10 +0200 Subject: intel_pstate: Avoid getting stuck in high P-states when idle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Jörg Otte reports that commit a4675fbc4a7a (cpufreq: intel_pstate: Replace timers with utilization update callbacks) caused the CPUs in his Haswell-based system to stay in the very high frequency region even if the system is completely idle. That turns out to be an existing problem in the intel_pstate driver's P-state selection algorithm for Core processors. Namely, all decisions made by that algorithm are based on the average frequency of the CPU between sampling events and on the P-state requested on the last invocation, so it may get stuck at a very hight frequency even if the utilization of the CPU is very low (in fact, it may get stuck in a inadequate P-state regardless of the CPU utilization). The only way to kick it out of that limbo is a sufficiently long idle period (3 times longer than the prescribed sampling interval), but if that doesn't happen often enough (eg. due to a timing change like after the above commit), the P-state of the CPU may be inadequate pretty much all the time. To address the most egregious manifestations of that issue, reset the core_busy value used to determine the next P-state to request if the utilization of the CPU, determined with the help of the MPERF feedback register and the TSC, is below 1%. Link: https://bugzilla.kernel.org/show_bug.cgi?id=115771 Reported-and-tested-by: Jörg Otte Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 8b5a415ee14a..30fe323c4551 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1130,6 +1130,10 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu) sample_ratio = div_fp(int_tofp(pid_params.sample_rate_ns), int_tofp(duration_ns)); core_busy = mul_fp(core_busy, sample_ratio); + } else { + sample_ratio = div_fp(100 * cpu->sample.mperf, cpu->sample.tsc); + if (sample_ratio < int_tofp(1)) + core_busy = 0; } cpu->sample.busy_scaled = core_busy; -- cgit v1.2.3 From 1cbabcb9807e31e87ef3a12af76ea025ceb582d3 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Tue, 5 Apr 2016 16:44:12 -0500 Subject: ARM: DRA7: clockdomain: Implement timer workaround for errata i874 Errata Title: i874: TIMER5/6/7/8 interrupts not propagated Description: When TIMER5, TIMER6, TIMER7, or TIMER8 clocks are enabled (CM_IPU_TIMER5/6/7/8_CLKCTRL[0:1]MODULEMODE=0x2:ENABLE) and the CD-IPU is in HW_AUTO mode (CM_IPU_CLKSTCTRL[0:1]CLKTRCTRL=0x3:HW_AUTO) the corresponding TIMER will continue counting, but enabled interrupts will not be propagated to the destinations (MPU, DSP, etc) in the SoC until the TIMER registers are accessed from the CPUs (MPU, DSP etc.). This can result in missed timer interrupts. Workaround: In order for TIMER5/6/7/8 interrupts to be propagated and serviced correctly the CD_IPU domain should be set to SW_WKUP mode (CM_IPU_CLKSTCTRL[0:1]CLKTRCTRL=0x2:SW_WKUP). The above workaround is achieved by switching the IPU clockdomain flags from HWSUP_SWSUP to SWSUP only. Signed-off-by: Keerthy Signed-off-by: Suman Anna Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clockdomains7xx_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/clockdomains7xx_data.c b/arch/arm/mach-omap2/clockdomains7xx_data.c index 7581e036bda6..ef9ed36e8a61 100644 --- a/arch/arm/mach-omap2/clockdomains7xx_data.c +++ b/arch/arm/mach-omap2/clockdomains7xx_data.c @@ -461,7 +461,7 @@ static struct clockdomain ipu_7xx_clkdm = { .cm_inst = DRA7XX_CM_CORE_AON_IPU_INST, .clkdm_offs = DRA7XX_CM_CORE_AON_IPU_IPU_CDOFFS, .dep_bit = DRA7XX_IPU_STATDEP_SHIFT, - .flags = CLKDM_CAN_HWSUP_SWSUP, + .flags = CLKDM_CAN_SWSUP, }; static struct clockdomain mpu1_7xx_clkdm = { -- cgit v1.2.3 From 7a98205deebfff9fc96f90d9e7b1a334b0bd3e2b Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Fri, 25 Mar 2016 21:19:35 +0800 Subject: KVM: MMU: fix permission_fault() kvm-unit-tests complained about the PFEC is not set properly, e.g,: test pte.rw pte.d pte.nx pde.p pde.rw pde.pse user fetch: FAIL: error code 15 expected 5 Dump mapping: address: 0x123400000000 ------L4: 3e95007 ------L3: 3e96007 ------L2: 2000083 It's caused by the reason that PFEC returned to guest is copied from the PFEC triggered by shadow page table This patch fixes it and makes the logic of updating errcode more clean Signed-off-by: Xiao Guangrong [Do not assume pfec.p=1. - Paolo] Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu.h | 9 ++++----- arch/x86/kvm/paging_tmpl.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index b70df72e2b33..66b33b96a31b 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -173,10 +173,9 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, int index = (pfec >> 1) + (smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1)); bool fault = (mmu->permissions[index] >> pte_access) & 1; + u32 errcode = PFERR_PRESENT_MASK; WARN_ON(pfec & (PFERR_PK_MASK | PFERR_RSVD_MASK)); - pfec |= PFERR_PRESENT_MASK; - if (unlikely(mmu->pkru_mask)) { u32 pkru_bits, offset; @@ -189,15 +188,15 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, pkru_bits = (kvm_read_pkru(vcpu) >> (pte_pkey * 2)) & 3; /* clear present bit, replace PFEC.RSVD with ACC_USER_MASK. */ - offset = pfec - 1 + + offset = (pfec & ~1) + ((pte_access & PT_USER_MASK) << (PFERR_RSVD_BIT - PT_USER_SHIFT)); pkru_bits &= mmu->pkru_mask >> offset; - pfec |= -pkru_bits & PFERR_PK_MASK; + errcode |= -pkru_bits & PFERR_PK_MASK; fault |= (pkru_bits != 0); } - return -(uint32_t)fault & pfec; + return -(u32)fault & errcode; } void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm); diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 1d971c7553c3..bc019f70e0b6 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -360,7 +360,7 @@ retry_walk: goto error; if (unlikely(is_rsvd_bits_set(mmu, pte, walker->level))) { - errcode |= PFERR_RSVD_MASK | PFERR_PRESENT_MASK; + errcode = PFERR_RSVD_MASK | PFERR_PRESENT_MASK; goto error; } -- cgit v1.2.3 From fc5b7f3bf1e1414bd4e91db6918c85ace0c873a5 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Wed, 30 Mar 2016 12:24:47 -0700 Subject: kvm: x86: do not leak guest xcr0 into host interrupt handlers An interrupt handler that uses the fpu can kill a KVM VM, if it runs under the following conditions: - the guest's xcr0 register is loaded on the cpu - the guest's fpu context is not loaded - the host is using eagerfpu Note that the guest's xcr0 register and fpu context are not loaded as part of the atomic world switch into "guest mode". They are loaded by KVM while the cpu is still in "host mode". Usage of the fpu in interrupt context is gated by irq_fpu_usable(). The interrupt handler will look something like this: if (irq_fpu_usable()) { kernel_fpu_begin(); [... code that uses the fpu ...] kernel_fpu_end(); } As long as the guest's fpu is not loaded and the host is using eager fpu, irq_fpu_usable() returns true (interrupted_kernel_fpu_idle() returns true). The interrupt handler proceeds to use the fpu with the guest's xcr0 live. kernel_fpu_begin() saves the current fpu context. If this uses XSAVE[OPT], it may leave the xsave area in an undesirable state. According to the SDM, during XSAVE bit i of XSTATE_BV is not modified if bit i is 0 in xcr0. So it's possible that XSTATE_BV[i] == 1 and xcr0[i] == 0 following an XSAVE. kernel_fpu_end() restores the fpu context. Now if any bit i in XSTATE_BV == 1 while xcr0[i] == 0, XRSTOR generates a #GP. The fault is trapped and SIGSEGV is delivered to the current process. Only pre-4.2 kernels appear to be vulnerable to this sequence of events. Commit 653f52c ("kvm,x86: load guest FPU context more eagerly") from 4.2 forces the guest's fpu to always be loaded on eagerfpu hosts. This patch fixes the bug by keeping the host's xcr0 loaded outside of the interrupts-disabled region where KVM switches into guest mode. Cc: stable@vger.kernel.org Suggested-by: Andy Lutomirski Signed-off-by: David Matlack [Move load after goto cancel_injection. - Paolo] Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0a2c70e43bc8..9b7798c7b210 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -700,7 +700,6 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) if ((xcr0 & XFEATURE_MASK_AVX512) != XFEATURE_MASK_AVX512) return 1; } - kvm_put_guest_xcr0(vcpu); vcpu->arch.xcr0 = xcr0; if ((xcr0 ^ old_xcr0) & XFEATURE_MASK_EXTEND) @@ -6590,8 +6589,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) kvm_x86_ops->prepare_guest_switch(vcpu); if (vcpu->fpu_active) kvm_load_guest_fpu(vcpu); - kvm_load_guest_xcr0(vcpu); - vcpu->mode = IN_GUEST_MODE; srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); @@ -6618,6 +6615,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) goto cancel_injection; } + kvm_load_guest_xcr0(vcpu); + if (req_immediate_exit) smp_send_reschedule(vcpu->cpu); @@ -6667,6 +6666,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) vcpu->mode = OUTSIDE_GUEST_MODE; smp_wmb(); + kvm_put_guest_xcr0(vcpu); + /* Interrupt is enabled by handle_external_intr() */ kvm_x86_ops->handle_external_intr(vcpu); @@ -7314,7 +7315,6 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) * and assume host would use all available bits. * Guest xcr0 would be loaded later. */ - kvm_put_guest_xcr0(vcpu); vcpu->guest_fpu_loaded = 1; __kernel_fpu_begin(); __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state); @@ -7323,8 +7323,6 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) { - kvm_put_guest_xcr0(vcpu); - if (!vcpu->guest_fpu_loaded) { vcpu->fpu_counter = 0; return; -- cgit v1.2.3 From 316314cae15fb0e3869b76b468f59a0c83ac3d4e Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 21 Mar 2016 12:33:00 +0100 Subject: KVM: x86: mask CPUID(0xD,0x1).EAX against host value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures that the guest doesn't see XSAVE extensions (e.g. xgetbv1 or xsavec) that the host lacks. Cc: stable@vger.kernel.org Reviewed-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/kvm/cpuid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 8efb839948e5..bbbaa802d13e 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -534,6 +534,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, do_cpuid_1_ent(&entry[i], function, idx); if (idx == 1) { entry[i].eax &= kvm_cpuid_D_1_eax_x86_features; + cpuid_mask(&entry[i].eax, CPUID_D_1_EAX); entry[i].ebx = 0; if (entry[i].eax & (F(XSAVES)|F(XSAVEC))) entry[i].ebx = -- cgit v1.2.3 From 2763ee644809820fb1b741f1e7dd779038092324 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Thu, 7 Apr 2016 05:26:26 +1000 Subject: m68k/gpio: remove arch specific sysfs bus device The ColdFire architecture specific gpio support code registers a sysfs bus device named "gpio". This clashes with the new generic API device added in commit 3c702e99 ("gpio: add a userspace chardev ABI for GPIOs"). The old ColdFire sysfs gpio device was never used for anything specific, and no links or other nodes were created under it. The new API sysfs gpio device has all the same default sysfs links (device, drivers, etc) and they are properly populated. Remove the old ColdFire sysfs gpio registration. Signed-off-by: Greg Ungerer Acked-by: Linus Walleij --- arch/m68k/coldfire/gpio.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/arch/m68k/coldfire/gpio.c b/arch/m68k/coldfire/gpio.c index 8832083e1cb8..b515809be2b9 100644 --- a/arch/m68k/coldfire/gpio.c +++ b/arch/m68k/coldfire/gpio.c @@ -158,11 +158,6 @@ static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset) return -EINVAL; } -static struct bus_type mcfgpio_subsys = { - .name = "gpio", - .dev_name = "gpio", -}; - static struct gpio_chip mcfgpio_chip = { .label = "mcfgpio", .request = mcfgpio_request, @@ -178,8 +173,7 @@ static struct gpio_chip mcfgpio_chip = { static int __init mcfgpio_sysinit(void) { - gpiochip_add_data(&mcfgpio_chip, NULL); - return subsys_system_register(&mcfgpio_subsys, NULL); + return gpiochip_add_data(&mcfgpio_chip, NULL); } core_initcall(mcfgpio_sysinit); -- cgit v1.2.3 From ba6f5e33bdbb9ed2014b778fbbaecf20060ca989 Mon Sep 17 00:00:00 2001 From: Marcelo Ricardo Leitner Date: Wed, 6 Apr 2016 15:15:19 -0300 Subject: sctp: avoid refreshing heartbeat timer too often Currently on high rate SCTP streams the heartbeat timer refresh can consume quite a lot of resources as timer updates are costly and it contains a random factor, which a) is also costly and b) invalidates mod_timer() optimization for not editing a timer to the same value. It may even cause the timer to be slightly advanced, for no good reason. As suggested by David Laight this patch now removes this timer update from hot path by leaving the timer on and re-evaluating upon its expiration if the heartbeat is still needed or not, similarly to what is done for TCP. If it's not needed anymore the timer is re-scheduled to the new timeout, considering the time already elapsed. For this, we now record the last tx timestamp per transport, updated in the same spots as hb timer was restarted on tx. Also split up sctp_transport_reset_timers into sctp_transport_reset_t3_rtx and sctp_transport_reset_hb_timer, so we can re-arm T3 without re-arming the heartbeat one. On loopback with MTU of 65535 and data chunks with 1636, so that we have a considerable amount of chunks without stressing system calls, netperf -t SCTP_STREAM -l 30, perf looked like this before: Samples: 103K of event 'cpu-clock', Event count (approx.): 25833000000 Overhead Command Shared Object Symbol + 6,15% netperf [kernel.vmlinux] [k] copy_user_enhanced_fast_string - 5,43% netperf [kernel.vmlinux] [k] _raw_write_unlock_irqrestore - _raw_write_unlock_irqrestore - 96,54% _raw_spin_unlock_irqrestore - 36,14% mod_timer + 97,24% sctp_transport_reset_timers + 2,76% sctp_do_sm + 33,65% __wake_up_sync_key + 28,77% sctp_ulpq_tail_event + 1,40% del_timer - 1,84% mod_timer + 99,03% sctp_transport_reset_timers + 0,97% sctp_do_sm + 1,50% sctp_ulpq_tail_event And after this patch, now with netperf -l 60: Samples: 230K of event 'cpu-clock', Event count (approx.): 57707250000 Overhead Command Shared Object Symbol + 5,65% netperf [kernel.vmlinux] [k] memcpy_erms + 5,59% netperf [kernel.vmlinux] [k] copy_user_enhanced_fast_string - 5,05% netperf [kernel.vmlinux] [k] _raw_spin_unlock_irqrestore - _raw_spin_unlock_irqrestore + 49,89% __wake_up_sync_key + 45,68% sctp_ulpq_tail_event - 2,85% mod_timer + 76,51% sctp_transport_reset_t3_rtx + 23,49% sctp_do_sm + 1,55% del_timer + 2,50% netperf [sctp] [k] sctp_datamsg_from_user + 2,26% netperf [sctp] [k] sctp_sendmsg Throughput-wise, from 6800mbps without the patch to 7050mbps with it, ~3.7%. Signed-off-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller --- include/net/sctp/structs.h | 8 +++++++- net/sctp/outqueue.c | 15 ++++++++++----- net/sctp/sm_make_chunk.c | 3 +-- net/sctp/sm_sideeffect.c | 36 ++++++++++++++++-------------------- net/sctp/transport.c | 19 +++++++++++++------ 5 files changed, 47 insertions(+), 34 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 6df1ce7a411c..5a404c354f4c 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -847,6 +847,11 @@ struct sctp_transport { */ ktime_t last_time_heard; + /* When was the last time that we sent a chunk using this + * transport? We use this to check for idle transports + */ + unsigned long last_time_sent; + /* Last time(in jiffies) when cwnd is reduced due to the congestion * indication based on ECNE chunk. */ @@ -952,7 +957,8 @@ void sctp_transport_route(struct sctp_transport *, union sctp_addr *, struct sctp_sock *); void sctp_transport_pmtu(struct sctp_transport *, struct sock *sk); void sctp_transport_free(struct sctp_transport *); -void sctp_transport_reset_timers(struct sctp_transport *); +void sctp_transport_reset_t3_rtx(struct sctp_transport *); +void sctp_transport_reset_hb_timer(struct sctp_transport *); int sctp_transport_hold(struct sctp_transport *); void sctp_transport_put(struct sctp_transport *); void sctp_transport_update_rto(struct sctp_transport *, __u32); diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 8d3d3625130e..084718f9b3da 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -866,8 +866,10 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) * sender MUST assure that at least one T3-rtx * timer is running. */ - if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) - sctp_transport_reset_timers(transport); + if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) { + sctp_transport_reset_t3_rtx(transport); + transport->last_time_sent = jiffies; + } } break; @@ -924,8 +926,10 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) error = sctp_outq_flush_rtx(q, packet, rtx_timeout, &start_timer); - if (start_timer) - sctp_transport_reset_timers(transport); + if (start_timer) { + sctp_transport_reset_t3_rtx(transport); + transport->last_time_sent = jiffies; + } /* This can happen on COOKIE-ECHO resend. Only * one chunk can get bundled with a COOKIE-ECHO. @@ -1062,7 +1066,8 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) list_add_tail(&chunk->transmitted_list, &transport->transmitted); - sctp_transport_reset_timers(transport); + sctp_transport_reset_t3_rtx(transport); + transport->last_time_sent = jiffies; /* Only let one DATA chunk get bundled with a * COOKIE-ECHO chunk. diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 7f0bf798205b..56f364d8f932 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -3080,8 +3080,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, return SCTP_ERROR_RSRC_LOW; /* Start the heartbeat timer. */ - if (!mod_timer(&peer->hb_timer, sctp_transport_timeout(peer))) - sctp_transport_hold(peer); + sctp_transport_reset_hb_timer(peer); asoc->new_transport = peer; break; case SCTP_PARAM_DEL_IP: diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 7fe56d0acabf..41b081a64752 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -69,8 +69,6 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, sctp_cmd_seq_t *commands, gfp_t gfp); -static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds, - struct sctp_transport *t); /******************************************************************** * Helper functions ********************************************************************/ @@ -367,6 +365,7 @@ void sctp_generate_heartbeat_event(unsigned long data) struct sctp_association *asoc = transport->asoc; struct sock *sk = asoc->base.sk; struct net *net = sock_net(sk); + u32 elapsed, timeout; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -378,6 +377,16 @@ void sctp_generate_heartbeat_event(unsigned long data) goto out_unlock; } + /* Check if we should still send the heartbeat or reschedule */ + elapsed = jiffies - transport->last_time_sent; + timeout = sctp_transport_timeout(transport); + if (elapsed < timeout) { + elapsed = timeout - elapsed; + if (!mod_timer(&transport->hb_timer, jiffies + elapsed)) + sctp_transport_hold(transport); + goto out_unlock; + } + error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT, SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_HEARTBEAT), asoc->state, asoc->ep, asoc, @@ -507,7 +516,7 @@ static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands, 0); /* Update the hb timer to resend a heartbeat every rto */ - sctp_cmd_hb_timer_update(commands, transport); + sctp_transport_reset_hb_timer(transport); } if (transport->state != SCTP_INACTIVE && @@ -634,11 +643,8 @@ static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *cmds, * hold a reference on the transport to make sure none of * the needed data structures go away. */ - list_for_each_entry(t, &asoc->peer.transport_addr_list, transports) { - - if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) - sctp_transport_hold(t); - } + list_for_each_entry(t, &asoc->peer.transport_addr_list, transports) + sctp_transport_reset_hb_timer(t); } static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *cmds, @@ -669,15 +675,6 @@ static void sctp_cmd_t3_rtx_timers_stop(sctp_cmd_seq_t *cmds, } -/* Helper function to update the heartbeat timer. */ -static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds, - struct sctp_transport *t) -{ - /* Update the heartbeat timer. */ - if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) - sctp_transport_hold(t); -} - /* Helper function to handle the reception of an HEARTBEAT ACK. */ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, struct sctp_association *asoc, @@ -742,8 +739,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at)); /* Update the heartbeat timer. */ - if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) - sctp_transport_hold(t); + sctp_transport_reset_hb_timer(t); if (was_unconfirmed && asoc->peer.transport_count == 1) sctp_transport_immediate_rtx(t); @@ -1614,7 +1610,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, case SCTP_CMD_HB_TIMER_UPDATE: t = cmd->obj.transport; - sctp_cmd_hb_timer_update(commands, t); + sctp_transport_reset_hb_timer(t); break; case SCTP_CMD_HB_TIMERS_STOP: diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 9b6b48c7524e..81b86678be4d 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -183,7 +183,7 @@ static void sctp_transport_destroy(struct sctp_transport *transport) /* Start T3_rtx timer if it is not already running and update the heartbeat * timer. This routine is called every time a DATA chunk is sent. */ -void sctp_transport_reset_timers(struct sctp_transport *transport) +void sctp_transport_reset_t3_rtx(struct sctp_transport *transport) { /* RFC 2960 6.3.2 Retransmission Timer Rules * @@ -197,11 +197,18 @@ void sctp_transport_reset_timers(struct sctp_transport *transport) if (!mod_timer(&transport->T3_rtx_timer, jiffies + transport->rto)) sctp_transport_hold(transport); +} + +void sctp_transport_reset_hb_timer(struct sctp_transport *transport) +{ + unsigned long expires; /* When a data chunk is sent, reset the heartbeat interval. */ - if (!mod_timer(&transport->hb_timer, - sctp_transport_timeout(transport))) - sctp_transport_hold(transport); + expires = jiffies + sctp_transport_timeout(transport); + if (time_before(transport->hb_timer.expires, expires) && + !mod_timer(&transport->hb_timer, + expires + prandom_u32_max(transport->rto))) + sctp_transport_hold(transport); } /* This transport has been assigned to an association. @@ -595,13 +602,13 @@ void sctp_transport_burst_reset(struct sctp_transport *t) unsigned long sctp_transport_timeout(struct sctp_transport *trans) { /* RTO + timer slack +/- 50% of RTO */ - unsigned long timeout = (trans->rto >> 1) + prandom_u32_max(trans->rto); + unsigned long timeout = trans->rto >> 1; if (trans->state != SCTP_UNCONFIRMED && trans->state != SCTP_PF) timeout += trans->hbinterval; - return timeout + jiffies; + return timeout; } /* Reset transport variables to their initial values */ -- cgit v1.2.3 From a36a0d4008488fa545c74445d69eaf56377d5d4e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Apr 2016 23:01:30 -0400 Subject: decnet: Do not build routes to devices without decnet private data. In particular, make sure we check for decnet private presence for loopback devices. Signed-off-by: David S. Miller --- net/decnet/dn_route.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 607a14f20d88..b1dc096d22f8 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1034,10 +1034,13 @@ source_ok: if (!fld.daddr) { fld.daddr = fld.saddr; - err = -EADDRNOTAVAIL; if (dev_out) dev_put(dev_out); + err = -EINVAL; dev_out = init_net.loopback_dev; + if (!dev_out->dn_ptr) + goto out; + err = -EADDRNOTAVAIL; dev_hold(dev_out); if (!fld.daddr) { fld.daddr = @@ -1110,6 +1113,8 @@ source_ok: if (dev_out == NULL) goto out; dn_db = rcu_dereference_raw(dev_out->dn_ptr); + if (!dn_db) + goto e_inval; /* Possible improvement - check all devices for local addr */ if (dn_dev_islocal(dev_out, fld.daddr)) { dev_put(dev_out); @@ -1151,6 +1156,8 @@ select_source: dev_put(dev_out); dev_out = init_net.loopback_dev; dev_hold(dev_out); + if (!dev_out->dn_ptr) + goto e_inval; fld.flowidn_oif = dev_out->ifindex; if (res.fi) dn_fib_info_put(res.fi); -- cgit v1.2.3 From e27260203912b40751fa353d009eaa5a642c739f Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Thu, 7 Apr 2016 09:31:38 +0200 Subject: netlink: don't send NETLINK_URELEASE for unbound sockets All existing users of NETLINK_URELEASE use it to clean up resources that were previously allocated to a socket via some command. As a result, no users require getting this notification for unbound sockets. Sending it for unbound sockets, however, is a problem because any user (including unprivileged users) can create a socket that uses the same ID as an existing socket. Binding this new socket will fail, but if the NETLINK_URELEASE notification is generated for such sockets, the users thereof will be tricked into thinking the socket that they allocated the resources for is closed. In the nl80211 case, this will cause destruction of virtual interfaces that still belong to an existing hostapd process; this is the case that Dmitry noticed. In the NFC case, it will cause a poll abort. In the case of netlink log/queue it will cause them to stop reporting events, as if NFULNL_CFG_CMD_UNBIND/NFQNL_CFG_CMD_UNBIND had been called. Fix this problem by checking that the socket is bound before generating the NETLINK_URELEASE notification. Cc: stable@vger.kernel.org Signed-off-by: Dmitry Ivanov Signed-off-by: Johannes Berg Signed-off-by: David S. Miller --- net/netlink/af_netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 215fc08c02ab..330ebd600f25 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -688,7 +688,7 @@ static int netlink_release(struct socket *sock) skb_queue_purge(&sk->sk_write_queue); - if (nlk->portid) { + if (nlk->portid && nlk->bound) { struct netlink_notify n = { .net = sock_net(sk), .protocol = sk->sk_protocol, -- cgit v1.2.3 From 734e00fa02eff5003827abc06a7ebf9449349109 Mon Sep 17 00:00:00 2001 From: Phil Reid Date: Thu, 7 Apr 2016 15:55:35 +0800 Subject: net: stmmac: socfgpa: Ensure emac bit set in System Manger for PTP When using the PTP fpga to hps clock source for the stmmac module the appropriate bit in the System Manager FPGA Interface Group register needs to be set. This is not set by the bootloader setup when the HPS emac pins are being for this emac module. This allows the PTP clock to be sourced from the FPGA and also connects the PTP pps and ext trig signals to the stmmac PTP hardware. Patch proposed by Phil Collins. Signed-off-by: Phil Reid Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index f0d797ab74d8..44022b1845ce 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -34,6 +34,9 @@ #define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x00000003 #define SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK 0x00000010 +#define SYSMGR_FPGAGRP_MODULE_REG 0x00000028 +#define SYSMGR_FPGAGRP_MODULE_EMAC 0x00000004 + #define EMAC_SPLITTER_CTRL_REG 0x0 #define EMAC_SPLITTER_CTRL_SPEED_MASK 0x3 #define EMAC_SPLITTER_CTRL_SPEED_10 0x2 @@ -148,7 +151,7 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac) int phymode = dwmac->interface; u32 reg_offset = dwmac->reg_offset; u32 reg_shift = dwmac->reg_shift; - u32 ctrl, val; + u32 ctrl, val, module; switch (phymode) { case PHY_INTERFACE_MODE_RGMII: @@ -175,12 +178,19 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac) ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift); ctrl |= val << reg_shift; - if (dwmac->f2h_ptp_ref_clk) + if (dwmac->f2h_ptp_ref_clk) { ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2); - else + regmap_read(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG, + &module); + module |= (SYSMGR_FPGAGRP_MODULE_EMAC << (reg_shift / 2)); + regmap_write(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG, + module); + } else { ctrl &= ~(SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2)); + } regmap_write(sys_mgr_base_addr, reg_offset, ctrl); + return 0; } -- cgit v1.2.3 From dc5027a72369f4979a48d628ddebeeb974b7eb37 Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Mon, 11 Apr 2016 09:25:52 -0400 Subject: ALSA: sscape: Use correct format identifier for size_t The 'size' member of a struct firmware is passed to snd_printk with a respective format string using the %d identifier. The 'size' member is of type size_t, but format identifier %d indicates a signed int data type. This patch replaces the %d format identifier with the correct %zu format identifier for size_t data types. Signed-off-by: William Breathitt Gray Signed-off-by: Takashi Iwai --- sound/isa/sscape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 7b248cdf06e2..fdcfa29e2205 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c @@ -591,7 +591,7 @@ static int sscape_upload_microcode(struct snd_card *card, int version) } err = upload_dma_data(sscape, init_fw->data, init_fw->size); if (err == 0) - snd_printk(KERN_INFO "sscape: MIDI firmware loaded %d KBs\n", + snd_printk(KERN_INFO "sscape: MIDI firmware loaded %zu KBs\n", init_fw->size >> 10); release_firmware(init_fw); -- cgit v1.2.3 From e3156048346c28c695f5cf9db67a8cf88c90f947 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 8 Apr 2016 15:12:24 +0200 Subject: iommu/amd: Fix checking of pci dma aliases Commit 61289cb ('iommu/amd: Remove old alias handling code') removed the old alias handling code from the AMD IOMMU driver because this is now handled by the IOMMU core code. But this also removed the handling of PCI aliases, which is not handled by the core code. This caused issues with PCI devices that have hidden PCIe-to-PCI bridges that rewrite the request-id. Fix this bug by re-introducing some of the removed functions from commit 61289cbaf6c8 and add a alias field 'struct iommu_dev_data'. This field carrys the return value of the get_alias() function and uses that instead of the amd_iommu_alias_table[] array in the code. Fixes: 61289cbaf6c8 ('iommu/amd: Remove old alias handling code') Cc: stable@vger.kernel.org # v4.4+ Tested-by: Tomasz Golinski Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 87 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 11 deletions(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 374c129219ef..5efadad4615b 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -92,6 +92,7 @@ struct iommu_dev_data { struct list_head dev_data_list; /* For global dev_data_list */ struct protection_domain *domain; /* Domain the device is bound to */ u16 devid; /* PCI Device ID */ + u16 alias; /* Alias Device ID */ bool iommu_v2; /* Device can make use of IOMMUv2 */ bool passthrough; /* Device is identity mapped */ struct { @@ -166,6 +167,13 @@ static struct protection_domain *to_pdomain(struct iommu_domain *dom) return container_of(dom, struct protection_domain, domain); } +static inline u16 get_device_id(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + return PCI_DEVID(pdev->bus->number, pdev->devfn); +} + static struct iommu_dev_data *alloc_dev_data(u16 devid) { struct iommu_dev_data *dev_data; @@ -203,6 +211,68 @@ out_unlock: return dev_data; } +static int __last_alias(struct pci_dev *pdev, u16 alias, void *data) +{ + *(u16 *)data = alias; + return 0; +} + +static u16 get_alias(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + u16 devid, ivrs_alias, pci_alias; + + devid = get_device_id(dev); + ivrs_alias = amd_iommu_alias_table[devid]; + pci_for_each_dma_alias(pdev, __last_alias, &pci_alias); + + if (ivrs_alias == pci_alias) + return ivrs_alias; + + /* + * DMA alias showdown + * + * The IVRS is fairly reliable in telling us about aliases, but it + * can't know about every screwy device. If we don't have an IVRS + * reported alias, use the PCI reported alias. In that case we may + * still need to initialize the rlookup and dev_table entries if the + * alias is to a non-existent device. + */ + if (ivrs_alias == devid) { + if (!amd_iommu_rlookup_table[pci_alias]) { + amd_iommu_rlookup_table[pci_alias] = + amd_iommu_rlookup_table[devid]; + memcpy(amd_iommu_dev_table[pci_alias].data, + amd_iommu_dev_table[devid].data, + sizeof(amd_iommu_dev_table[pci_alias].data)); + } + + return pci_alias; + } + + pr_info("AMD-Vi: Using IVRS reported alias %02x:%02x.%d " + "for device %s[%04x:%04x], kernel reported alias " + "%02x:%02x.%d\n", PCI_BUS_NUM(ivrs_alias), PCI_SLOT(ivrs_alias), + PCI_FUNC(ivrs_alias), dev_name(dev), pdev->vendor, pdev->device, + PCI_BUS_NUM(pci_alias), PCI_SLOT(pci_alias), + PCI_FUNC(pci_alias)); + + /* + * If we don't have a PCI DMA alias and the IVRS alias is on the same + * bus, then the IVRS table may know about a quirk that we don't. + */ + if (pci_alias == devid && + PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) { + pdev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN; + pdev->dma_alias_devfn = ivrs_alias & 0xff; + pr_info("AMD-Vi: Added PCI DMA alias %02x.%d for %s\n", + PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias), + dev_name(dev)); + } + + return ivrs_alias; +} + static struct iommu_dev_data *find_dev_data(u16 devid) { struct iommu_dev_data *dev_data; @@ -215,13 +285,6 @@ static struct iommu_dev_data *find_dev_data(u16 devid) return dev_data; } -static inline u16 get_device_id(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - - return PCI_DEVID(pdev->bus->number, pdev->devfn); -} - static struct iommu_dev_data *get_dev_data(struct device *dev) { return dev->archdata.iommu; @@ -349,6 +412,8 @@ static int iommu_init_device(struct device *dev) if (!dev_data) return -ENOMEM; + dev_data->alias = get_alias(dev); + if (pci_iommuv2_capable(pdev)) { struct amd_iommu *iommu; @@ -369,7 +434,7 @@ static void iommu_ignore_device(struct device *dev) u16 devid, alias; devid = get_device_id(dev); - alias = amd_iommu_alias_table[devid]; + alias = get_alias(dev); memset(&amd_iommu_dev_table[devid], 0, sizeof(struct dev_table_entry)); memset(&amd_iommu_dev_table[alias], 0, sizeof(struct dev_table_entry)); @@ -1061,7 +1126,7 @@ static int device_flush_dte(struct iommu_dev_data *dev_data) int ret; iommu = amd_iommu_rlookup_table[dev_data->devid]; - alias = amd_iommu_alias_table[dev_data->devid]; + alias = dev_data->alias; ret = iommu_flush_dte(iommu, dev_data->devid); if (!ret && alias != dev_data->devid) @@ -2039,7 +2104,7 @@ static void do_attach(struct iommu_dev_data *dev_data, bool ats; iommu = amd_iommu_rlookup_table[dev_data->devid]; - alias = amd_iommu_alias_table[dev_data->devid]; + alias = dev_data->alias; ats = dev_data->ats.enabled; /* Update data structures */ @@ -2073,7 +2138,7 @@ static void do_detach(struct iommu_dev_data *dev_data) return; iommu = amd_iommu_rlookup_table[dev_data->devid]; - alias = amd_iommu_alias_table[dev_data->devid]; + alias = dev_data->alias; /* decrease reference counters */ dev_data->domain->dev_iommu[iommu->index] -= 1; -- cgit v1.2.3 From c636b95ec5980345674ad7960a3c67135a84b687 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 11 Apr 2016 16:55:26 +0200 Subject: ALSA: hda/realtek - Enable the ALC292 dock fixup on the Thinkpad T460s The Lenovo Thinkpad T460s requires the alc_fixup_tpt440_dock as well in order to get working sound output on the docking stations headphone jack. Patch tested on a Thinkpad T460s (20F9CT01WW) using a ThinkPad Ultradock on kernel 4.4.6. Signed-off-by: Sven Eckelmann Tested-by: Simon Wunderlich Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fefe83f2beab..1402ba954b3d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4760,6 +4760,7 @@ enum { ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, ALC280_FIXUP_HP_HEADSET_MIC, ALC221_FIXUP_HP_FRONT_MIC, + ALC292_FIXUP_TPT460, }; static const struct hda_fixup alc269_fixups[] = { @@ -5409,6 +5410,12 @@ static const struct hda_fixup alc269_fixups[] = { { } }, }, + [ALC292_FIXUP_TPT460] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_tpt440_dock, + .chained = true, + .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -5563,7 +5570,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK), - SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE), + SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460), SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), @@ -5658,6 +5665,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"}, {.id = ALC292_FIXUP_TPT440, .name = "tpt440"}, + {.id = ALC292_FIXUP_TPT460, .name = "tpt460"}, {} }; #define ALC225_STANDARD_PINS \ -- cgit v1.2.3 From 072623de1f964c7ff01c46a9101af1c822fd2873 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Sat, 9 Apr 2016 12:48:18 -0400 Subject: dm: fix dm_target_io leak if clone_bio() returns an error Commit c80914e81ec5b08 ("dm: return error if bio_integrity_clone() fails in clone_bio()") changed clone_bio() such that if it does return error then the alloc_tio() created resources (both the bio that was allocated to be a clone and the containing dm_target_io struct) will leak. Fix this by calling free_tio() in __clone_and_map_data_bio()'s clone_bio() error path. Fixes: c80914e81ec5b08 ("dm: return error if bio_integrity_clone() fails in clone_bio()") Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- drivers/md/dm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index be4905769a45..3d3ac13287a4 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1662,8 +1662,10 @@ static int __clone_and_map_data_bio(struct clone_info *ci, struct dm_target *ti, tio = alloc_tio(ci, ti, target_bio_nr); tio->len_ptr = len; r = clone_bio(tio, bio, sector, *len); - if (r < 0) + if (r < 0) { + free_tio(ci->md, tio); break; + } __map_bio(tio); } -- cgit v1.2.3 From 9bf2b972afeaffd173fe2ce211ebc555ea7e8a87 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 8 Apr 2016 16:11:02 -0600 Subject: NVMe: Fix reset/remove race This fixes a scenario where device is present and being reset, but a request to unbind the driver occurs. A previous patch series addressing a device failure removal scenario flushed reset_work after controller disable to unblock reset_work waiting on a completion that wouldn't occur. This isn't safe as-is. The broken scenario can potentially be induced with: modprobe nvme && modprobe -r nvme To fix, the reset work is flushed immediately after setting the controller removing flag, and any subsequent reset will not proceed with controller initialization if the flag is set. The controller status must be polled while active, so the watchdog timer is also left active until the controller is disabled to cleanup requests that may be stuck during namespace removal. [Fixes: ff23a2a15a2117245b4599c1352343c8b8fb4c43] Signed-off-by: Keith Busch Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Reviewed-by: Sagi Grimberg Signed-off-by: Jens Axboe --- drivers/nvme/host/pci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 24ccda303efb..660ec84bc40f 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1859,6 +1859,9 @@ static void nvme_reset_work(struct work_struct *work) if (dev->ctrl.ctrl_config & NVME_CC_ENABLE) nvme_dev_disable(dev, false); + if (test_bit(NVME_CTRL_REMOVING, &dev->flags)) + goto out; + set_bit(NVME_CTRL_RESETTING, &dev->flags); result = nvme_pci_enable(dev); @@ -2078,11 +2081,10 @@ static void nvme_remove(struct pci_dev *pdev) { struct nvme_dev *dev = pci_get_drvdata(pdev); - del_timer_sync(&dev->watchdog_timer); - set_bit(NVME_CTRL_REMOVING, &dev->flags); pci_set_drvdata(pdev, NULL); flush_work(&dev->async_work); + flush_work(&dev->reset_work); flush_work(&dev->scan_work); nvme_remove_namespaces(&dev->ctrl); nvme_uninit_ctrl(&dev->ctrl); -- cgit v1.2.3 From ebf4dc2b1b2b9c8c7797f01a952bce3cf0247a4f Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Mon, 11 Apr 2016 11:07:58 +0530 Subject: cxgb4: Stop Rx Queues before freeing it up Stop all Ethernet RX Queues before freeing up various Ingress/Egress Queues, etc. We were seeing cases of Ingress Queues not getting serviced during the shutdown process leading to Ingress Paths jamming up through the chip and blocking the shutdown effort itself. One such case involved the Firmware sending a "Flush Token" through the ULP-TX -> ULP-RX path for an Ethernet TX Queue being freed in order to make sure there weren't any remaining TX Work Requests in the pipeline. But the return path was stalled by Ingress Data unable to be delivered to the Host because those Ingress Queues were no longer being serviced. Based on original work by Casey Leedom Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 3 +++ drivers/net/ethernet/chelsio/cxgb4/sge.c | 20 +++++++++++++++--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 33 ++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 984a3cc26f86..326d4009525e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1451,6 +1451,9 @@ int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, u16 *valp); int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, u16 val); +int t4_iq_stop(struct adapter *adap, unsigned int mbox, unsigned int pf, + unsigned int vf, unsigned int iqtype, unsigned int iqid, + unsigned int fl0id, unsigned int fl1id); int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int iqtype, unsigned int iqid, unsigned int fl0id, unsigned int fl1id); diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 13b144bcf725..6278e5a74b74 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -2981,14 +2981,28 @@ void t4_free_ofld_rxqs(struct adapter *adap, int n, struct sge_ofld_rxq *q) void t4_free_sge_resources(struct adapter *adap) { int i; - struct sge_eth_rxq *eq = adap->sge.ethrxq; - struct sge_eth_txq *etq = adap->sge.ethtxq; + struct sge_eth_rxq *eq; + struct sge_eth_txq *etq; + + /* stop all Rx queues in order to start them draining */ + for (i = 0; i < adap->sge.ethqsets; i++) { + eq = &adap->sge.ethrxq[i]; + if (eq->rspq.desc) + t4_iq_stop(adap, adap->mbox, adap->pf, 0, + FW_IQ_TYPE_FL_INT_CAP, + eq->rspq.cntxt_id, + eq->fl.size ? eq->fl.cntxt_id : 0xffff, + 0xffff); + } /* clean up Ethernet Tx/Rx queues */ - for (i = 0; i < adap->sge.ethqsets; i++, eq++, etq++) { + for (i = 0; i < adap->sge.ethqsets; i++) { + eq = &adap->sge.ethrxq[i]; if (eq->rspq.desc) free_rspq_fl(adap, &eq->rspq, eq->fl.size ? &eq->fl : NULL); + + etq = &adap->sge.ethtxq[i]; if (etq->q.desc) { t4_eth_eq_free(adap, adap->mbox, adap->pf, 0, etq->q.cntxt_id); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index cc1736bece0f..520ffcaef6d8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -6939,6 +6939,39 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } +/** + * t4_iq_stop - stop an ingress queue and its FLs + * @adap: the adapter + * @mbox: mailbox to use for the FW command + * @pf: the PF owning the queues + * @vf: the VF owning the queues + * @iqtype: the ingress queue type (FW_IQ_TYPE_FL_INT_CAP, etc.) + * @iqid: ingress queue id + * @fl0id: FL0 queue id or 0xffff if no attached FL0 + * @fl1id: FL1 queue id or 0xffff if no attached FL1 + * + * Stops an ingress queue and its associated FLs, if any. This causes + * any current or future data/messages destined for these queues to be + * tossed. + */ +int t4_iq_stop(struct adapter *adap, unsigned int mbox, unsigned int pf, + unsigned int vf, unsigned int iqtype, unsigned int iqid, + unsigned int fl0id, unsigned int fl1id) +{ + struct fw_iq_cmd c; + + memset(&c, 0, sizeof(c)); + c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F | + FW_CMD_EXEC_F | FW_IQ_CMD_PFN_V(pf) | + FW_IQ_CMD_VFN_V(vf)); + c.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_IQSTOP_F | FW_LEN16(c)); + c.type_to_iqandstindex = cpu_to_be32(FW_IQ_CMD_TYPE_V(iqtype)); + c.iqid = cpu_to_be16(iqid); + c.fl0id = cpu_to_be16(fl0id); + c.fl1id = cpu_to_be16(fl1id); + return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); +} + /** * t4_iq_free - free an ingress queue and its FLs * @adap: the adapter -- cgit v1.2.3 From 541726abe7daca64390c2ec34e6a203145f1686d Mon Sep 17 00:00:00 2001 From: Erik Hugne Date: Thu, 7 Apr 2016 10:40:43 -0400 Subject: tipc: make dist queue pernet Nametable updates received from the network that cannot be applied immediately are placed on a defer queue. This queue is global to the TIPC module, which might cause problems when using TIPC in containers. To prevent nametable updates from escaping into the wrong namespace, we make the queue pernet instead. Signed-off-by: Erik Hugne Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/core.c | 1 + net/tipc/core.h | 3 +++ net/tipc/name_distr.c | 16 +++++++--------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/net/tipc/core.c b/net/tipc/core.c index 03a842870c52..e2bdb07a49a2 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -69,6 +69,7 @@ static int __net_init tipc_init_net(struct net *net) if (err) goto out_nametbl; + INIT_LIST_HEAD(&tn->dist_queue); err = tipc_topsrv_start(net); if (err) goto out_subscr; diff --git a/net/tipc/core.h b/net/tipc/core.h index 5504d63503df..eff58dc53aa1 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -103,6 +103,9 @@ struct tipc_net { spinlock_t nametbl_lock; struct name_table *nametbl; + /* Name dist queue */ + struct list_head dist_queue; + /* Topology subscription server */ struct tipc_server *topsrv; atomic_t subscription_count; diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index ebe9d0ff6e9e..4f4f5810f223 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -40,11 +40,6 @@ int sysctl_tipc_named_timeout __read_mostly = 2000; -/** - * struct tipc_dist_queue - queue holding deferred name table updates - */ -static struct list_head tipc_dist_queue = LIST_HEAD_INIT(tipc_dist_queue); - struct distr_queue_item { struct distr_item i; u32 dtype; @@ -279,9 +274,11 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i, * tipc_named_add_backlog - add a failed name table update to the backlog * */ -static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) +static void tipc_named_add_backlog(struct net *net, struct distr_item *i, + u32 type, u32 node) { struct distr_queue_item *e; + struct tipc_net *tn = net_generic(net, tipc_net_id); unsigned long now = get_jiffies_64(); e = kzalloc(sizeof(*e), GFP_ATOMIC); @@ -291,7 +288,7 @@ static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) e->node = node; e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout); memcpy(e, i, sizeof(*i)); - list_add_tail(&e->next, &tipc_dist_queue); + list_add_tail(&e->next, &tn->dist_queue); } /** @@ -301,10 +298,11 @@ static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) void tipc_named_process_backlog(struct net *net) { struct distr_queue_item *e, *tmp; + struct tipc_net *tn = net_generic(net, tipc_net_id); char addr[16]; unsigned long now = get_jiffies_64(); - list_for_each_entry_safe(e, tmp, &tipc_dist_queue, next) { + list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) { if (time_after(e->expires, now)) { if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype)) continue; @@ -344,7 +342,7 @@ void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq) node = msg_orignode(msg); while (count--) { if (!tipc_update_nametbl(net, item, node, mtype)) - tipc_named_add_backlog(item, mtype, node); + tipc_named_add_backlog(net, item, mtype, node); item++; } kfree_skb(skb); -- cgit v1.2.3 From ddb1d33969ef52687ad00f75eecf87029f62e382 Mon Sep 17 00:00:00 2001 From: Erik Hugne Date: Thu, 7 Apr 2016 10:40:44 -0400 Subject: tipc: purge deferred updates from dead nodes If a peer node becomes unavailable, in addition to removing the nametable entries from this node we also need to purge all deferred updates associated with this node. Signed-off-by: Erik Hugne Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/name_distr.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 4f4f5810f223..6b626a64b517 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -224,12 +224,31 @@ static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr) kfree_rcu(p, rcu); } +/** + * tipc_dist_queue_purge - remove deferred updates from a node that went down + */ +static void tipc_dist_queue_purge(struct net *net, u32 addr) +{ + struct tipc_net *tn = net_generic(net, tipc_net_id); + struct distr_queue_item *e, *tmp; + + spin_lock_bh(&tn->nametbl_lock); + list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) { + if (e->node != addr) + continue; + list_del(&e->next); + kfree(e); + } + spin_unlock_bh(&tn->nametbl_lock); +} + void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr) { struct publication *publ, *tmp; list_for_each_entry_safe(publ, tmp, nsub_list, nodesub_list) tipc_publ_purge(net, publ, addr); + tipc_dist_queue_purge(net, addr); } /** -- cgit v1.2.3 From 9ab179d83b4e31ea277a123492e419067c2f129a Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 7 Apr 2016 11:10:06 -0700 Subject: net: vrf: Fix dst reference counting Vivek reported a kernel exception deleting a VRF with an active connection through it. The root cause is that the socket has a cached reference to a dst that is destroyed. Converting the dst_destroy to dst_release and letting proper reference counting kick in does not work as the dst has a reference to the device which needs to be released as well. I talked to Hannes about this at netdev and he pointed out the ipv4 and ipv6 dst handling has dst_ifdown for just this scenario. Rather than continuing with the reinvented dst wheel in VRF just remove it and leverage the ipv4 and ipv6 versions. Fixes: 193125dbd8eb2 ("net: Introduce VRF device driver") Fixes: 35402e3136634 ("net: Add IPv6 support to VRF device") Signed-off-by: David Ahern Signed-off-by: David S. Miller --- drivers/net/vrf.c | 177 +++++------------------------------------------- include/net/ip6_route.h | 3 + include/net/route.h | 3 + net/ipv4/route.c | 7 +- net/ipv6/route.c | 7 +- 5 files changed, 30 insertions(+), 167 deletions(-) diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 9a9fabb900c1..8a8f1e58b415 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -60,41 +60,6 @@ struct pcpu_dstats { struct u64_stats_sync syncp; }; -static struct dst_entry *vrf_ip_check(struct dst_entry *dst, u32 cookie) -{ - return dst; -} - -static int vrf_ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) -{ - return ip_local_out(net, sk, skb); -} - -static unsigned int vrf_v4_mtu(const struct dst_entry *dst) -{ - /* TO-DO: return max ethernet size? */ - return dst->dev->mtu; -} - -static void vrf_dst_destroy(struct dst_entry *dst) -{ - /* our dst lives forever - or until the device is closed */ -} - -static unsigned int vrf_default_advmss(const struct dst_entry *dst) -{ - return 65535 - 40; -} - -static struct dst_ops vrf_dst_ops = { - .family = AF_INET, - .local_out = vrf_ip_local_out, - .check = vrf_ip_check, - .mtu = vrf_v4_mtu, - .destroy = vrf_dst_destroy, - .default_advmss = vrf_default_advmss, -}; - /* neighbor handling is done with actual device; do not want * to flip skb->dev for those ndisc packets. This really fails * for multiple next protocols (e.g., NEXTHDR_HOP). But it is @@ -349,46 +314,6 @@ static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev) } #if IS_ENABLED(CONFIG_IPV6) -static struct dst_entry *vrf_ip6_check(struct dst_entry *dst, u32 cookie) -{ - return dst; -} - -static struct dst_ops vrf_dst_ops6 = { - .family = AF_INET6, - .local_out = ip6_local_out, - .check = vrf_ip6_check, - .mtu = vrf_v4_mtu, - .destroy = vrf_dst_destroy, - .default_advmss = vrf_default_advmss, -}; - -static int init_dst_ops6_kmem_cachep(void) -{ - vrf_dst_ops6.kmem_cachep = kmem_cache_create("vrf_ip6_dst_cache", - sizeof(struct rt6_info), - 0, - SLAB_HWCACHE_ALIGN, - NULL); - - if (!vrf_dst_ops6.kmem_cachep) - return -ENOMEM; - - return 0; -} - -static void free_dst_ops6_kmem_cachep(void) -{ - kmem_cache_destroy(vrf_dst_ops6.kmem_cachep); -} - -static int vrf_input6(struct sk_buff *skb) -{ - skb->dev->stats.rx_errors++; - kfree_skb(skb); - return 0; -} - /* modelled after ip6_finish_output2 */ static int vrf_finish_output6(struct net *net, struct sock *sk, struct sk_buff *skb) @@ -429,67 +354,34 @@ static int vrf_output6(struct net *net, struct sock *sk, struct sk_buff *skb) !(IP6CB(skb)->flags & IP6SKB_REROUTED)); } -static void vrf_rt6_destroy(struct net_vrf *vrf) +static void vrf_rt6_release(struct net_vrf *vrf) { - dst_destroy(&vrf->rt6->dst); - free_percpu(vrf->rt6->rt6i_pcpu); + dst_release(&vrf->rt6->dst); vrf->rt6 = NULL; } static int vrf_rt6_create(struct net_device *dev) { struct net_vrf *vrf = netdev_priv(dev); - struct dst_entry *dst; + struct net *net = dev_net(dev); struct rt6_info *rt6; - int cpu; int rc = -ENOMEM; - rt6 = dst_alloc(&vrf_dst_ops6, dev, 0, - DST_OBSOLETE_NONE, - (DST_HOST | DST_NOPOLICY | DST_NOXFRM)); + rt6 = ip6_dst_alloc(net, dev, + DST_HOST | DST_NOPOLICY | DST_NOXFRM | DST_NOCACHE); if (!rt6) goto out; - dst = &rt6->dst; - - rt6->rt6i_pcpu = alloc_percpu_gfp(struct rt6_info *, GFP_KERNEL); - if (!rt6->rt6i_pcpu) { - dst_destroy(dst); - goto out; - } - for_each_possible_cpu(cpu) { - struct rt6_info **p = per_cpu_ptr(rt6->rt6i_pcpu, cpu); - *p = NULL; - } - - memset(dst + 1, 0, sizeof(*rt6) - sizeof(*dst)); - - INIT_LIST_HEAD(&rt6->rt6i_siblings); - INIT_LIST_HEAD(&rt6->rt6i_uncached); - - rt6->dst.input = vrf_input6; rt6->dst.output = vrf_output6; - - rt6->rt6i_table = fib6_get_table(dev_net(dev), vrf->tb_id); - - atomic_set(&rt6->dst.__refcnt, 2); - + rt6->rt6i_table = fib6_get_table(net, vrf->tb_id); + dst_hold(&rt6->dst); vrf->rt6 = rt6; rc = 0; out: return rc; } #else -static int init_dst_ops6_kmem_cachep(void) -{ - return 0; -} - -static void free_dst_ops6_kmem_cachep(void) -{ -} - -static void vrf_rt6_destroy(struct net_vrf *vrf) +static void vrf_rt6_release(struct net_vrf *vrf) { } @@ -557,11 +449,11 @@ static int vrf_output(struct net *net, struct sock *sk, struct sk_buff *skb) !(IPCB(skb)->flags & IPSKB_REROUTED)); } -static void vrf_rtable_destroy(struct net_vrf *vrf) +static void vrf_rtable_release(struct net_vrf *vrf) { struct dst_entry *dst = (struct dst_entry *)vrf->rth; - dst_destroy(dst); + dst_release(dst); vrf->rth = NULL; } @@ -570,22 +462,10 @@ static struct rtable *vrf_rtable_create(struct net_device *dev) struct net_vrf *vrf = netdev_priv(dev); struct rtable *rth; - rth = dst_alloc(&vrf_dst_ops, dev, 2, - DST_OBSOLETE_NONE, - (DST_HOST | DST_NOPOLICY | DST_NOXFRM)); + rth = rt_dst_alloc(dev, 0, RTN_UNICAST, 1, 1, 0); if (rth) { rth->dst.output = vrf_output; - rth->rt_genid = rt_genid_ipv4(dev_net(dev)); - rth->rt_flags = 0; - rth->rt_type = RTN_UNICAST; - rth->rt_is_input = 0; - rth->rt_iif = 0; - rth->rt_pmtu = 0; - rth->rt_gateway = 0; - rth->rt_uses_gateway = 0; rth->rt_table_id = vrf->tb_id; - INIT_LIST_HEAD(&rth->rt_uncached); - rth->rt_uncached_list = NULL; } return rth; @@ -673,8 +553,8 @@ static void vrf_dev_uninit(struct net_device *dev) struct net_device *port_dev; struct list_head *iter; - vrf_rtable_destroy(vrf); - vrf_rt6_destroy(vrf); + vrf_rtable_release(vrf); + vrf_rt6_release(vrf); netdev_for_each_lower_dev(dev, port_dev, iter) vrf_del_slave(dev, port_dev); @@ -704,7 +584,7 @@ static int vrf_dev_init(struct net_device *dev) return 0; out_rth: - vrf_rtable_destroy(vrf); + vrf_rtable_release(vrf); out_stats: free_percpu(dev->dstats); dev->dstats = NULL; @@ -737,7 +617,7 @@ static struct rtable *vrf_get_rtable(const struct net_device *dev, struct net_vrf *vrf = netdev_priv(dev); rth = vrf->rth; - atomic_inc(&rth->dst.__refcnt); + dst_hold(&rth->dst); } return rth; @@ -788,7 +668,7 @@ static struct dst_entry *vrf_get_rt6_dst(const struct net_device *dev, struct net_vrf *vrf = netdev_priv(dev); rt = vrf->rt6; - atomic_inc(&rt->dst.__refcnt); + dst_hold(&rt->dst); } return (struct dst_entry *)rt; @@ -946,19 +826,6 @@ static int __init vrf_init_module(void) { int rc; - vrf_dst_ops.kmem_cachep = - kmem_cache_create("vrf_ip_dst_cache", - sizeof(struct rtable), 0, - SLAB_HWCACHE_ALIGN, - NULL); - - if (!vrf_dst_ops.kmem_cachep) - return -ENOMEM; - - rc = init_dst_ops6_kmem_cachep(); - if (rc != 0) - goto error2; - register_netdevice_notifier(&vrf_notifier_block); rc = rtnl_link_register(&vrf_link_ops); @@ -969,22 +836,10 @@ static int __init vrf_init_module(void) error: unregister_netdevice_notifier(&vrf_notifier_block); - free_dst_ops6_kmem_cachep(); -error2: - kmem_cache_destroy(vrf_dst_ops.kmem_cachep); return rc; } -static void __exit vrf_cleanup_module(void) -{ - rtnl_link_unregister(&vrf_link_ops); - unregister_netdevice_notifier(&vrf_notifier_block); - kmem_cache_destroy(vrf_dst_ops.kmem_cachep); - free_dst_ops6_kmem_cachep(); -} - module_init(vrf_init_module); -module_exit(vrf_cleanup_module); MODULE_AUTHOR("Shrijeet Mukherjee, David Ahern"); MODULE_DESCRIPTION("Device driver to instantiate VRF domains"); MODULE_LICENSE("GPL"); diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 295d291269e2..54c779416eec 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -101,6 +101,9 @@ void fib6_force_start_gc(struct net *net); struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, const struct in6_addr *addr, bool anycast); +struct rt6_info *ip6_dst_alloc(struct net *net, struct net_device *dev, + int flags); + /* * support functions for ND * diff --git a/include/net/route.h b/include/net/route.h index 9b0a523bb428..6de665bf1750 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -209,6 +209,9 @@ unsigned int inet_addr_type_dev_table(struct net *net, void ip_rt_multicast_event(struct in_device *); int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg); void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt); +struct rtable *rt_dst_alloc(struct net_device *dev, + unsigned int flags, u16 type, + bool nopolicy, bool noxfrm, bool will_cache); struct in_ifaddr; void fib_add_ifaddr(struct in_ifaddr *); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 02c62299d717..2852bdf73540 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1438,9 +1438,9 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr, #endif } -static struct rtable *rt_dst_alloc(struct net_device *dev, - unsigned int flags, u16 type, - bool nopolicy, bool noxfrm, bool will_cache) +struct rtable *rt_dst_alloc(struct net_device *dev, + unsigned int flags, u16 type, + bool nopolicy, bool noxfrm, bool will_cache) { struct rtable *rt; @@ -1468,6 +1468,7 @@ static struct rtable *rt_dst_alloc(struct net_device *dev, return rt; } +EXPORT_SYMBOL(rt_dst_alloc); /* called in rcu_read_lock() section */ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, diff --git a/net/ipv6/route.c b/net/ipv6/route.c index ed446639219c..1d8871a5ed20 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -338,9 +338,9 @@ static struct rt6_info *__ip6_dst_alloc(struct net *net, return rt; } -static struct rt6_info *ip6_dst_alloc(struct net *net, - struct net_device *dev, - int flags) +struct rt6_info *ip6_dst_alloc(struct net *net, + struct net_device *dev, + int flags) { struct rt6_info *rt = __ip6_dst_alloc(net, dev, flags); @@ -364,6 +364,7 @@ static struct rt6_info *ip6_dst_alloc(struct net *net, return rt; } +EXPORT_SYMBOL(ip6_dst_alloc); static void ip6_dst_destroy(struct dst_entry *dst) { -- cgit v1.2.3 From 4f7f34eaab9f68c9bcd45386b15c414c38b40587 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 7 Apr 2016 11:10:41 -0700 Subject: net: vrf: Fix dev refcnt leak due to IPv6 prefix route ifupdown2 found a kernel bug with IPv6 routes and movement from the main table to the VRF table. Sequence of events: Create the interface and add addresses: ip link add dev eth4.105 link eth4 type vlan id 105 ip addr add dev eth4.105 8.105.105.10/24 ip -6 addr add dev eth4.105 2008:105:105::10/64 At this point IPv6 has inserted a prefix route in the main table even though the interface is 'down'. From there the VRF device is created: ip link add dev vrf105 type vrf table 105 ip addr add dev vrf105 9.9.105.10/32 ip -6 addr add dev vrf105 2000:9:105::10/128 ip link set vrf105 up Then the interface is enslaved, while still in the 'down' state: ip link set dev eth4.105 master vrf105 Since the device is down the VRF driver cycling the device does not send the NETDEV_UP and NETDEV_DOWN but rather the NETDEV_CHANGE event which does not flush the routes inserted prior. When the link is brought up ip link set dev eth4.105 up the prefix route is added in the VRF table, but does not remove the route from the main table. Fix by handling the NETDEV_CHANGEUPPER event similar what was implemented for IPv4 in 7f49e7a38b77 ("net: Flush local routes when device changes vrf association") Fixes: 35402e3136634 ("net: Add IPv6 support to VRF device") Signed-off-by: David Ahern Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 27aed1afcf81..2db2116d3e6b 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3255,6 +3255,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct netdev_notifier_changeupper_info *info; struct inet6_dev *idev = __in6_dev_get(dev); int run_pending = 0; int err; @@ -3413,6 +3414,15 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, if (idev) addrconf_type_change(dev, event); break; + + case NETDEV_CHANGEUPPER: + info = ptr; + + /* flush all routes if dev is linked to or unlinked from + * an L3 master device (e.g., VRF) + */ + if (info->upper_dev && netif_is_l3_master(info->upper_dev)) + addrconf_ifdown(dev, 0); } return NOTIFY_OK; -- cgit v1.2.3 From 1ecf689013b598918cd9a261a078e64571b60f90 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 11 Apr 2016 13:39:08 -0700 Subject: devlink: add missing install of header The new devlink.h in uapi was not being installed by make headers_install Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/uapi/linux/Kbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index b71fd0b5cbad..813ffb2e22c9 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -96,6 +96,7 @@ header-y += cyclades.h header-y += cycx_cfm.h header-y += dcbnl.h header-y += dccp.h +header-y += devlink.h header-y += dlmconstants.h header-y += dlm_device.h header-y += dlm.h -- cgit v1.2.3 From f0c8e1d9c4f473dfc771a613b602f1841afe8f8b Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Tue, 12 Apr 2016 10:31:23 +0530 Subject: ASoC: Intel: Skylake: Fix ibs/obs calc for non-integral sampling rates FW expects sampling rate rounded up to next higher integer value when calculating ibs/obs. For example for 44.1k, it should be rounded up to 45 to calculate ibs/obs. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-topology.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 5a85f3a4699b..cdb78b7e5a14 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -239,6 +239,7 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx, { int multiplier = 1; struct skl_module_fmt *in_fmt, *out_fmt; + int in_rate, out_rate; /* Since fixups is applied to pin 0 only, ibs, obs needs @@ -249,15 +250,24 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx, if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) multiplier = 5; - mcfg->ibs = (in_fmt->s_freq / 1000) * - (mcfg->in_fmt->channels) * - (mcfg->in_fmt->bit_depth >> 3) * - multiplier; - - mcfg->obs = (mcfg->out_fmt->s_freq / 1000) * - (mcfg->out_fmt->channels) * - (mcfg->out_fmt->bit_depth >> 3) * - multiplier; + + if (in_fmt->s_freq % 1000) + in_rate = (in_fmt->s_freq / 1000) + 1; + else + in_rate = (in_fmt->s_freq / 1000); + + mcfg->ibs = in_rate * (mcfg->in_fmt->channels) * + (mcfg->in_fmt->bit_depth >> 3) * + multiplier; + + if (mcfg->out_fmt->s_freq % 1000) + out_rate = (mcfg->out_fmt->s_freq / 1000) + 1; + else + out_rate = (mcfg->out_fmt->s_freq / 1000); + + mcfg->obs = out_rate * (mcfg->out_fmt->channels) * + (mcfg->out_fmt->bit_depth >> 3) * + multiplier; } static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, -- cgit v1.2.3 From d34475b964b01067ed25187c4f52d8bdf2c0e113 Mon Sep 17 00:00:00 2001 From: Oren Givon Date: Thu, 24 Mar 2016 10:20:28 +0200 Subject: iwlwifi: add device IDs for the 8265 device Add new 8265 series PCI IDs. Signed-off-by: Oren Givon Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 05b968506836..79d7cd7d461e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -479,8 +479,18 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)}, {IWL_PCI_DEVICE(0x24F3, 0x0000, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x0010, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0110, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x1110, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x1010, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0050, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x0150, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x9010, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x8110, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x8050, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x8010, iwl8265_2ac_cfg)}, {IWL_PCI_DEVICE(0x24FD, 0x0810, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x9110, iwl8265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24FD, 0x8130, iwl8265_2ac_cfg)}, /* 9000 Series */ {IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl5165_2ac_cfg)}, -- cgit v1.2.3 From cd49727e1a2bccc4ff008dde24c2f8430dd9e368 Mon Sep 17 00:00:00 2001 From: Ayala Beker Date: Wed, 3 Feb 2016 15:36:52 +0200 Subject: iwlwifi: mvm: avoid to WARN about gscan capabilities Gscan capabilities were updated with new capabilities supported by the device. Update GSCAN capabilities TLV and avoid to WARN if the firmware does not have the new capabilities. Signed-off-by: Ayala Beker Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index f899666acb41..33d0d51e32e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1060,11 +1060,18 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, return -EINVAL; } - if (WARN(fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) && - !gscan_capa, - "GSCAN is supported but capabilities TLV is unavailable\n")) + /* + * If ucode advertises that it supports GSCAN but GSCAN + * capabilities TLV is not present, or if it has an old format, + * warn and continue without GSCAN. + */ + if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) && + !gscan_capa) { + IWL_DEBUG_INFO(drv, + "GSCAN is supported but capabilities TLV is unavailable\n"); __clear_bit((__force long)IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT, capa->_capa); + } return 0; -- cgit v1.2.3 From 17f5f28ffa6e81461a569290ae802a9b05a89072 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 23 Mar 2016 14:43:41 +0000 Subject: mailbox: mailbox-test: Use more consistent format for calling copy_from_user() While we're at it, ensure copy-to location is NULL'ed in the error path. Suggested-by: Dan Carpenter Signed-off-by: Lee Jones Signed-off-by: Jassi Brar --- drivers/mailbox/mailbox-test.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c index dc11bbf27274..5f4b439fd45a 100644 --- a/drivers/mailbox/mailbox-test.c +++ b/drivers/mailbox/mailbox-test.c @@ -46,7 +46,6 @@ static ssize_t mbox_test_signal_write(struct file *filp, size_t count, loff_t *ppos) { struct mbox_test_device *tdev = filp->private_data; - int ret; if (!tdev->tx_channel) { dev_err(tdev->dev, "Channel cannot do Tx\n"); @@ -64,13 +63,13 @@ static ssize_t mbox_test_signal_write(struct file *filp, if (!tdev->signal) return -ENOMEM; - ret = copy_from_user(tdev->signal, userbuf, count); - if (ret) { + if (copy_from_user(tdev->signal, userbuf, count)) { kfree(tdev->signal); + tdev->signal = NULL; return -EFAULT; } - return ret < 0 ? ret : count; + return count; } static const struct file_operations mbox_test_signal_ops = { -- cgit v1.2.3 From d1c2f87c9a8f79fa8816bbe7de98da38eae2be5e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 23 Mar 2016 14:43:42 +0000 Subject: mailbox: mailbox-test: Prevent memory leak If we set the Signal twice or more, without using it as part of a message, memory will be re-allocated and the pointer over-written. Prevent this potential leak by only allocating memory when there isn't any already. Reported-by: Dan Carpenter Signed-off-by: Lee Jones Signed-off-by: Jassi Brar --- drivers/mailbox/mailbox-test.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c index 5f4b439fd45a..58d04726cdd7 100644 --- a/drivers/mailbox/mailbox-test.c +++ b/drivers/mailbox/mailbox-test.c @@ -59,9 +59,12 @@ static ssize_t mbox_test_signal_write(struct file *filp, return -EINVAL; } - tdev->signal = kzalloc(MBOX_MAX_SIG_LEN, GFP_KERNEL); - if (!tdev->signal) - return -ENOMEM; + /* Only allocate memory if we need to */ + if (!tdev->signal) { + tdev->signal = kzalloc(MBOX_MAX_SIG_LEN, GFP_KERNEL); + if (!tdev->signal) + return -ENOMEM; + } if (copy_from_user(tdev->signal, userbuf, count)) { kfree(tdev->signal); -- cgit v1.2.3 From 0c44d7896cbf9156b8bb10da4f665005622235ae Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 23 Mar 2016 14:43:43 +0000 Subject: mailbox: Stop using ENOSYS for anything other than unimplemented syscalls In accordance with e15f431fe2d5 ("errno.h: Improve ENOSYS's comment") and 91c9afaf97ee ("checkpatch.pl: new instances of ENOSYS are errors") we're converting from the old meaning of: ENOSYS "Function not implemented" to a more standard EINVAL. Reported-by: Seraphin Bonnaffe Signed-off-by: Lee Jones Signed-off-by: Jassi Brar --- drivers/mailbox/mailbox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index 6a4811f85705..4a36632c236f 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -375,13 +375,13 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl, if (!np) { dev_err(cl->dev, "%s() currently only supports DT\n", __func__); - return ERR_PTR(-ENOSYS); + return ERR_PTR(-EINVAL); } if (!of_get_property(np, "mbox-names", NULL)) { dev_err(cl->dev, "%s() requires an \"mbox-names\" property\n", __func__); - return ERR_PTR(-ENOSYS); + return ERR_PTR(-EINVAL); } of_property_for_each_string(np, "mbox-names", prop, mbox_name) { -- cgit v1.2.3 From 42c25013ca95ce79b4ed192188ca843ae48f8c71 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 12 Apr 2016 10:00:34 +0200 Subject: Revert "gpio: rcar: Add Runtime PM handling for interrupts" This reverts commit b26a719bdba9aa926ceaadecc66e07623d2b8a53. --- drivers/gpio/gpio-rcar.c | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index d9ab0cd1d205..cf41440aff91 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -196,44 +196,6 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on) return 0; } -static void gpio_rcar_irq_bus_lock(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gpio_rcar_priv *p = gpiochip_get_data(gc); - - pm_runtime_get_sync(&p->pdev->dev); -} - -static void gpio_rcar_irq_bus_sync_unlock(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gpio_rcar_priv *p = gpiochip_get_data(gc); - - pm_runtime_put(&p->pdev->dev); -} - - -static int gpio_rcar_irq_request_resources(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gpio_rcar_priv *p = gpiochip_get_data(gc); - int error; - - error = pm_runtime_get_sync(&p->pdev->dev); - if (error < 0) - return error; - - return 0; -} - -static void gpio_rcar_irq_release_resources(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gpio_rcar_priv *p = gpiochip_get_data(gc); - - pm_runtime_put(&p->pdev->dev); -} - static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id) { struct gpio_rcar_priv *p = dev_id; @@ -488,10 +450,6 @@ static int gpio_rcar_probe(struct platform_device *pdev) irq_chip->irq_unmask = gpio_rcar_irq_enable; irq_chip->irq_set_type = gpio_rcar_irq_set_type; irq_chip->irq_set_wake = gpio_rcar_irq_set_wake; - irq_chip->irq_bus_lock = gpio_rcar_irq_bus_lock; - irq_chip->irq_bus_sync_unlock = gpio_rcar_irq_bus_sync_unlock; - irq_chip->irq_request_resources = gpio_rcar_irq_request_resources; - irq_chip->irq_release_resources = gpio_rcar_irq_release_resources; irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND; ret = gpiochip_add_data(gpio_chip, p); -- cgit v1.2.3 From ce0e2c60e69e5f87ab4ac10c935d8bd85d4d11f7 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 12 Apr 2016 10:05:22 +0200 Subject: Revert "gpio: rcar: Fine-grained Runtime PM support" This reverts commit 65194cb174b873448b208eb6e04ecb72237af76e. --- drivers/gpio/gpio-rcar.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index cf41440aff91..4d9a315cfd43 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -242,32 +242,18 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip, static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset) { - struct gpio_rcar_priv *p = gpiochip_get_data(chip); - int error; - - error = pm_runtime_get_sync(&p->pdev->dev); - if (error < 0) - return error; - - error = pinctrl_request_gpio(chip->base + offset); - if (error) - pm_runtime_put(&p->pdev->dev); - - return error; + return pinctrl_request_gpio(chip->base + offset); } static void gpio_rcar_free(struct gpio_chip *chip, unsigned offset) { - struct gpio_rcar_priv *p = gpiochip_get_data(chip); - pinctrl_free_gpio(chip->base + offset); - /* Set the GPIO as an input to ensure that the next GPIO request won't + /* + * Set the GPIO as an input to ensure that the next GPIO request won't * drive the GPIO pin as an output. */ gpio_rcar_config_general_input_output_mode(chip, offset, false); - - pm_runtime_put(&p->pdev->dev); } static int gpio_rcar_direction_input(struct gpio_chip *chip, unsigned offset) @@ -414,6 +400,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) } pm_runtime_enable(dev); + pm_runtime_get_sync(dev); io = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -480,6 +467,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) err1: gpiochip_remove(gpio_chip); err0: + pm_runtime_put(dev); pm_runtime_disable(dev); return ret; } @@ -490,6 +478,7 @@ static int gpio_rcar_remove(struct platform_device *pdev) gpiochip_remove(&p->gpio_chip); + pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; } -- cgit v1.2.3 From e1ba684f762b9a8064de2c916bb60b1694dd8a17 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Mon, 11 Apr 2016 15:01:46 +0300 Subject: iwlwifi: 8000: fix MODULE_FIRMWARE input The firwmare name for 8000 is iwlwifi-8000C. The C is appended based on a value read from a register. This allows to load different firwmare versions based on the hardware step during development. Now that the hardware development is completed, we can hard code the 'C' and along the way, fix the input to MODULE_FIRMWARE. This fixes: https://bugzilla.kernel.org/show_bug.cgi?id=116041 Signed-off-by: Sara Sharon Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/intel/iwlwifi/iwl-8000.c | 2 +- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c index 97be104d1203..b5c57eebf995 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c @@ -93,7 +93,7 @@ #define IWL8260_SMEM_OFFSET 0x400000 #define IWL8260_SMEM_LEN 0x68000 -#define IWL8000_FW_PRE "iwlwifi-8000" +#define IWL8000_FW_PRE "iwlwifi-8000C-" #define IWL8000_MODULE_FIRMWARE(api) \ IWL8000_FW_PRE "-" __stringify(api) ".ucode" diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 33d0d51e32e9..9e45bf9c6071 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -238,19 +238,6 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s%s.ucode", name_pre, tag); - /* - * Starting 8000B - FW name format has changed. This overwrites the - * previous name and uses the new format. - */ - if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { - char rev_step = 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev); - - if (rev_step != 'A') - snprintf(drv->firmware_name, - sizeof(drv->firmware_name), "%s%c-%s.ucode", - name_pre, rev_step, tag); - } - IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) ? "EXPERIMENTAL " : "", -- cgit v1.2.3 From f742aaf36edf0390c54d0614bc4d20fd4cd3762a Mon Sep 17 00:00:00 2001 From: Matti Gottlieb Date: Sun, 10 Apr 2016 10:53:57 +0300 Subject: iwlwifi: mvm: fix accessing Null pointer during fw dump collection The firwmare file can come with data that is relevant for paging. This data is availablet to the firmware upon request, but it stored in the host's memory. During the firmware init flow, the driver configures the firmware so that the firwmare knows where is the data. When paging is used, the variable paging_mem_size is the number of bytes that are available through paging. This variable is not zeror-ed if the driver fails to configure the paging in the firmware, but the memory is freed which is inconsistent. This inconsistency led to a NULL pointer dereference in the code that collects the debug data. Fix this by zero-ing the paging_mem_size variable and NULLify the relevant pointers, so that the code that collects the debug data will know that the paging data is not available. Signed-off-by: Matti Gottlieb Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c | 6 ++++-- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c index 4856eac120f6..6938cd37be57 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c @@ -526,7 +526,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len; /* Make room for fw's virtual image pages, if it exists */ - if (mvm->fw->img[mvm->cur_ucode].paging_mem_size) + if (mvm->fw->img[mvm->cur_ucode].paging_mem_size && + mvm->fw_paging_db[0].fw_paging_block) file_len += mvm->num_of_paging_blk * (sizeof(*dump_data) + sizeof(struct iwl_fw_error_dump_paging) + @@ -643,7 +644,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) } /* Dump fw's virtual image */ - if (mvm->fw->img[mvm->cur_ucode].paging_mem_size) { + if (mvm->fw->img[mvm->cur_ucode].paging_mem_size && + mvm->fw_paging_db[0].fw_paging_block) { for (i = 1; i < mvm->num_of_paging_blk + 1; i++) { struct iwl_fw_error_dump_paging *paging; struct page *pages = diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 594cd0dc7df9..09d895fafaf2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -144,9 +144,11 @@ void iwl_free_fw_paging(struct iwl_mvm *mvm) __free_pages(mvm->fw_paging_db[i].fw_paging_block, get_order(mvm->fw_paging_db[i].fw_paging_size)); + mvm->fw_paging_db[i].fw_paging_block = NULL; } kfree(mvm->trans->paging_download_buf); mvm->trans->paging_download_buf = NULL; + mvm->trans->paging_db = NULL; memset(mvm->fw_paging_db, 0, sizeof(mvm->fw_paging_db)); } -- cgit v1.2.3 From adcdd0d5a1cb779f6d455ae70882c19c527627a8 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 12 Apr 2016 10:55:03 +0800 Subject: ALSA: usb-audio: Skip volume controls triggers hangup on Dell USB Dock This is Dell usb dock audio workaround. It was fixed the master volume keep lower. [Some background: the patch essentially skips the controls of a couple of FU volumes. Although the firmware exposes the dB and the value information via the usb descriptor, changing the values (we set the min volume as default) screws up the device. Although this has been fixed in the newer firmware, the devices are shipped with the old firmware, thus we need the workaround in the driver side. -- tiwai] Signed-off-by: Kailang Yang Cc: Signed-off-by: Takashi Iwai --- sound/usb/mixer_maps.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index ddca6547399b..1f8fb0d904e0 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -348,6 +348,16 @@ static struct usbmix_name_map bose_companion5_map[] = { { 0 } /* terminator */ }; +/* + * Dell usb dock with ALC4020 codec had a firmware problem where it got + * screwed up when zero volume is passed; just skip it as a workaround + */ +static const struct usbmix_name_map dell_alc4020_map[] = { + { 16, NULL }, + { 19, NULL }, + { 0 } +}; + /* * Control map entries */ @@ -430,6 +440,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x0ccd, 0x0028), .map = aureon_51_2_map, }, + { + .id = USB_ID(0x0bda, 0x4014), + .map = dell_alc4020_map, + }, { .id = USB_ID(0x0dba, 0x1000), .map = mbox1_map, -- cgit v1.2.3 From 8f815cdde3e550e10c2736990d791f60c2ce43eb Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 6 Apr 2016 17:23:18 +0300 Subject: nl80211: check netlink protocol in socket release notification A non-privileged user can create a netlink socket with the same port_id as used by an existing open nl80211 netlink socket (e.g. as used by a hostapd process) with a different protocol number. Closing this socket will then lead to the notification going to nl80211's socket release notification handler, and possibly cause an action such as removing a virtual interface. Fix this issue by checking that the netlink protocol is NETLINK_GENERIC. Since generic netlink has no notifier chain of its own, we can't fix the problem more generically. Fixes: 026331c4d9b5 ("cfg80211/mac80211: allow registering for and sending action frames") Cc: stable@vger.kernel.org Signed-off-by: Dmitry Ivanov [rewrite commit message] Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 98c924260b3d..056a7307862b 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -13216,7 +13216,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb, struct wireless_dev *wdev; struct cfg80211_beacon_registration *reg, *tmp; - if (state != NETLINK_URELEASE) + if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC) return NOTIFY_DONE; rcu_read_lock(); -- cgit v1.2.3 From 55c4b906aa2aec3fa66310ec03c6842e34a04b2a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 14 Mar 2016 15:22:25 +0100 Subject: drm/exynos: fix error handling in exynos_drm_subdrv_open gcc-6 warns about a pointless loop in exynos_drm_subdrv_open: drivers/gpu/drm/exynos/exynos_drm_core.c: In function 'exynos_drm_subdrv_open': drivers/gpu/drm/exynos/exynos_drm_core.c:104:199: error: self-comparison always evaluates to false [-Werror=tautological-compare] list_for_each_entry_reverse(subdrv, &subdrv->list, list) { Here, the list_for_each_entry_reverse immediately terminates because the subdrv pointer is compared to itself as the loop end condition. If we were to take the current subdrv pointer as the start of the list (as we would do if list_for_each_entry_reverse() was not a macro), we would iterate backwards over the &exynos_drm_subdrv_list anchor, which would be even worse. Instead, we need to use list_for_each_entry_continue_reverse() to go back over each subdrv that was successfully opened until the first entry. Signed-off-by: Arnd Bergmann Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c index 7f55ba6771c6..011211e4167d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c @@ -101,7 +101,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) return 0; err: - list_for_each_entry_reverse(subdrv, &subdrv->list, list) { + list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) { if (subdrv->close) subdrv->close(dev, subdrv->dev, file); } -- cgit v1.2.3 From 311521e25630b9c61ce22f3adc3ad0b35d5f2667 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 15 Mar 2016 12:38:02 +0100 Subject: drm/exynos: fix adjusted_mode pointer in exynos_plane_mode_set exynos_plane_mode_set should use adjusted_mode from the same atomic state as plane state. Otherwise it will result in incorrect behavior in case crtc mode changes. The patch fixes bug with black console framebuffer in case of command mode panels. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_plane.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index d86227236f55..50185ac347b2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -11,9 +11,10 @@ #include -#include -#include +#include #include +#include +#include #include "exynos_drm_drv.h" #include "exynos_drm_crtc.h" #include "exynos_drm_fb.h" @@ -57,11 +58,12 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last) } static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) - { struct drm_plane_state *state = &exynos_state->base; - struct drm_crtc *crtc = exynos_state->base.crtc; - struct drm_display_mode *mode = &crtc->state->adjusted_mode; + struct drm_crtc *crtc = state->crtc; + struct drm_crtc_state *crtc_state = + drm_atomic_get_existing_crtc_state(state->state, crtc); + struct drm_display_mode *mode = &crtc_state->adjusted_mode; int crtc_x, crtc_y; unsigned int crtc_w, crtc_h; unsigned int src_x, src_y; -- cgit v1.2.3 From 9b988a0dc93689c93214b518bcb5fd52c44691ba Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 15 Mar 2016 12:43:21 +0100 Subject: drm/exynos: build fbdev code conditionally Fbdev code should be compiled only if CONFIG_DRM_FBDEV_EMULATION option is enabled. The patch fixes exynos-drm code trying to manipulate fbdev data which is not initialized in case CONFIG_DRM_FBDEV_EMULATION is disabled. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/Makefile | 6 +++--- drivers/gpu/drm/exynos/exynos_drm_fb.c | 11 ----------- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 11 +++++++++++ drivers/gpu/drm/exynos/exynos_drm_fbdev.h | 23 ++++++++++++++++++++++- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile index 968b31c522b2..23d2f958739b 100644 --- a/drivers/gpu/drm/exynos/Makefile +++ b/drivers/gpu/drm/exynos/Makefile @@ -2,10 +2,10 @@ # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \ - exynos_drm_fb.o exynos_drm_gem.o exynos_drm_core.o \ - exynos_drm_plane.o +exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \ + exynos_drm_gem.o exynos_drm_core.o exynos_drm_plane.o +exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index d614194644c8..81cc5537cf25 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -199,17 +199,6 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index) return exynos_fb->dma_addr[index]; } -static void exynos_drm_output_poll_changed(struct drm_device *dev) -{ - struct exynos_drm_private *private = dev->dev_private; - struct drm_fb_helper *fb_helper = private->fb_helper; - - if (fb_helper) - drm_fb_helper_hotplug_event(fb_helper); - else - exynos_drm_fbdev_init(dev); -} - static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { .fb_create = exynos_user_fb_create, .output_poll_changed = exynos_drm_output_poll_changed, diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 4ae860c44f1d..72d7c0b7c216 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -317,3 +317,14 @@ void exynos_drm_fbdev_restore_mode(struct drm_device *dev) drm_fb_helper_restore_fbdev_mode_unlocked(private->fb_helper); } + +void exynos_drm_output_poll_changed(struct drm_device *dev) +{ + struct exynos_drm_private *private = dev->dev_private; + struct drm_fb_helper *fb_helper = private->fb_helper; + + if (fb_helper) + drm_fb_helper_hotplug_event(fb_helper); + else + exynos_drm_fbdev_init(dev); +} diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.h b/drivers/gpu/drm/exynos/exynos_drm_fbdev.h index e16d7f0ae192..330eef87f718 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.h +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.h @@ -15,9 +15,30 @@ #ifndef _EXYNOS_DRM_FBDEV_H_ #define _EXYNOS_DRM_FBDEV_H_ +#ifdef CONFIG_DRM_FBDEV_EMULATION + int exynos_drm_fbdev_init(struct drm_device *dev); -int exynos_drm_fbdev_reinit(struct drm_device *dev); void exynos_drm_fbdev_fini(struct drm_device *dev); void exynos_drm_fbdev_restore_mode(struct drm_device *dev); +void exynos_drm_output_poll_changed(struct drm_device *dev); + +#else + +static inline int exynos_drm_fbdev_init(struct drm_device *dev) +{ + return 0; +} + +static inline void exynos_drm_fbdev_fini(struct drm_device *dev) +{ +} + +static inline void exynos_drm_fbdev_restore_mode(struct drm_device *dev) +{ +} + +#define exynos_drm_output_poll_changed (NULL) + +#endif #endif -- cgit v1.2.3 From d42a114d88dcead9c3a41574aa0647d56d0a28f7 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 17 Mar 2016 07:53:12 +0100 Subject: drm/exynos: fimd: fix broken dp_clock control Commit 1feafd3afd294b03dbbedb8e8f94e0c4db526f10 ("drm/exynos: add exynos5420 support for fimd") add support for Exynos 5420 SoC, but it broke enabling display clock feature because of incorrect condition check. This patch fixes it, so display is working again on platforms requiring display clock control (i.e. Exynos5250-based SNOW platform). Signed-off-by: Marek Szyprowski Reviewed-by: Krzysztof Kozlowski Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 51d484ae9f49..018449f8d557 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -888,7 +888,7 @@ static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable) * clock. On these SoCs the bootloader may enable it but any * power domain off/on will reset it to disable state. */ - if (ctx->driver_data != &exynos5_fimd_driver_data || + if (ctx->driver_data != &exynos5_fimd_driver_data && ctx->driver_data != &exynos5420_fimd_driver_data) return; -- cgit v1.2.3 From 6c9c15813b21ce75bc82db86db1163a34b772437 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 17 Mar 2016 13:32:15 +0300 Subject: drm/exynos: mic: fix an error code We accidentally return success instead of a negative error code here. Signed-off-by: Dan Carpenter Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_mic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index 9869d70e9e54..890c9b1c0239 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -457,6 +457,7 @@ static int exynos_mic_probe(struct platform_device *pdev) "samsung,disp-syscon"); if (IS_ERR(mic->sysreg)) { DRM_ERROR("mic: Failed to get system register.\n"); + ret = PTR_ERR(mic->sysreg); goto err; } -- cgit v1.2.3 From 36ffc2bde5fc743aa64c2e1f53de163a92824a27 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 25 Mar 2016 23:05:59 +0300 Subject: drm/exynos: fix a warning message The "ret = regmap_write()" assignment was missing so this error message is never printed. Signed-off-by: Dan Carpenter Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_mic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index 890c9b1c0239..a0def0be6d65 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -129,7 +129,7 @@ static void mic_set_path(struct exynos_mic *mic, bool enable) } else val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX); - regmap_write(mic->sysreg, DSD_CFG_MUX, val); + ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val); if (ret) DRM_ERROR("mic: Failed to read system register\n"); } -- cgit v1.2.3 From 2072fe51466f86e1f0eedf12bff7106913807efc Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 29 Mar 2016 10:28:55 +0900 Subject: drm/exynos: Use VIDEO_SAMSUNG_S5P_G2D=n as G2D Kconfig dependency Commit 254d4d111ee1 ("drm/exynos: Add dependency for G2D in Kconfig") made the DRM_EXYNOS_G2D symbol to only be selectable if the s5p-g2d V4L2 driver is not enabled, since both use the same HW IP block. But added the dependency as depends on !VIDEO_SAMSUNG_S5P_G2D which isn't correct since Kconfig expressions are not boolean but tristate. So it will only evaluate to 'n' if VIDEO_SAMSUNG_S5P_G2D=y but it will evaluate to m if VIDEO_SAMSUNG_S5P_G2D=m. This means that both the V4L2 and DRM drivers can be enabled if the former is enabled as a module, which is not what we want. Signed-off-by: Javier Martinez Canillas Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index f17d39279596..baddf33fb475 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -94,7 +94,7 @@ comment "Sub-drivers" config DRM_EXYNOS_G2D bool "G2D" - depends on !VIDEO_SAMSUNG_S5P_G2D + depends on VIDEO_SAMSUNG_S5P_G2D=n select FRAME_VECTOR help Choose this option if you want to use Exynos G2D for DRM. -- cgit v1.2.3 From d7d75352890447b55c13a81df316a6894ff32ecf Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 11 Apr 2016 15:10:11 -0700 Subject: fscrypto: use dget_parent() in fscrypt_d_revalidate() This patch updates fscrypto along with the below ext4 crypto change. Fixes: 3d43bcfef5f0 ("ext4 crypto: use dget_parent() in ext4_d_revalidate()") Cc: Theodore Ts'o Signed-off-by: Jaegeuk Kim --- fs/crypto/crypto.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 7f5804537d30..58ae0ba91ca2 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -345,13 +345,17 @@ EXPORT_SYMBOL(fscrypt_zeroout_range); */ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) { - struct inode *dir = d_inode(dentry->d_parent); - struct fscrypt_info *ci = dir->i_crypt_info; + struct dentry *dir; + struct fscrypt_info *ci; int dir_has_key, cached_with_key; - if (!dir->i_sb->s_cop->is_encrypted(dir)) + dir = dget_parent(dentry); + if (!d_inode(dir)->i_sb->s_cop->is_encrypted(d_inode(dir))) { + dput(dir); return 0; + } + ci = d_inode(dir)->i_crypt_info; if (ci && ci->ci_keyring_key && (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) | (1 << KEY_FLAG_REVOKED) | @@ -363,6 +367,7 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY; spin_unlock(&dentry->d_lock); dir_has_key = (ci != NULL); + dput(dir); /* * If the dentry was cached without the key, and it is a -- cgit v1.2.3 From 33b1395124c63ed4a42e33c1dd14859f9b3f29c2 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 11 Apr 2016 15:15:38 -0700 Subject: f2fs: use dget_parent and file_dentry in f2fs_file_open This patch synced with the below two ext4 crypto fixes together. In 4.6-rc1, f2fs newly introduced accessing f_path.dentry which crashes overlayfs. To fix, now we need to use file_dentry() to access that field. Fixes: c0a37d487884 ("ext4: use file_dentry()") Fixes: 9dd78d8c9a7b ("ext4: use dget_parent() in ext4_file_open()") Cc: Miklos Szeredi Cc: Theodore Ts'o Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 443e07705c2a..90d1157a09f9 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -441,7 +441,7 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma) static int f2fs_file_open(struct inode *inode, struct file *filp) { int ret = generic_file_open(inode, filp); - struct inode *dir = filp->f_path.dentry->d_parent->d_inode; + struct dentry *dir; if (!ret && f2fs_encrypted_inode(inode)) { ret = fscrypt_get_encryption_info(inode); @@ -450,9 +450,13 @@ static int f2fs_file_open(struct inode *inode, struct file *filp) if (!fscrypt_has_encryption_key(inode)) return -ENOKEY; } - if (f2fs_encrypted_inode(dir) && - !fscrypt_has_permitted_context(dir, inode)) + dir = dget_parent(file_dentry(filp)); + if (f2fs_encrypted_inode(d_inode(dir)) && + !fscrypt_has_permitted_context(d_inode(dir), inode)) { + dput(dir); return -EPERM; + } + dput(dir); return ret; } -- cgit v1.2.3 From b32e4482aadfd1322357f46d4ed8a990603664d9 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 11 Apr 2016 15:51:57 -0700 Subject: fscrypto: don't let data integrity writebacks fail with ENOMEM This patch fixes the issue introduced by the ext4 crypto fix in a same manner. For F2FS, however, we flush the pending IOs and wait for a while to acquire free memory. Fixes: c9af28fdd4492 ("ext4 crypto: don't let data integrity writebacks fail with ENOMEM") Cc: Theodore Ts'o Signed-off-by: Jaegeuk Kim --- fs/crypto/crypto.c | 36 ++++++++++++++++++++---------------- fs/f2fs/data.c | 16 +++++++++++++--- include/linux/fscrypto.h | 9 +++++---- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 58ae0ba91ca2..da70520f3ab4 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -81,13 +81,14 @@ EXPORT_SYMBOL(fscrypt_release_ctx); /** * fscrypt_get_ctx() - Gets an encryption context * @inode: The inode for which we are doing the crypto + * @gfp_flags: The gfp flag for memory allocation * * Allocates and initializes an encryption context. * * Return: An allocated and initialized encryption context on success; error * value or NULL otherwise. */ -struct fscrypt_ctx *fscrypt_get_ctx(struct inode *inode) +struct fscrypt_ctx *fscrypt_get_ctx(struct inode *inode, gfp_t gfp_flags) { struct fscrypt_ctx *ctx = NULL; struct fscrypt_info *ci = inode->i_crypt_info; @@ -113,7 +114,7 @@ struct fscrypt_ctx *fscrypt_get_ctx(struct inode *inode) list_del(&ctx->free_list); spin_unlock_irqrestore(&fscrypt_ctx_lock, flags); if (!ctx) { - ctx = kmem_cache_zalloc(fscrypt_ctx_cachep, GFP_NOFS); + ctx = kmem_cache_zalloc(fscrypt_ctx_cachep, gfp_flags); if (!ctx) return ERR_PTR(-ENOMEM); ctx->flags |= FS_CTX_REQUIRES_FREE_ENCRYPT_FL; @@ -147,7 +148,8 @@ typedef enum { static int do_page_crypto(struct inode *inode, fscrypt_direction_t rw, pgoff_t index, - struct page *src_page, struct page *dest_page) + struct page *src_page, struct page *dest_page, + gfp_t gfp_flags) { u8 xts_tweak[FS_XTS_TWEAK_SIZE]; struct skcipher_request *req = NULL; @@ -157,7 +159,7 @@ static int do_page_crypto(struct inode *inode, struct crypto_skcipher *tfm = ci->ci_ctfm; int res = 0; - req = skcipher_request_alloc(tfm, GFP_NOFS); + req = skcipher_request_alloc(tfm, gfp_flags); if (!req) { printk_ratelimited(KERN_ERR "%s: crypto_request_alloc() failed\n", @@ -199,10 +201,9 @@ static int do_page_crypto(struct inode *inode, return 0; } -static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx) +static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags) { - ctx->w.bounce_page = mempool_alloc(fscrypt_bounce_page_pool, - GFP_NOWAIT); + ctx->w.bounce_page = mempool_alloc(fscrypt_bounce_page_pool, gfp_flags); if (ctx->w.bounce_page == NULL) return ERR_PTR(-ENOMEM); ctx->flags |= FS_WRITE_PATH_FL; @@ -213,6 +214,7 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx) * fscypt_encrypt_page() - Encrypts a page * @inode: The inode for which the encryption should take place * @plaintext_page: The page to encrypt. Must be locked. + * @gfp_flags: The gfp flag for memory allocation * * Allocates a ciphertext page and encrypts plaintext_page into it using the ctx * encryption context. @@ -225,7 +227,7 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx) * error value or NULL. */ struct page *fscrypt_encrypt_page(struct inode *inode, - struct page *plaintext_page) + struct page *plaintext_page, gfp_t gfp_flags) { struct fscrypt_ctx *ctx; struct page *ciphertext_page = NULL; @@ -233,18 +235,19 @@ struct page *fscrypt_encrypt_page(struct inode *inode, BUG_ON(!PageLocked(plaintext_page)); - ctx = fscrypt_get_ctx(inode); + ctx = fscrypt_get_ctx(inode, gfp_flags); if (IS_ERR(ctx)) return (struct page *)ctx; /* The encryption operation will require a bounce page. */ - ciphertext_page = alloc_bounce_page(ctx); + ciphertext_page = alloc_bounce_page(ctx, gfp_flags); if (IS_ERR(ciphertext_page)) goto errout; ctx->w.control_page = plaintext_page; err = do_page_crypto(inode, FS_ENCRYPT, plaintext_page->index, - plaintext_page, ciphertext_page); + plaintext_page, ciphertext_page, + gfp_flags); if (err) { ciphertext_page = ERR_PTR(err); goto errout; @@ -275,7 +278,7 @@ int fscrypt_decrypt_page(struct page *page) BUG_ON(!PageLocked(page)); return do_page_crypto(page->mapping->host, - FS_DECRYPT, page->index, page, page); + FS_DECRYPT, page->index, page, page, GFP_NOFS); } EXPORT_SYMBOL(fscrypt_decrypt_page); @@ -289,11 +292,11 @@ int fscrypt_zeroout_range(struct inode *inode, pgoff_t lblk, BUG_ON(inode->i_sb->s_blocksize != PAGE_SIZE); - ctx = fscrypt_get_ctx(inode); + ctx = fscrypt_get_ctx(inode, GFP_NOFS); if (IS_ERR(ctx)) return PTR_ERR(ctx); - ciphertext_page = alloc_bounce_page(ctx); + ciphertext_page = alloc_bounce_page(ctx, GFP_NOWAIT); if (IS_ERR(ciphertext_page)) { err = PTR_ERR(ciphertext_page); goto errout; @@ -301,11 +304,12 @@ int fscrypt_zeroout_range(struct inode *inode, pgoff_t lblk, while (len--) { err = do_page_crypto(inode, FS_ENCRYPT, lblk, - ZERO_PAGE(0), ciphertext_page); + ZERO_PAGE(0), ciphertext_page, + GFP_NOFS); if (err) goto errout; - bio = bio_alloc(GFP_KERNEL, 1); + bio = bio_alloc(GFP_NOWAIT, 1); if (!bio) { err = -ENOMEM; goto errout; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 53fec0872e60..5dafb9cef12e 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -992,7 +992,7 @@ submit_and_realloc: if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { - ctx = fscrypt_get_ctx(inode); + ctx = fscrypt_get_ctx(inode, GFP_NOFS); if (IS_ERR(ctx)) goto set_error_page; @@ -1092,14 +1092,24 @@ int do_write_data_page(struct f2fs_io_info *fio) } if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { + gfp_t gfp_flags = GFP_NOFS; /* wait for GCed encrypted page writeback */ f2fs_wait_on_encrypted_page_writeback(F2FS_I_SB(inode), fio->old_blkaddr); - - fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page); +retry_encrypt: + fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page, + gfp_flags); if (IS_ERR(fio->encrypted_page)) { err = PTR_ERR(fio->encrypted_page); + if (err == -ENOMEM) { + /* flush pending ios and wait for a while */ + f2fs_flush_merged_bios(F2FS_I_SB(inode)); + congestion_wait(BLK_RW_ASYNC, HZ/50); + gfp_flags |= __GFP_NOFAIL; + err = 0; + goto retry_encrypt; + } goto out_writepage; } } diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h index cd91f75de49b..6027f6bbb061 100644 --- a/include/linux/fscrypto.h +++ b/include/linux/fscrypto.h @@ -263,9 +263,9 @@ static inline void fscrypt_set_d_op(struct dentry *dentry) extern struct kmem_cache *fscrypt_info_cachep; int fscrypt_initialize(void); -extern struct fscrypt_ctx *fscrypt_get_ctx(struct inode *); +extern struct fscrypt_ctx *fscrypt_get_ctx(struct inode *, gfp_t); extern void fscrypt_release_ctx(struct fscrypt_ctx *); -extern struct page *fscrypt_encrypt_page(struct inode *, struct page *); +extern struct page *fscrypt_encrypt_page(struct inode *, struct page *, gfp_t); extern int fscrypt_decrypt_page(struct page *); extern void fscrypt_decrypt_bio_pages(struct fscrypt_ctx *, struct bio *); extern void fscrypt_pullback_bio_page(struct page **, bool); @@ -299,7 +299,8 @@ extern int fscrypt_fname_usr_to_disk(struct inode *, const struct qstr *, #endif /* crypto.c */ -static inline struct fscrypt_ctx *fscrypt_notsupp_get_ctx(struct inode *i) +static inline struct fscrypt_ctx *fscrypt_notsupp_get_ctx(struct inode *i, + gfp_t f) { return ERR_PTR(-EOPNOTSUPP); } @@ -310,7 +311,7 @@ static inline void fscrypt_notsupp_release_ctx(struct fscrypt_ctx *c) } static inline struct page *fscrypt_notsupp_encrypt_page(struct inode *i, - struct page *p) + struct page *p, gfp_t f) { return ERR_PTR(-EOPNOTSUPP); } -- cgit v1.2.3 From 3137b716568f3ca8ca575fd13b91ddb42abd6844 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 25 Mar 2016 11:14:02 +0900 Subject: ARM: uniphier: drop weird sizeof() My intention was to ioremap a 4-byte register. Coincidentally enough, sizeof(SZ_4) equals to SZ_4, but this code is weird anyway. Signed-off-by: Masahiro Yamada Signed-off-by: Olof Johansson --- arch/arm/mach-uniphier/platsmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-uniphier/platsmp.c b/arch/arm/mach-uniphier/platsmp.c index 69141357afe8..db04142f88bc 100644 --- a/arch/arm/mach-uniphier/platsmp.c +++ b/arch/arm/mach-uniphier/platsmp.c @@ -120,7 +120,7 @@ static int __init uniphier_smp_prepare_trampoline(unsigned int max_cpus) if (ret) return ret; - uniphier_smp_rom_boot_rsv2 = ioremap(rom_rsv2_phys, sizeof(SZ_4)); + uniphier_smp_rom_boot_rsv2 = ioremap(rom_rsv2_phys, SZ_4); if (!uniphier_smp_rom_boot_rsv2) { pr_err("failed to map ROM_BOOT_RSV2 register\n"); return -ENOMEM; -- cgit v1.2.3 From 3de7beebddf8d56dcaa17b41c723d602dd0c513c Mon Sep 17 00:00:00 2001 From: Kunihiko Hayashi Date: Fri, 1 Apr 2016 19:32:43 +0900 Subject: bus: uniphier-system-bus: fix condition of overlap check This patch fixes condition whether the specified address ranges overlap each other. Fixes: 4b7f48d395a7 ("bus: uniphier-system-bus: add UniPhier System Bus driver") Signed-off-by: Kunihiko Hayashi Acked-by: Masahiro Yamada Signed-off-by: Olof Johansson --- drivers/bus/uniphier-system-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bus/uniphier-system-bus.c b/drivers/bus/uniphier-system-bus.c index 834a2aeaf27a..350b7309c26d 100644 --- a/drivers/bus/uniphier-system-bus.c +++ b/drivers/bus/uniphier-system-bus.c @@ -108,7 +108,7 @@ static int uniphier_system_bus_check_overlap( for (i = 0; i < ARRAY_SIZE(priv->bank); i++) { for (j = i + 1; j < ARRAY_SIZE(priv->bank); j++) { - if (priv->bank[i].end > priv->bank[j].base || + if (priv->bank[i].end > priv->bank[j].base && priv->bank[i].base < priv->bank[j].end) { dev_err(priv->dev, "region overlap between bank%d and bank%d\n", -- cgit v1.2.3 From 452a31fd36255fc7d9dd9dce9d820fe0e5bb97b8 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 4 Apr 2016 14:43:38 +0200 Subject: ARM: sa1100: remove references to the defunct handhelds.org The website handhelds.org has been down for a long time and is likely never coming back online. Signed-off-by: Linus Walleij Signed-off-by: Olof Johansson --- arch/arm/mach-sa1100/Kconfig | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig index c6f6ed1cbed0..36e3c79f4973 100644 --- a/arch/arm/mach-sa1100/Kconfig +++ b/arch/arm/mach-sa1100/Kconfig @@ -61,10 +61,7 @@ config SA1100_H3100 select MFD_IPAQ_MICRO help Say Y here if you intend to run this kernel on the Compaq iPAQ - H3100 handheld computer. Information about this machine and the - Linux port to this machine can be found at: - - + H3100 handheld computer. config SA1100_H3600 bool "Compaq iPAQ H3600/H3700" @@ -73,10 +70,7 @@ config SA1100_H3600 select MFD_IPAQ_MICRO help Say Y here if you intend to run this kernel on the Compaq iPAQ - H3600 handheld computer. Information about this machine and the - Linux port to this machine can be found at: - - + H3600 and H3700 handheld computers. config SA1100_BADGE4 bool "HP Labs BadgePAD 4" -- cgit v1.2.3 From e1123fe975852cc0970b4e53ea65ca917e54c923 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 12 Apr 2016 13:37:45 -0700 Subject: HID: wacom: Add support for DTK-1651 DTK-1651 is a display pen-only tablet Signed-off-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 02c4efea241c..e9902f2f8ec9 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -3395,6 +3395,10 @@ static const struct wacom_features wacom_features_0x33E = { "Wacom Intuos PT M 2", 21600, 13500, 2047, 63, INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16, .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; +static const struct wacom_features wacom_features_0x343 = + { "Wacom DTK1651", 34616, 19559, 1023, 0, + DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4, + WACOM_DTU_OFFSET, WACOM_DTU_OFFSET }; static const struct wacom_features wacom_features_HID_ANY_ID = { "Wacom HID", .type = HID_GENERIC }; @@ -3560,6 +3564,7 @@ const struct hid_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x33C) }, { USB_DEVICE_WACOM(0x33D) }, { USB_DEVICE_WACOM(0x33E) }, + { USB_DEVICE_WACOM(0x343) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x4004) }, { USB_DEVICE_WACOM(0x5000) }, -- cgit v1.2.3 From b0b6d123f5df189d7d3a62d450e5f5c33ad614d8 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Mon, 14 Mar 2016 11:09:15 +0800 Subject: i2c: rk3x: add support for rk3228 Enable the I2C core for this SoC. Signed-off-by: Yakir Yang Reviewed-by: Heiko Stuebner Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-rk3x.txt | 4 ++-- drivers/i2c/busses/i2c-rk3x.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt b/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt index f0d71bc52e64..0b4a85fe2d86 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt @@ -6,8 +6,8 @@ RK3xxx SoCs. Required properties : - reg : Offset and length of the register set for the device - - compatible : should be "rockchip,rk3066-i2c", "rockchip,rk3188-i2c" or - "rockchip,rk3288-i2c". + - compatible : should be "rockchip,rk3066-i2c", "rockchip,rk3188-i2c", + "rockchip,rk3228-i2c" or "rockchip,rk3288-i2c". - interrupts : interrupt number - clocks : parent clock diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index 9096d17beb5b..3dcc5f3f26cb 100644 --- a/drivers/i2c/busses/i2c-rk3x.c +++ b/drivers/i2c/busses/i2c-rk3x.c @@ -855,6 +855,7 @@ static struct rk3x_i2c_soc_data soc_data[3] = { static const struct of_device_id rk3x_i2c_match[] = { { .compatible = "rockchip,rk3066-i2c", .data = (void *)&soc_data[0] }, { .compatible = "rockchip,rk3188-i2c", .data = (void *)&soc_data[1] }, + { .compatible = "rockchip,rk3228-i2c", .data = (void *)&soc_data[2] }, { .compatible = "rockchip,rk3288-i2c", .data = (void *)&soc_data[2] }, {}, }; -- cgit v1.2.3 From 8574ad7800ad298dc7f184f12b454a67fa3dd839 Mon Sep 17 00:00:00 2001 From: Tanmay Jagdale Date: Mon, 11 Apr 2016 18:01:26 +0530 Subject: i2c: xlp9xx: add support for Broadcom Vulcan The Broadcom Vulcan ARM64 processor uses the same I2C controller present on the Broadcom XLP9xx/5xx MIPS processor family. Updated the Kconfig by adding ARCH_VULCAN option. Signed-off-by: Tanmay Jagdale Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index faa8e6821fea..0967e1a5b3a2 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -975,10 +975,10 @@ config I2C_XLR config I2C_XLP9XX tristate "XLP9XX I2C support" - depends on CPU_XLP || COMPILE_TEST + depends on CPU_XLP || ARCH_VULCAN || COMPILE_TEST help This driver enables support for the on-chip I2C interface of - the Broadcom XLP9xx/XLP5xx MIPS processors. + the Broadcom XLP9xx/XLP5xx MIPS and Vulcan ARM64 processors. This driver can also be built as a module. If so, the module will be called i2c-xlp9xx. -- cgit v1.2.3 From abaa7b0c1286ca1610a6dfa079e1d2e27dca1f25 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 8 Apr 2016 15:41:08 +0300 Subject: i2c: ismt: Add Intel DNV PCI ID Intel DNV has the same iSMT SMBus host controller than Intel Avoton. Add DNV PCI ID to the list of supported devices. Signed-off-by: Mika Westerberg Acked-by: Andy Shevchenko Acked-by: Neil Horman Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-ismt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c index 7ba795b24e75..1c8707710098 100644 --- a/drivers/i2c/busses/i2c-ismt.c +++ b/drivers/i2c/busses/i2c-ismt.c @@ -75,6 +75,7 @@ /* PCI DIDs for the Intel SMBus Message Transport (SMT) Devices */ #define PCI_DEVICE_ID_INTEL_S1200_SMT0 0x0c59 #define PCI_DEVICE_ID_INTEL_S1200_SMT1 0x0c5a +#define PCI_DEVICE_ID_INTEL_DNV_SMT 0x19ac #define PCI_DEVICE_ID_INTEL_AVOTON_SMT 0x1f15 #define ISMT_DESC_ENTRIES 2 /* number of descriptor entries */ @@ -180,6 +181,7 @@ struct ismt_priv { static const struct pci_device_id ismt_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMT) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) }, { 0, } }; -- cgit v1.2.3 From 87243deb88671f70def4c52dfa7ca7830707bd31 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Wed, 9 Mar 2016 09:18:07 -0600 Subject: debugfs: Make automount point inodes permanently empty Starting with 4.1 the tracing subsystem has its own filesystem which is automounted in the tracing subdirectory of debugfs. Prior to this debugfs could be bind mounted in a cloned mount namespace, but if tracefs has been mounted under debugfs this now fails because there is a locked child mount. This creates a regression for container software which bind mounts debugfs to satisfy the assumption of some userspace software. In other pseudo filesystems such as proc and sysfs we're already creating mountpoints like this in such a way that no dirents can be created in the directories, allowing them to be exceptions to some MNT_LOCKED tests. In fact we're already do this for the tracefs mountpoint in sysfs. Do the same in debugfs_create_automount(), since the intention here is clearly to create a mountpoint. This fixes the regression, as locked child mounts on permanently empty directories do not cause a bind mount to fail. Cc: stable@vger.kernel.org # v4.1+ Signed-off-by: Seth Forshee Acked-by: Serge Hallyn Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index bece948b363d..8580831ed237 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -457,7 +457,7 @@ struct dentry *debugfs_create_automount(const char *name, if (unlikely(!inode)) return failed_creating(dentry); - inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; + make_empty_dir_inode(inode); inode->i_flags |= S_AUTOMOUNT; inode->i_private = data; dentry->d_fsdata = (void *)f; -- cgit v1.2.3 From bcf4934288402be3464110109a4dae3bd6fb3e93 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Tue, 12 Apr 2016 01:31:14 +0200 Subject: netfilter: ebtables: Fix extension lookup with identical name If a requested extension exists as module and is not loaded, ebt_check_match() might accidentally use an NFPROTO_UNSPEC one with same name and fail. Reproduced with limit match: Given xt_limit and ebt_limit both built as module, the following would fail: modprobe xt_limit ebtables -I INPUT --limit 1/s -j ACCEPT The fix is to make ebt_check_match() distrust a found NFPROTO_UNSPEC extension and retry after requesting an appropriate module. Cc: Florian Westphal Signed-off-by: Phil Sutter Acked-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/bridge/netfilter/ebtables.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 8570bc7744c2..5a61f35412a0 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -370,7 +370,11 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par, left - sizeof(struct ebt_entry_match) < m->match_size) return -EINVAL; - match = xt_request_find_match(NFPROTO_BRIDGE, m->u.name, 0); + match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); + if (IS_ERR(match) || match->family != NFPROTO_BRIDGE) { + request_module("ebt_%s", m->u.name); + match = xt_find_match(NFPROTO_BRIDGE, m->u.name, 0); + } if (IS_ERR(match)) return PTR_ERR(match); m->u.match = match; -- cgit v1.2.3 From 03a8bb0e53d9562276045bdfcf2b5de2e4cff5a1 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 12 Apr 2016 16:05:36 -0700 Subject: ext4/fscrypto: avoid RCU lookup in d_revalidate As Al pointed, d_revalidate should return RCU lookup before using d_inode. This was originally introduced by: commit 34286d666230 ("fs: rcu-walk aware d_revalidate method"). Reported-by: Al Viro Signed-off-by: Jaegeuk Kim Cc: Theodore Ts'o Cc: stable --- fs/crypto/crypto.c | 4 ++++ fs/ext4/crypto.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index da70520f3ab4..2fc8c43ce531 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -353,6 +354,9 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) struct fscrypt_info *ci; int dir_has_key, cached_with_key; + if (flags & LOOKUP_RCU) + return -ECHILD; + dir = dget_parent(dentry); if (!d_inode(dir)->i_sb->s_cop->is_encrypted(d_inode(dir))) { dput(dir); diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c index db9ae6e18154..6a6c27373b54 100644 --- a/fs/ext4/crypto.c +++ b/fs/ext4/crypto.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "ext4_extents.h" #include "xattr.h" @@ -482,6 +483,9 @@ static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags) struct ext4_crypt_info *ci; int dir_has_key, cached_with_key; + if (flags & LOOKUP_RCU) + return -ECHILD; + dir = dget_parent(dentry); if (!ext4_encrypted_inode(d_inode(dir))) { dput(dir); -- cgit v1.2.3 From 7196c52c9377df0175b510ff5896bda524f7345e Mon Sep 17 00:00:00 2001 From: Lothar Waßmann Date: Wed, 30 Mar 2016 14:23:03 +0200 Subject: clk: imx6q: fix typo in CAN clock definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit ee36027427c7 ("clk: imx: Add clock support for imx6qp") introduced a regression due to a subtle typo in the 'can_root' clock definition. The effect is that trying to configure the bitrate of the can interfaces fails with -EDOM or produces a division by zero error due to the clock_freq of the can serial clock being reported as '0'. Signed-off-by: Lothar Waßmann Fixes: ee36027427c7 ("clk: imx: Add clock support for imx6qp") Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx6q.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index 02e18182fcb5..2beb396fe652 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -394,7 +394,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1", 2, 7); } else { clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); - clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60", base + 0x20, 2, 6); + clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6); clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup); clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); -- cgit v1.2.3 From 023d8218ec0dfc30e11d4ec54f640e8f127d1fbe Mon Sep 17 00:00:00 2001 From: Hyungwon Hwang Date: Wed, 13 Apr 2016 09:27:39 +0900 Subject: ALSA: hda - Fix regression of monitor_present flag in eld proc file The commit [bd48128539ab: ALSA: hda - Fix forgotten HDMI monitor_present update] covered the missing update of monitor_present flag, but this caused a regression for devices without the i915 eld notifier. Since the old code supposed that pin_eld->monitor_present was updated by the caller side, the hdmi_present_sense_via_verbs() doesn't update the temporary eld->monitor_present but only pin_eld->monitor_present, which is now overridden in update_eld(). The fix is to update pin_eld->monitor_present as well before calling update_eld(). Note that this may still leave monitor_present flag in an inconsistent state when the driver repolls, but this is at least the old behavior. More proper fix will follow in the later patch. Fixes: bd48128539ab ('ALSA: hda - Fix forgotten HDMI monitor_present update') Signed-off-by: Hyungwon Hwang Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 5af372d01834..9de114df270b 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1414,6 +1414,8 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, mutex_lock(&per_pin->lock); pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); + eld->monitor_present = pin_eld->monitor_present; + if (pin_eld->monitor_present) eld->eld_valid = !!(present & AC_PINSENSE_ELDV); else -- cgit v1.2.3 From c44da62b55bb453052869ab095bcda7aa0bd6bba Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Apr 2016 09:45:53 +0200 Subject: ALSA: hda - Fix inconsistent monitor_present state until repoll While the previous commit fixed the missing monitor_present flag update, it may be still in an inconsistent state while the driver repolls: the flag itself is updated, but the eld_valid flag and the contents don't follow until the repoll finishes (and may be repeated for a few times). The basic problem is that pin_eld->monitor_present is updated in the caller side. This should have been updated only in update_eld(). So, the proper fix is to avoid accessing pin_eld but only spec->temp_eld. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 9de114df270b..c83c1a8d9742 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1396,7 +1396,6 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, struct hda_codec *codec = per_pin->codec; struct hdmi_spec *spec = codec->spec; struct hdmi_eld *eld = &spec->temp_eld; - struct hdmi_eld *pin_eld = &per_pin->sink_eld; hda_nid_t pin_nid = per_pin->pin_nid; /* * Always execute a GetPinSense verb here, even when called from @@ -1413,17 +1412,15 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, present = snd_hda_pin_sense(codec, pin_nid); mutex_lock(&per_pin->lock); - pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); - eld->monitor_present = pin_eld->monitor_present; - - if (pin_eld->monitor_present) + eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); + if (eld->monitor_present) eld->eld_valid = !!(present & AC_PINSENSE_ELDV); else eld->eld_valid = false; codec_dbg(codec, "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", - codec->addr, pin_nid, pin_eld->monitor_present, eld->eld_valid); + codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); if (eld->eld_valid) { if (spec->ops.pin_get_eld(codec, pin_nid, eld->eld_buffer, @@ -1443,7 +1440,7 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, else update_eld(codec, per_pin, eld); - ret = !repoll || !pin_eld->monitor_present || pin_eld->eld_valid; + ret = !repoll || !eld->monitor_present || eld->eld_valid; jack = snd_hda_jack_tbl_get(codec, pin_nid); if (jack) -- cgit v1.2.3 From fc26fe9c3869f02dd9dc54ff3a45c6d9d4bbbdfa Mon Sep 17 00:00:00 2001 From: Alexander Kurz Date: Mon, 11 Apr 2016 10:20:46 +0200 Subject: ARM: mach-imx: sdhci-esdhc-imx: initialize DMA mask With commit 7b91369b4655 ("mmc: sdhci: Set DMA mask when adding host") DMA access got disabled for device drivers with zero DMA mask property. sdhci-esdhc-imx got blocked from DMA access by this. Hence: initialize the DMA mask to enable access again. Signed-off-by: Alexander Kurz Signed-off-by: Shawn Guo --- arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c b/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c index a5edd7d60266..3d039ef021e0 100644 --- a/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c +++ b/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c @@ -71,6 +71,7 @@ struct platform_device *__init imx_add_sdhci_esdhc_imx( if (!pdata) pdata = &default_esdhc_pdata; - return imx_add_platform_device(data->devid, data->id, res, - ARRAY_SIZE(res), pdata, sizeof(*pdata)); + return imx_add_platform_device_dmamask(data->devid, data->id, res, + ARRAY_SIZE(res), pdata, sizeof(*pdata), + DMA_BIT_MASK(32)); } -- cgit v1.2.3 From a3125494cff084b098c80bb36fbe2061ffed9d52 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 6 Apr 2016 10:05:16 +0200 Subject: x86/mce: Avoid using object after free in genpool When we loop over all queued machine check error records to pass them to the registered notifiers we use llist_for_each_entry(). But the loop calls gen_pool_free() for the entry in the body of the loop - and then the iterator looks at node->next after the free. Use llist_for_each_entry_safe() instead. Signed-off-by: Tony Luck Signed-off-by: Borislav Petkov Cc: Cc: Gong Chen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-edac Link: http://lkml.kernel.org/r/0205920@agluck-desk.sc.intel.com Link: http://lkml.kernel.org/r/1459929916-12852-4-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/mcheck/mce-genpool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce-genpool.c b/arch/x86/kernel/cpu/mcheck/mce-genpool.c index 0a850100c594..2658e2af74ec 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-genpool.c +++ b/arch/x86/kernel/cpu/mcheck/mce-genpool.c @@ -29,7 +29,7 @@ static char gen_pool_buf[MCE_POOLSZ]; void mce_gen_pool_process(void) { struct llist_node *head; - struct mce_evt_llist *node; + struct mce_evt_llist *node, *tmp; struct mce *mce; head = llist_del_all(&mce_event_llist); @@ -37,7 +37,7 @@ void mce_gen_pool_process(void) return; head = llist_reverse_order(head); - llist_for_each_entry(node, head, llnode) { + llist_for_each_entry_safe(node, tmp, head, llnode) { mce = &node->mce; atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce); gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node)); -- cgit v1.2.3 From d9c9f3b809d2bb0356f013e88d10730eafab5346 Mon Sep 17 00:00:00 2001 From: James Liao Date: Tue, 12 Apr 2016 16:34:30 +0800 Subject: Revert "soc: mediatek: SCPSYS: Fix double enabling of regulators" This reverts commit cc8ed76938b5cf6a54ab3d60edabaf808dc960d1 ("soc: mediatek: SCPSYS: Fix double enabling of regulators") [1]. This patch fixes mt8173-evb failing boot issue. With commit [1], genpd state will not sync to real power domain state. So some resources such as clocks and regulators may stay in a wrong state. There is no regulator double enabling issue on mainline kernel, so we can refert commit [1] safely. Signed-off-by: James Liao Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-scpsys.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index 57e781c71e67..837effe19907 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -491,13 +491,14 @@ static int scpsys_probe(struct platform_device *pdev) genpd->dev_ops.active_wakeup = scpsys_active_wakeup; /* - * With CONFIG_PM disabled turn on all domains to make the - * hardware usable. + * Initially turn on all domains to make the domains usable + * with !CONFIG_PM and to get the hardware in sync with the + * software. The unused domains will be switched off during + * late_init time. */ - if (!IS_ENABLED(CONFIG_PM)) - genpd->power_on(genpd); + genpd->power_on(genpd); - pm_genpd_init(genpd, NULL, true); + pm_genpd_init(genpd, NULL, false); } /* -- cgit v1.2.3 From 0311c76e4722b8d6e5fa47eaee63c6552bcc74f5 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 24 Mar 2016 22:29:01 +0100 Subject: phy: rockchip-dp: should be a child device of the GRF The displayport-phy is fully enclosed in the general register files (GRF). Therefore as seen from the device-tree it shouldn't be a separate platform- device but instead a sub-device of the GRF - using the simply-mfd mechanism. The driver entered the kernel in the current merge-window, so we can still adapt the binding without needing a fallback, as the binding hasn't been released with a full kernel yet. While the edp phy is fully part of the GRF, it doesn't have any separate register set there, so doesn't get any register-area assigned. Signed-off-by: Heiko Stuebner Acked-by: Rob Herring Reviewed-by: Yakir Yang Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/rockchip-dp-phy.txt | 18 +++++++++++------- drivers/phy/phy-rockchip-dp.c | 7 +++++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt index 50c4f9b00adf..e3b4809fbe82 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt @@ -8,15 +8,19 @@ Required properties: of memory mapped region. - clock-names: from common clock binding: Required elements: "24m" -- rockchip,grf: phandle to the syscon managing the "general register files" - #phy-cells : from the generic PHY bindings, must be 0; Example: -edp_phy: edp-phy { - compatible = "rockchip,rk3288-dp-phy"; - rockchip,grf = <&grf>; - clocks = <&cru SCLK_EDP_24M>; - clock-names = "24m"; - #phy-cells = <0>; +grf: syscon@ff770000 { + compatible = "rockchip,rk3288-grf", "syscon", "simple-mfd"; + +... + + edp_phy: edp-phy { + compatible = "rockchip,rk3288-dp-phy"; + clocks = <&cru SCLK_EDP_24M>; + clock-names = "24m"; + #phy-cells = <0>; + }; }; diff --git a/drivers/phy/phy-rockchip-dp.c b/drivers/phy/phy-rockchip-dp.c index 77e2d02e6bee..793ecb6d87bc 100644 --- a/drivers/phy/phy-rockchip-dp.c +++ b/drivers/phy/phy-rockchip-dp.c @@ -86,6 +86,9 @@ static int rockchip_dp_phy_probe(struct platform_device *pdev) if (!np) return -ENODEV; + if (!dev->parent || !dev->parent->of_node) + return -ENODEV; + dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); if (IS_ERR(dp)) return -ENOMEM; @@ -104,9 +107,9 @@ static int rockchip_dp_phy_probe(struct platform_device *pdev) return ret; } - dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); + dp->grf = syscon_node_to_regmap(dev->parent->of_node); if (IS_ERR(dp->grf)) { - dev_err(dev, "rk3288-dp needs rockchip,grf property\n"); + dev_err(dev, "rk3288-dp needs the General Register Files syscon\n"); return PTR_ERR(dp->grf); } -- cgit v1.2.3 From 332184adff50de9596f03735496c545e8bccc73e Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 24 Mar 2016 22:29:02 +0100 Subject: phy: rockchip-emmc: should be a child device of the GRF The emmc-phy is fully enclosed in the general register files (GRF). Therefore as seen from the device-tree it shouldn't be a separate platform- device but instead a sub-device of the GRF - using the simply-mfd mechanism. The driver entered the kernel in the current merge-window, so we can still adapt the binding without needing a fallback, as the binding hasn't been released with a full kernel yet. Signed-off-by: Heiko Stuebner Acked-by: Rob Herring Reviewed-by: Shawn Lin Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/rockchip-emmc-phy.txt | 18 +++++++++++------- drivers/phy/phy-rockchip-emmc.c | 5 ++++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt index 61916f15a949..461e9580aa45 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt @@ -3,17 +3,21 @@ Rockchip EMMC PHY Required properties: - compatible: rockchip,rk3399-emmc-phy - - rockchip,grf : phandle to the syscon managing the "general - register files" - #phy-cells: must be 0 - reg: PHY configure reg address offset in "general register files" Example: -emmcphy: phy { - compatible = "rockchip,rk3399-emmc-phy"; - rockchip,grf = <&grf>; - reg = <0xf780>; - #phy-cells = <0>; + +grf: syscon@ff770000 { + compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd"; + +... + + emmcphy: phy@f780 { + compatible = "rockchip,rk3399-emmc-phy"; + reg = <0xf780>; + #phy-cells = <0>; + }; }; diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c index 887b4c27195f..6ebcf3e41c46 100644 --- a/drivers/phy/phy-rockchip-emmc.c +++ b/drivers/phy/phy-rockchip-emmc.c @@ -176,7 +176,10 @@ static int rockchip_emmc_phy_probe(struct platform_device *pdev) struct regmap *grf; unsigned int reg_offset; - grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); + if (!dev->parent || !dev->parent->of_node) + return -ENODEV; + + grf = syscon_node_to_regmap(dev->parent->of_node); if (IS_ERR(grf)) { dev_err(dev, "Missing rockchip,grf property\n"); return PTR_ERR(grf); -- cgit v1.2.3 From 5128de85124c728cdbb6b35bd9dc7410f02c0ca1 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 24 Mar 2016 22:29:03 +0100 Subject: phy: rockchip-emmc: adapt binding to specifiy register offset and length The emmc-phy occupies a contiguous set of 8 registers inside the general register files, so the reg property should specify this. Signed-off-by: Heiko Stuebner Acked-by: Rob Herring Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt index 461e9580aa45..555cb0f40690 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-emmc-phy.txt @@ -4,7 +4,7 @@ Rockchip EMMC PHY Required properties: - compatible: rockchip,rk3399-emmc-phy - #phy-cells: must be 0 - - reg: PHY configure reg address offset in "general + - reg: PHY register address offset and length in "general register files" Example: @@ -12,12 +12,14 @@ Example: grf: syscon@ff770000 { compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; ... emmcphy: phy@f780 { compatible = "rockchip,rk3399-emmc-phy"; - reg = <0xf780>; + reg = <0xf780 0x20>; #phy-cells = <0>; }; }; -- cgit v1.2.3 From 3fe6409c23e2bee4b2b1b6d671d2da8daa15271c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 8 Apr 2016 16:22:17 +0300 Subject: dmaengine: dw: fix master selection The commit 895005202987 ("dmaengine: dw: apply both HS interfaces and remove slave_id usage") cleaned up the code to avoid usage of depricated slave_id member of generic slave configuration. Meanwhile it broke the master selection by removing important call to dwc_set_masters() in ->device_alloc_chan_resources() which copied masters from custom slave configuration to the internal channel structure. Everything works until now since there is no customized connection of DesignWare DMA IP to the bus, i.e. one bus and one or more masters are in use. The configurations where 2 masters are connected to the different masters are not working anymore. We are expecting one user of such configuration and need to select masters properly. Besides that it is obviously a performance regression since only one master is in use in multi-master configuration. Select masters in accordance with what user asked for. Keep this patch in a form more suitable for back porting. We are safe to take necessary data in ->device_alloc_chan_resources() because we don't support generic slave configuration embedded into custom one, and thus the only way to provide such is to use the parameter to a filter function which is called exactly before channel resource allocation. While here, replase BUG_ON to less noisy dev_warn() and prevent channel allocation in case of error. Fixes: 895005202987 ("dmaengine: dw: apply both HS interfaces and remove slave_id usage") Cc: stable@vger.kernel.org Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul --- drivers/dma/dw/core.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 5ad0ec1f0e29..97199b3c25a2 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -130,26 +130,14 @@ static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc) static void dwc_initialize(struct dw_dma_chan *dwc) { struct dw_dma *dw = to_dw_dma(dwc->chan.device); - struct dw_dma_slave *dws = dwc->chan.private; u32 cfghi = DWC_CFGH_FIFO_MODE; u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority); if (dwc->initialized == true) return; - if (dws) { - /* - * We need controller-specific data to set up slave - * transfers. - */ - BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev); - - cfghi |= DWC_CFGH_DST_PER(dws->dst_id); - cfghi |= DWC_CFGH_SRC_PER(dws->src_id); - } else { - cfghi |= DWC_CFGH_DST_PER(dwc->dst_id); - cfghi |= DWC_CFGH_SRC_PER(dwc->src_id); - } + cfghi |= DWC_CFGH_DST_PER(dwc->dst_id); + cfghi |= DWC_CFGH_SRC_PER(dwc->src_id); channel_writel(dwc, CFG_LO, cfglo); channel_writel(dwc, CFG_HI, cfghi); @@ -941,7 +929,7 @@ bool dw_dma_filter(struct dma_chan *chan, void *param) struct dw_dma_chan *dwc = to_dw_dma_chan(chan); struct dw_dma_slave *dws = param; - if (!dws || dws->dma_dev != chan->device->dev) + if (dws->dma_dev != chan->device->dev) return false; /* We have to copy data since dws can be temporary storage */ @@ -1165,6 +1153,14 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) * doesn't mean what you think it means), and status writeback. */ + /* + * We need controller-specific data to set up slave transfers. + */ + if (chan->private && !dw_dma_filter(chan, chan->private)) { + dev_warn(chan2dev(chan), "Wrong controller-specific data\n"); + return -EINVAL; + } + /* Enable controller here if needed */ if (!dw->in_use) dw_dma_on(dw); @@ -1226,6 +1222,14 @@ static void dwc_free_chan_resources(struct dma_chan *chan) spin_lock_irqsave(&dwc->lock, flags); list_splice_init(&dwc->free_list, &list); dwc->descs_allocated = 0; + + /* Clear custom channel configuration */ + dwc->src_id = 0; + dwc->dst_id = 0; + + dwc->src_master = 0; + dwc->dst_master = 0; + dwc->initialized = false; /* Disable interrupts */ -- cgit v1.2.3 From 3e26a691fe3fe1e02a76e5bab0c143ace4b137b4 Mon Sep 17 00:00:00 2001 From: Rui Salvaterra Date: Sat, 9 Apr 2016 22:05:34 +0100 Subject: lib: lz4: fixed zram with lz4 on big endian machines Based on Sergey's test patch [1], this fixes zram with lz4 compression on big endian cpus. Note that the 64-bit preprocessor test is not a cleanup, it's part of the fix, since those identifiers are bogus (for example, __ppc64__ isn't defined anywhere else in the kernel, which means we'd fall into the 32-bit definitions on ppc64). Tested on ppc64 with no regression on x86_64. [1] http://marc.info/?l=linux-kernel&m=145994470805853&w=4 Cc: stable@vger.kernel.org Suggested-by: Sergey Senozhatsky Signed-off-by: Rui Salvaterra Reviewed-by: Sergey Senozhatsky Signed-off-by: Greg Kroah-Hartman --- lib/lz4/lz4defs.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/lz4/lz4defs.h b/lib/lz4/lz4defs.h index abcecdc2d0f2..0710a62ad2f6 100644 --- a/lib/lz4/lz4defs.h +++ b/lib/lz4/lz4defs.h @@ -11,8 +11,7 @@ /* * Detects 64 bits mode */ -#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) \ - || defined(__ppc64__) || defined(__LP64__)) +#if defined(CONFIG_64BIT) #define LZ4_ARCH64 1 #else #define LZ4_ARCH64 0 @@ -35,6 +34,10 @@ typedef struct _U64_S { u64 v; } U64_S; #define PUT4(s, d) (A32(d) = A32(s)) #define PUT8(s, d) (A64(d) = A64(s)) + +#define LZ4_READ_LITTLEENDIAN_16(d, s, p) \ + (d = s - A16(p)) + #define LZ4_WRITE_LITTLEENDIAN_16(p, v) \ do { \ A16(p) = v; \ @@ -51,10 +54,13 @@ typedef struct _U64_S { u64 v; } U64_S; #define PUT8(s, d) \ put_unaligned(get_unaligned((const u64 *) s), (u64 *) d) -#define LZ4_WRITE_LITTLEENDIAN_16(p, v) \ - do { \ - put_unaligned(v, (u16 *)(p)); \ - p += 2; \ +#define LZ4_READ_LITTLEENDIAN_16(d, s, p) \ + (d = s - get_unaligned_le16(p)) + +#define LZ4_WRITE_LITTLEENDIAN_16(p, v) \ + do { \ + put_unaligned_le16(v, (u16 *)(p)); \ + p += 2; \ } while (0) #endif @@ -140,9 +146,6 @@ typedef struct _U64_S { u64 v; } U64_S; #endif -#define LZ4_READ_LITTLEENDIAN_16(d, s, p) \ - (d = s - get_unaligned_le16(p)) - #define LZ4_WILDCOPY(s, d, e) \ do { \ LZ4_COPYPACKET(s, d); \ -- cgit v1.2.3 From dea5c24a14047b7d6b6b269434a85ffd05f1d2cb Mon Sep 17 00:00:00 2001 From: Rui Salvaterra Date: Sat, 9 Apr 2016 22:05:35 +0100 Subject: lib: lz4: cleanup unaligned access efficiency detection These identifiers are bogus. The interested architectures should define HAVE_EFFICIENT_UNALIGNED_ACCESS whenever relevant to do so. If this isn't true for some arch, it should be fixed in the arch definition. Signed-off-by: Rui Salvaterra Reviewed-by: Sergey Senozhatsky Signed-off-by: Greg Kroah-Hartman --- lib/lz4/lz4defs.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/lz4/lz4defs.h b/lib/lz4/lz4defs.h index 0710a62ad2f6..c79d7ea8a38e 100644 --- a/lib/lz4/lz4defs.h +++ b/lib/lz4/lz4defs.h @@ -24,9 +24,7 @@ typedef struct _U16_S { u16 v; } U16_S; typedef struct _U32_S { u32 v; } U32_S; typedef struct _U64_S { u64 v; } U64_S; -#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) \ - || defined(CONFIG_ARM) && __LINUX_ARM_ARCH__ >= 6 \ - && defined(ARM_EFFICIENT_UNALIGNED_ACCESS) +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) #define A16(x) (((U16_S *)(x))->v) #define A32(x) (((U32_S *)(x))->v) -- cgit v1.2.3 From 2a14759a03a0a57b2fc99b1e416180788b8ba24c Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 4 Apr 2016 14:30:53 +0200 Subject: cdc-acm: fix crash if flushed with nothing buffered Under some circumstances acm_tty_flush_chars() is called with no buffer to flush. We simply need to do nothing. Signed-off-by: Oliver Neukum Reported-by: Torsten Hilbrich Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 83fd30b0577c..a6c4a1b895bd 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -744,11 +744,15 @@ static void acm_tty_flush_chars(struct tty_struct *tty) int err; unsigned long flags; + if (!cur) /* nothing to do */ + return; + acm->putbuffer = NULL; err = usb_autopm_get_interface_async(acm->control); spin_lock_irqsave(&acm->write_lock, flags); if (err < 0) { cur->use = 0; + acm->putbuffer = cur; goto out; } -- cgit v1.2.3 From 0d46faca6f887a849efb07c1655b5a9f7c288b45 Mon Sep 17 00:00:00 2001 From: Rafal Redzimski Date: Fri, 8 Apr 2016 16:25:05 +0300 Subject: usb: xhci: applying XHCI_PME_STUCK_QUIRK to Intel BXT B0 host Broxton B0 also requires XHCI_PME_STUCK_QUIRK. Adding PCI device ID for Broxton B and adding to quirk. Cc: Signed-off-by: Rafal Redzimski Signed-off-by: Robert Dobrowolski Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index f0640b7a1c42..071b34ae9c4e 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -48,6 +48,7 @@ #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f #define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8 +#define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI 0x1aa8 static const char hcd_name[] = "xhci_hcd"; @@ -155,7 +156,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI)) { + pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) { xhci->quirks |= XHCI_PME_STUCK_QUIRK; } if (pdev->vendor == PCI_VENDOR_ID_INTEL && -- cgit v1.2.3 From 671ffdff5b13314b1fc65d62cf7604b873fb5dc4 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 8 Apr 2016 16:25:06 +0300 Subject: xhci: resume USB 3 roothub first Give USB3 devices a better chance to enumerate at USB 3 speeds if they are connected to a suspended host. Solves an issue with NEC uPD720200 host hanging when partially enumerating a USB3 device as USB2 after host controller runtime resume. Cc: Tested-by: Mike Murdoch Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index d51ee0c3cf9f..b60928802686 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1108,8 +1108,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) /* Resume root hubs only when have pending events. */ status = readl(&xhci->op_regs->status); if (status & STS_EINT) { - usb_hcd_resume_root_hub(hcd); usb_hcd_resume_root_hub(xhci->shared_hcd); + usb_hcd_resume_root_hub(hcd); } } @@ -1124,10 +1124,10 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) /* Re-enable port polling. */ xhci_dbg(xhci, "%s: starting port polling.\n", __func__); - set_bit(HCD_FLAG_POLL_RH, &hcd->flags); - usb_hcd_poll_rh_status(hcd); set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); usb_hcd_poll_rh_status(xhci->shared_hcd); + set_bit(HCD_FLAG_POLL_RH, &hcd->flags); + usb_hcd_poll_rh_status(hcd); return retval; } -- cgit v1.2.3 From 0a380be8233dbf8dd20795b801c5d5d5ef3992f7 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Fri, 8 Apr 2016 16:25:07 +0300 Subject: usb: host: xhci: add a new quirk XHCI_NO_64BIT_SUPPORT On some xHCI controllers (e.g. R-Car SoCs), the AC64 bit (bit 0) of HCCPARAMS1 is set to 1. However, the xHCs don't support 64-bit address memory pointers actually. So, in this case, this driver should call dma_set_coherent_mask(dev, DMA_BIT_MASK(32)) in xhci_gen_setup(). Otherwise, the xHCI controller will be died after a usb device is connected if it runs on above 4GB physical memory environment. So, this patch adds a new quirk XHCI_NO_64BIT_SUPPORT to resolve such an issue. Cc: Signed-off-by: Yoshihiro Shimoda Reviewed-by: Felipe Balbi Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 10 ++++++++++ drivers/usb/host/xhci.h | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b60928802686..9283d3331b59 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4948,6 +4948,16 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) return retval; xhci_dbg(xhci, "Reset complete\n"); + /* + * On some xHCI controllers (e.g. R-Car SoCs), the AC64 bit (bit 0) + * of HCCPARAMS1 is set to 1. However, the xHCs don't support 64-bit + * address memory pointers actually. So, this driver clears the AC64 + * bit of xhci->hcc_params to call dma_set_coherent_mask(dev, + * DMA_BIT_MASK(32)) in this xhci_gen_setup(). + */ + if (xhci->quirks & XHCI_NO_64BIT_SUPPORT) + xhci->hcc_params &= ~BIT(0); + /* Set dma_mask and coherent_dma_mask to 64-bits, * if xHC supports 64-bit addressing */ if (HCC_64BIT_ADDR(xhci->hcc_params) && diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e293e0974f48..70f215c20b2b 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1641,6 +1641,7 @@ struct xhci_hcd { #define XHCI_PME_STUCK_QUIRK (1 << 20) #define XHCI_MTK_HOST (1 << 21) #define XHCI_SSIC_PORT_UNUSED (1 << 22) +#define XHCI_NO_64BIT_SUPPORT (1 << 23) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ -- cgit v1.2.3 From 5ad3b03e4910f9f62342956ecdc758c7af6b8699 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Fri, 8 Apr 2016 16:25:08 +0300 Subject: usb: host: xhci-plat: fix cannot work if R-Car Gen2/3 run on above 4GB phys This patch fixes an issue that cannot work if R-Car Gen2/3 run on above 4GB physical memory environment to use a quirk XHCI_NO_64BIT_SUPPORT. Cc: Signed-off-by: Yoshihiro Shimoda Reviewed-by: Felipe Balbi Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 5c15e9bc5f7a..474b5fa14900 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -39,12 +39,25 @@ static const struct xhci_driver_overrides xhci_plat_overrides __initconst = { static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) { + struct usb_hcd *hcd = xhci_to_hcd(xhci); + /* * As of now platform drivers don't provide MSI support so we ensure * here that the generic code does not try to make a pci_dev from our * dev struct in order to setup MSI */ xhci->quirks |= XHCI_PLAT; + + /* + * On R-Car Gen2 and Gen3, the AC64 bit (bit 0) of HCCPARAMS1 is set + * to 1. However, these SoCs don't support 64-bit address memory + * pointers. So, this driver clears the AC64 bit of xhci->hcc_params + * to call dma_set_coherent_mask(dev, DMA_BIT_MASK(32)) in + * xhci_gen_setup(). + */ + if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2) || + xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3)) + xhci->quirks |= XHCI_NO_64BIT_SUPPORT; } /* called during probe() after chip reset completes */ -- cgit v1.2.3 From 71504062a7c34838c3fccd92c447f399d3cb5797 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Fri, 8 Apr 2016 16:25:09 +0300 Subject: usb: xhci: fix wild pointers in xhci_mem_cleanup This patch fixes some wild pointers produced by xhci_mem_cleanup. These wild pointers will cause system crash if xhci_mem_cleanup() is called twice. Reported-and-tested-by: Pengcheng Li Signed-off-by: Lu Baolu Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 80c1de239e9a..bad0d1f9a41d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1861,6 +1861,12 @@ no_bw: kfree(xhci->rh_bw); kfree(xhci->ext_caps); + xhci->usb2_ports = NULL; + xhci->usb3_ports = NULL; + xhci->port_array = NULL; + xhci->rh_bw = NULL; + xhci->ext_caps = NULL; + xhci->page_size = 0; xhci->page_shift = 0; xhci->bus_state[0].bus_suspended = 0; -- cgit v1.2.3 From 98d74f9ceaefc2b6c4a6440050163a83be0abede Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 8 Apr 2016 16:25:10 +0300 Subject: xhci: fix 10 second timeout on removal of PCI hotpluggable xhci controllers PCI hotpluggable xhci controllers such as some Alpine Ridge solutions will remove the xhci controller from the PCI bus when the last USB device is disconnected. Add a flag to indicate that the host is being removed to avoid queueing configure_endpoint commands for the dropped endpoints. For PCI hotplugged controllers this will prevent 5 second command timeouts For static xhci controllers the configure_endpoint command is not needed in the removal case as everything will be returned, freed, and the controller is reset. For now the flag is only set for PCI connected host controllers. Cc: Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 1 + drivers/usb/host/xhci-ring.c | 3 ++- drivers/usb/host/xhci.c | 8 +++++--- drivers/usb/host/xhci.h | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 071b34ae9c4e..48672fac7ff3 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -304,6 +304,7 @@ static void xhci_pci_remove(struct pci_dev *dev) struct xhci_hcd *xhci; xhci = hcd_to_xhci(pci_get_drvdata(dev)); + xhci->xhc_state |= XHCI_STATE_REMOVING; if (xhci->shared_hcd) { usb_remove_hcd(xhci->shared_hcd); usb_put_hcd(xhci->shared_hcd); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7cf66212ceae..99b4ff42f7a0 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -4004,7 +4004,8 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd, int reserved_trbs = xhci->cmd_ring_reserved_trbs; int ret; - if (xhci->xhc_state) { + if ((xhci->xhc_state & XHCI_STATE_DYING) || + (xhci->xhc_state & XHCI_STATE_HALTED)) { xhci_dbg(xhci, "xHCI dying or halted, can't queue_command\n"); return -ESHUTDOWN; } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 9283d3331b59..9e71c96ad74a 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -147,7 +147,8 @@ static int xhci_start(struct xhci_hcd *xhci) "waited %u microseconds.\n", XHCI_MAX_HALT_USEC); if (!ret) - xhci->xhc_state &= ~(XHCI_STATE_HALTED | XHCI_STATE_DYING); + /* clear state flags. Including dying, halted or removing */ + xhci->xhc_state = 0; return ret; } @@ -2773,7 +2774,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) if (ret <= 0) return ret; xhci = hcd_to_xhci(hcd); - if (xhci->xhc_state & XHCI_STATE_DYING) + if ((xhci->xhc_state & XHCI_STATE_DYING) || + (xhci->xhc_state & XHCI_STATE_REMOVING)) return -ENODEV; xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); @@ -3820,7 +3822,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, mutex_lock(&xhci->mutex); - if (xhci->xhc_state) /* dying or halted */ + if (xhci->xhc_state) /* dying, removing or halted */ goto out; if (!udev->slot_id) { diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 70f215c20b2b..6c629c97f8ad 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1605,6 +1605,7 @@ struct xhci_hcd { */ #define XHCI_STATE_DYING (1 << 0) #define XHCI_STATE_HALTED (1 << 1) +#define XHCI_STATE_REMOVING (1 << 2) /* Statistics */ int error_bitmask; unsigned int quirks; -- cgit v1.2.3 From f9a85f6e61c695daeb427dfc6c1d5a279654207b Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Wed, 13 Apr 2016 19:58:44 +0300 Subject: usb: host: xhci-plat: Make enum xhci_plat_type start at a non zero value Otherwise generic-xhci and xhci-platform which have no data get wrongly detected as XHCI_PLAT_TYPE_MARVELL_ARMADA by xhci_plat_type_is(). This fixes a regression in v4.5 for STiH407 family SoC's which use the synopsis dwc3 IP, whereby the disable_clk error path gets taken due to wrongly being detected as XHCI_PLAT_TYPE_MARVELL_ARMADA and the hcd never gets added. I suspect this will also fix other dwc3 DT platforms such as Exynos, although I've only tested on STih410 SoC. Fixes: 4efb2f694114 ("usb: host: xhci-plat: add struct xhci_plat_priv") Cc: stable@vger.kernel.org Cc: gregory.clement@free-electrons.com Cc: yoshihiro.shimoda.uh@renesas.com Signed-off-by: Peter Griffin Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h index 5a2e2e3936c4..529c3c40f901 100644 --- a/drivers/usb/host/xhci-plat.h +++ b/drivers/usb/host/xhci-plat.h @@ -14,7 +14,7 @@ #include "xhci.h" /* for hcd_to_xhci() */ enum xhci_plat_type { - XHCI_PLAT_TYPE_MARVELL_ARMADA, + XHCI_PLAT_TYPE_MARVELL_ARMADA = 1, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3, }; -- cgit v1.2.3 From 2dc0194c1d0df078dc4a7bf539ce9bda7e6f1a41 Mon Sep 17 00:00:00 2001 From: Diego Herranz Date: Tue, 12 Apr 2016 18:13:27 +0100 Subject: doc: usb: Fix typo in gadget_multi documentation It tries to "match" drivers for each interface (not "much"). Signed-off-by: Diego Herranz Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/gadget_multi.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/usb/gadget_multi.txt b/Documentation/usb/gadget_multi.txt index 7d66a8636cb5..5faf514047e9 100644 --- a/Documentation/usb/gadget_multi.txt +++ b/Documentation/usb/gadget_multi.txt @@ -43,7 +43,7 @@ For the gadget two work under Windows two conditions have to be met: First of all, Windows need to detect the gadget as an USB composite gadget which on its own have some conditions[4]. If they are met, Windows lets USB Generic Parent Driver[5] handle the device which then -tries to much drivers for each individual interface (sort of, don't +tries to match drivers for each individual interface (sort of, don't get into too many details). The good news is: you do not have to worry about most of the -- cgit v1.2.3 From 198de51dbc3454d95b015ca0a055b673f85f01bb Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 12 Apr 2016 12:27:08 +0200 Subject: USB: uas: Limit qdepth at the scsi-host level Commit 64d513ac31bd ("scsi: use host wide tags by default") causes the SCSI core to queue more commands then we can handle on devices with multiple LUNs, limit the queue depth at the scsi-host level instead of per slave to fix this. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1315013 Cc: stable@vger.kernel.org # 4.4.x and 4.5.x Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 13e4cc31bc79..b1ec7499166d 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -824,7 +824,6 @@ static int uas_slave_configure(struct scsi_device *sdev) if (devinfo->flags & US_FL_BROKEN_FUA) sdev->broken_fua = 1; - scsi_change_queue_depth(sdev, devinfo->qdepth - 2); return 0; } @@ -956,6 +955,12 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) if (result) goto set_alt0; + /* + * 1 tag is reserved for untagged commands + + * 1 tag to avoid off by one errors in some bridge firmwares + */ + shost->can_queue = devinfo->qdepth - 2; + usb_set_intfdata(intf, shost); result = scsi_add_host(shost, &intf->dev); if (result) -- cgit v1.2.3 From 1363074667a6b7d0507527742ccd7bbed5e3ceaa Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 12 Apr 2016 12:27:09 +0200 Subject: USB: uas: Add a new NO_REPORT_LUNS quirk Add a new NO_REPORT_LUNS quirk and set it for Seagate drives with an usb-id of: 0bc2:331a, as these will fail to respond to a REPORT_LUNS command. Cc: stable@vger.kernel.org Reported-and-tested-by: David Webb Signed-off-by: Hans de Goede Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 2 ++ drivers/usb/storage/uas.c | 14 +++++++++++++- drivers/usb/storage/unusual_uas.h | 7 +++++++ drivers/usb/storage/usb.c | 5 ++++- include/linux/usb_usual.h | 2 ++ 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index ecc74fa4bfde..0b3de80ec8f6 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -4077,6 +4077,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. sector if the number is odd); i = IGNORE_DEVICE (don't bind to this device); + j = NO_REPORT_LUNS (don't use report luns + command, uas only); l = NOT_LOCKABLE (don't try to lock and unlock ejectable media); m = MAX_SECTORS_64 (don't transfer more diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index b1ec7499166d..16bc679dc2fc 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -2,7 +2,7 @@ * USB Attached SCSI * Note that this is not the same as the USB Mass Storage driver * - * Copyright Hans de Goede for Red Hat, Inc. 2013 - 2014 + * Copyright Hans de Goede for Red Hat, Inc. 2013 - 2016 * Copyright Matthew Wilcox for Intel Corp, 2010 * Copyright Sarah Sharp for Intel Corp, 2010 * @@ -781,6 +781,17 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) return SUCCESS; } +static int uas_target_alloc(struct scsi_target *starget) +{ + struct uas_dev_info *devinfo = (struct uas_dev_info *) + dev_to_shost(starget->dev.parent)->hostdata; + + if (devinfo->flags & US_FL_NO_REPORT_LUNS) + starget->no_report_luns = 1; + + return 0; +} + static int uas_slave_alloc(struct scsi_device *sdev) { struct uas_dev_info *devinfo = @@ -831,6 +842,7 @@ static struct scsi_host_template uas_host_template = { .module = THIS_MODULE, .name = "uas", .queuecommand = uas_queuecommand, + .target_alloc = uas_target_alloc, .slave_alloc = uas_slave_alloc, .slave_configure = uas_slave_configure, .eh_abort_handler = uas_eh_abort_handler, diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index ccc113e83d88..53341a77d89f 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -64,6 +64,13 @@ UNUSUAL_DEV(0x0bc2, 0x3312, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_ATA_1X), +/* Reported-by: David Webb */ +UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999, + "Seagate", + "Expansion Desk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_LUNS), + /* Reported-by: Hans de Goede */ UNUSUAL_DEV(0x0bc2, 0x3320, 0x0000, 0x9999, "Seagate", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 43576ed31ccd..9de988a0f856 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -482,7 +482,7 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 | US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE | US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES | - US_FL_MAX_SECTORS_240); + US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS); p = quirks; while (*p) { @@ -532,6 +532,9 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) case 'i': f |= US_FL_IGNORE_DEVICE; break; + case 'j': + f |= US_FL_NO_REPORT_LUNS; + break; case 'l': f |= US_FL_NOT_LOCKABLE; break; diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h index 7f5f78bd15ad..245f57dbbb61 100644 --- a/include/linux/usb_usual.h +++ b/include/linux/usb_usual.h @@ -79,6 +79,8 @@ /* Cannot handle MI_REPORT_SUPPORTED_OPERATION_CODES */ \ US_FLAG(MAX_SECTORS_240, 0x08000000) \ /* Sets max_sectors to 240 */ \ + US_FLAG(NO_REPORT_LUNS, 0x10000000) \ + /* Cannot handle REPORT_LUNS */ \ #define US_FLAG(name, value) US_FL_##name = value , enum { US_DO_ALL_FLAGS }; -- cgit v1.2.3 From e86103a75705c7c530768f4ffaba74cf382910f2 Mon Sep 17 00:00:00 2001 From: Robert Dobrowolski Date: Thu, 24 Mar 2016 03:30:07 -0700 Subject: usb: hcd: out of bounds access in for_each_companion On BXT platform Host Controller and Device Controller figure as same PCI device but with different device function. HCD should not pass data to Device Controller but only to Host Controllers. Checking if companion device is Host Controller, otherwise skip. Cc: Signed-off-by: Robert Dobrowolski Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd-pci.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index f9d42cf23e55..7859d738df41 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -73,6 +73,15 @@ static void for_each_companion(struct pci_dev *pdev, struct usb_hcd *hcd, if (companion->bus != pdev->bus || PCI_SLOT(companion->devfn) != slot) continue; + + /* + * Companion device should be either UHCI,OHCI or EHCI host + * controller, otherwise skip. + */ + if (companion->class != CL_UHCI && companion->class != CL_OHCI && + companion->class != CL_EHCI) + continue; + companion_hcd = pci_get_drvdata(companion); if (!companion_hcd || !companion_hcd->self.root_hub) continue; -- cgit v1.2.3 From 535dac4ab5f42e040e8405b31e309a6b6d4eee57 Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Thu, 14 Jan 2016 10:31:11 -0600 Subject: ata: add AMD Seattle platform driver AMD Seattle SATA controller mostly conforms to AHCI interface with some special register to control SGPIO interface. In the case of an AHCI controller, the SGPIO feature is ideally implemented using the "Enclosure Management" register of the AHCI controller, but those registeres are not implemented in the Seattle SoC. Instead SoC (Rev B0 onwards) provides a 32-bit SGPIO control register which should be programmed to control the activity, locate and fault LEDs. The driver is based on ahci_platform driver. Signed-off-by: Brijesh Singh Acked-by: Hans de Goede CC: tj@kernel.org CC: linux-ide@vger.kernel.org Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 8 ++ drivers/ata/Makefile | 1 + drivers/ata/ahci_seattle.c | 210 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 219 insertions(+) create mode 100644 drivers/ata/ahci_seattle.c diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 5083f85efea7..cfa936a32513 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -202,6 +202,14 @@ config SATA_FSL If unsure, say N. +config SATA_AHCI_SEATTLE + tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support" + depends on ARCH_SEATTLE + help + This option enables support for AMD Seattle SATA host controller. + + If unsure, say N + config SATA_INIC162X tristate "Initio 162x SATA support (Very Experimental)" depends on PCI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 18579521464e..0b2afb7e5f35 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_ATA) += libata.o # non-SFF interface obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o +obj-$(CONFIG_SATA_AHCI_SEATTLE) += ahci_seattle.o libahci.o libahci_platform.o obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o obj-$(CONFIG_SATA_FSL) += sata_fsl.o obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o diff --git a/drivers/ata/ahci_seattle.c b/drivers/ata/ahci_seattle.c new file mode 100644 index 000000000000..6e702ab57220 --- /dev/null +++ b/drivers/ata/ahci_seattle.c @@ -0,0 +1,210 @@ +/* + * AMD Seattle AHCI SATA driver + * + * Copyright (c) 2015, Advanced Micro Devices + * Author: Brijesh Singh + * + * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ahci.h" + +/* SGPIO Control Register definition + * + * Bit Type Description + * 31 RW OD7.2 (activity) + * 30 RW OD7.1 (locate) + * 29 RW OD7.0 (fault) + * 28...8 RW OD6.2...OD0.0 (3bits per port, 1 bit per LED) + * 7 RO SGPIO feature flag + * 6:4 RO Reserved + * 3:0 RO Number of ports (0 means no port supported) + */ +#define ACTIVITY_BIT_POS(x) (8 + (3 * x)) +#define LOCATE_BIT_POS(x) (ACTIVITY_BIT_POS(x) + 1) +#define FAULT_BIT_POS(x) (LOCATE_BIT_POS(x) + 1) + +#define ACTIVITY_MASK 0x00010000 +#define LOCATE_MASK 0x00080000 +#define FAULT_MASK 0x00400000 + +#define DRV_NAME "ahci-seattle" + +static ssize_t seattle_transmit_led_message(struct ata_port *ap, u32 state, + ssize_t size); + +struct seattle_plat_data { + void __iomem *sgpio_ctrl; +}; + +static struct ata_port_operations ahci_port_ops = { + .inherits = &ahci_ops, +}; + +static const struct ata_port_info ahci_port_info = { + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_port_ops, +}; + +static struct ata_port_operations ahci_seattle_ops = { + .inherits = &ahci_ops, + .transmit_led_message = seattle_transmit_led_message, +}; + +static const struct ata_port_info ahci_port_seattle_info = { + .flags = AHCI_FLAG_COMMON | ATA_FLAG_EM | ATA_FLAG_SW_ACTIVITY, + .link_flags = ATA_LFLAG_SW_ACTIVITY, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_seattle_ops, +}; + +static struct scsi_host_template ahci_platform_sht = { + AHCI_SHT(DRV_NAME), +}; + +static ssize_t seattle_transmit_led_message(struct ata_port *ap, u32 state, + ssize_t size) +{ + struct ahci_host_priv *hpriv = ap->host->private_data; + struct ahci_port_priv *pp = ap->private_data; + struct seattle_plat_data *plat_data = hpriv->plat_data; + unsigned long flags; + int pmp; + struct ahci_em_priv *emp; + u32 val; + + /* get the slot number from the message */ + pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; + if (pmp >= EM_MAX_SLOTS) + return -EINVAL; + emp = &pp->em_priv[pmp]; + + val = ioread32(plat_data->sgpio_ctrl); + if (state & ACTIVITY_MASK) + val |= 1 << ACTIVITY_BIT_POS((ap->port_no)); + else + val &= ~(1 << ACTIVITY_BIT_POS((ap->port_no))); + + if (state & LOCATE_MASK) + val |= 1 << LOCATE_BIT_POS((ap->port_no)); + else + val &= ~(1 << LOCATE_BIT_POS((ap->port_no))); + + if (state & FAULT_MASK) + val |= 1 << FAULT_BIT_POS((ap->port_no)); + else + val &= ~(1 << FAULT_BIT_POS((ap->port_no))); + + iowrite32(val, plat_data->sgpio_ctrl); + + spin_lock_irqsave(ap->lock, flags); + + /* save off new led state for port/slot */ + emp->led_state = state; + + spin_unlock_irqrestore(ap->lock, flags); + + return size; +} + +static const struct ata_port_info *ahci_seattle_get_port_info( + struct platform_device *pdev, struct ahci_host_priv *hpriv) +{ + struct device *dev = &pdev->dev; + struct seattle_plat_data *plat_data; + u32 val; + + plat_data = devm_kzalloc(dev, sizeof(*plat_data), GFP_KERNEL); + if (IS_ERR(plat_data)) + return &ahci_port_info; + + plat_data->sgpio_ctrl = devm_ioremap_resource(dev, + platform_get_resource(pdev, IORESOURCE_MEM, 1)); + if (IS_ERR(plat_data->sgpio_ctrl)) + return &ahci_port_info; + + val = ioread32(plat_data->sgpio_ctrl); + + if (!(val & 0xf)) + return &ahci_port_info; + + hpriv->em_loc = 0; + hpriv->em_buf_sz = 4; + hpriv->em_msg_type = EM_MSG_TYPE_LED; + hpriv->plat_data = plat_data; + + dev_info(dev, "SGPIO LED control is enabled.\n"); + return &ahci_port_seattle_info; +} + +static int ahci_seattle_probe(struct platform_device *pdev) +{ + int rc; + struct ahci_host_priv *hpriv; + + hpriv = ahci_platform_get_resources(pdev); + if (IS_ERR(hpriv)) + return PTR_ERR(hpriv); + + rc = ahci_platform_enable_resources(hpriv); + if (rc) + return rc; + + rc = ahci_platform_init_host(pdev, hpriv, + ahci_seattle_get_port_info(pdev, hpriv), + &ahci_platform_sht); + if (rc) + goto disable_resources; + + return 0; +disable_resources: + ahci_platform_disable_resources(hpriv); + return rc; +} + +static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, + ahci_platform_resume); + +static const struct acpi_device_id ahci_acpi_match[] = { + { "AMDI0600", 0 }, + {} +}; +MODULE_DEVICE_TABLE(acpi, ahci_acpi_match); + +static struct platform_driver ahci_seattle_driver = { + .probe = ahci_seattle_probe, + .remove = ata_platform_remove_one, + .driver = { + .name = DRV_NAME, + .acpi_match_table = ahci_acpi_match, + .pm = &ahci_pm_ops, + }, +}; +module_platform_driver(ahci_seattle_driver); + +MODULE_DESCRIPTION("Seattle AHCI SATA platform driver"); +MODULE_AUTHOR("Brijesh Singh "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); -- cgit v1.2.3 From e7e0c3e26587749b62d17b9dd0532874186c77f7 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sun, 3 Apr 2016 16:15:00 -0300 Subject: [media] videobuf2-core: Check user space planes array in dqbuf The number of planes in videobuf2 is specific to a buffer. In order to verify that the planes array provided by the user is long enough, a new vb2_buf_op is required. Call __verify_planes_array() when the dequeued buffer is known. Return an error to the caller if there was one, otherwise remove the buffer from the done list. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Cc: stable@vger.kernel.org # for v4.4 and later Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 10 +++++----- include/media/videobuf2-core.h | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 5d016f496e0e..2169544883e8 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1645,7 +1645,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) * Will sleep if required for nonblocking == false. */ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb, - int nonblocking) + void *pb, int nonblocking) { unsigned long flags; int ret; @@ -1666,10 +1666,10 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb, /* * Only remove the buffer from done_list if v4l2_buffer can handle all * the planes. - * Verifying planes is NOT necessary since it already has been checked - * before the buffer is queued/prepared. So it can never fail. */ - list_del(&(*vb)->done_entry); + ret = call_bufop(q, verify_planes_array, *vb, pb); + if (!ret) + list_del(&(*vb)->done_entry); spin_unlock_irqrestore(&q->done_lock, flags); return ret; @@ -1748,7 +1748,7 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, struct vb2_buffer *vb = NULL; int ret; - ret = __vb2_get_done_vb(q, &vb, nonblocking); + ret = __vb2_get_done_vb(q, &vb, pb, nonblocking); if (ret < 0) return ret; diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 8a0f55b6c2ba..5342ff4d748f 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -375,6 +375,9 @@ struct vb2_ops { /** * struct vb2_ops - driver-specific callbacks * + * @verify_planes_array: Verify that a given user space structure contains + * enough planes for the buffer. This is called + * for each dequeued buffer. * @fill_user_buffer: given a vb2_buffer fill in the userspace structure. * For V4L2 this is a struct v4l2_buffer. * @fill_vb2_buffer: given a userspace structure, fill in the vb2_buffer. @@ -384,6 +387,7 @@ struct vb2_ops { * the vb2_buffer struct. */ struct vb2_buf_ops { + int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb); void (*fill_user_buffer)(struct vb2_buffer *vb, void *pb); int (*fill_vb2_buffer)(struct vb2_buffer *vb, const void *pb, struct vb2_plane *planes); -- cgit v1.2.3 From 2c1f6951a8a82e6de0d82b1158b5e493fc6c54ab Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sun, 3 Apr 2016 16:31:03 -0300 Subject: [media] videobuf2-v4l2: Verify planes array in buffer dequeueing When a buffer is being dequeued using VIDIOC_DQBUF IOCTL, the exact buffer which will be dequeued is not known until the buffer has been removed from the queue. The number of planes is specific to a buffer, not to the queue. This does lead to the situation where multi-plane buffers may be requested and queued with n planes, but VIDIOC_DQBUF IOCTL may be passed an argument struct with fewer planes. __fill_v4l2_buffer() however uses the number of planes from the dequeued videobuf2 buffer, overwriting kernel memory (the m.planes array allocated in video_usercopy() in v4l2-ioctl.c) if the user provided fewer planes than the dequeued buffer had. Oops! Fixes: b0e0e1f83de3 ("[media] media: videobuf2: Prepare to divide videobuf2") Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Cc: stable@vger.kernel.org # for v4.4 and later Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-v4l2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c index 91f552124050..8da7470ca364 100644 --- a/drivers/media/v4l2-core/videobuf2-v4l2.c +++ b/drivers/media/v4l2-core/videobuf2-v4l2.c @@ -74,6 +74,11 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer return 0; } +static int __verify_planes_array_core(struct vb2_buffer *vb, const void *pb) +{ + return __verify_planes_array(vb, pb); +} + /** * __verify_length() - Verify that the bytesused value for each plane fits in * the plane length and that the data offset doesn't exceed the bytesused value. @@ -437,6 +442,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, } static const struct vb2_buf_ops v4l2_buf_ops = { + .verify_planes_array = __verify_planes_array_core, .fill_user_buffer = __fill_v4l2_buffer, .fill_vb2_buffer = __fill_vb2_buffer, .copy_timestamp = __copy_timestamp, -- cgit v1.2.3 From a2abf904a6b594b93c0e73a36c98ecbaa7388463 Mon Sep 17 00:00:00 2001 From: Franklin S Cooper Jr Date: Thu, 10 Mar 2016 17:56:38 -0600 Subject: ARM: dts: am33xx: Fix GPMC dma properties This patch updates the GPMC's DT DMA property to reflect the updated eDMA bindings. Fixes: b5e509066074 ("ARM: DTS: am33xx: Use the new DT bindings for the eDMA3") Signed-off-by: Franklin S Cooper Jr Acked-by: Roger Quadros Acked-by: Peter Ujfalusi Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am33xx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 55ca9c7dcf6a..0467846b4cc3 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -860,7 +860,7 @@ ti,no-idle-on-init; reg = <0x50000000 0x2000>; interrupts = <100>; - dmas = <&edma 52>; + dmas = <&edma 52 0>; dma-names = "rxtx"; gpmc,num-cs = <7>; gpmc,num-waitpins = <2>; -- cgit v1.2.3 From 883cbc901b570625f54250a37b008d3635f1fbda Mon Sep 17 00:00:00 2001 From: Franklin S Cooper Jr Date: Thu, 10 Mar 2016 17:56:39 -0600 Subject: ARM: dts: am437x: Fix GPMC dma properties This patch updates the GPMC's DT DMA property to reflect the updated eDMA bindings. Fixes: cce1ee000187 ("ARM: DTS: am437x: Use the new DT bindings for the eDMA3") Signed-off-by: Franklin S Cooper Jr Acked-by: Roger Quadros Acked-by: Peter Ujfalusi Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am4372.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 344b861a55a5..ba580a9da390 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -884,7 +884,7 @@ gpmc: gpmc@50000000 { compatible = "ti,am3352-gpmc"; ti,hwmods = "gpmc"; - dmas = <&edma 52>; + dmas = <&edma 52 0>; dma-names = "rxtx"; clocks = <&l3s_gclk>; clock-names = "fck"; -- cgit v1.2.3 From a1def45365594dd16be0d8cc52b0d5a6a79d6ae6 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 6 Apr 2016 17:32:38 +0300 Subject: ARM: dts: am57xx-beagle-x15: remove extcon_usb1 USB1 controller is hardwired to be used as Host only port so we don't need to check ID pin state and can get rid of extcon_usb1. This also reduces USB1 controller's and so eSATA power's dependency with EXTCON. This fixes eSATA port with multi_v7_defconfig. Cc: Franklin S Cooper Jr. Cc: Vagrant Cascadian Signed-off-by: Roger Quadros Tested-by: Franklin S Cooper Jr. [tony@atomide.com: updated to describe what it fixes] Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am57xx-beagle-x15.dts | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index 0a5fc5d02ce2..4168eb9dd369 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts @@ -99,13 +99,6 @@ #cooling-cells = <2>; }; - extcon_usb1: extcon_usb1 { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&gpio7 25 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&extcon_usb1_pins>; - }; - hdmi0: connector { compatible = "hdmi-connector"; label = "hdmi"; @@ -349,12 +342,6 @@ >; }; - extcon_usb1_pins: extcon_usb1_pins { - pinctrl-single,pins = < - DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_rtsn.gpio7_25 */ - >; - }; - tpd12s015_pins: pinmux_tpd12s015_pins { pinctrl-single,pins = < DRA7XX_CORE_IOPAD(0x37b0, PIN_OUTPUT | MUX_MODE14) /* gpio7_10 CT_CP_HPD */ @@ -706,10 +693,6 @@ pinctrl-0 = <&usb1_pins>; }; -&omap_dwc3_1 { - extcon = <&extcon_usb1>; -}; - &omap_dwc3_2 { extcon = <&extcon_usb2>; }; -- cgit v1.2.3 From a6d37131c02f15463daa00e2f1da6824e8e00de2 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 8 Apr 2016 13:28:42 +0200 Subject: net: ethernet: renesas: ravb_main: test clock rate to avoid division by 0 The clk API may return 0 on clk_get_rate, so we should check the result before using it as a divisor. Signed-off-by: Wolfram Sang Acked-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/ravb_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 087e14a3fba7..9e2a0bd8f5a8 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -1691,6 +1691,9 @@ static int ravb_set_gti(struct net_device *ndev) rate = clk_get_rate(clk); clk_put(clk); + if (!rate) + return -EINVAL; + inc = 1000000000ULL << 20; do_div(inc, rate); -- cgit v1.2.3 From 70af921db6f8835f4b11c65731116560adb00c14 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Fri, 8 Apr 2016 12:01:21 -0700 Subject: net: ipv6: Do not keep linklocal and loopback addresses f1705ec197e7 added the option to retain user configured addresses on an admin down. A comment to one of the later revisions suggested using the IFA_F_PERMANENT flag rather than adding a user_managed boolean to the ifaddr struct. A side effect of this change is that link local and loopback addresses are also retained which is not part of the objective of f1705ec197e7. Add check to drop those addresses. Fixes: f1705ec197e7 ("net: ipv6: Make address flushing on ifdown optional") Signed-off-by: David Ahern Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2db2116d3e6b..23cec53b568a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3448,6 +3448,12 @@ static void addrconf_type_change(struct net_device *dev, unsigned long event) ipv6_mc_unmap(idev); } +static bool addr_is_local(const struct in6_addr *addr) +{ + return ipv6_addr_type(addr) & + (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); +} + static int addrconf_ifdown(struct net_device *dev, int how) { struct net *net = dev_net(dev); @@ -3505,7 +3511,8 @@ restart: * address is retained on a down event */ if (!keep_addr || - !(ifa->flags & IFA_F_PERMANENT)) { + !(ifa->flags & IFA_F_PERMANENT) || + addr_is_local(&ifa->addr)) { hlist_del_init_rcu(&ifa->addr_lst); goto restart; } @@ -3554,7 +3561,8 @@ restart: write_unlock_bh(&idev->lock); spin_lock_bh(&ifa->lock); - if (keep_addr && (ifa->flags & IFA_F_PERMANENT)) { + if (keep_addr && (ifa->flags & IFA_F_PERMANENT) && + !addr_is_local(&ifa->addr)) { /* set state to skip the notifier below */ state = INET6_IFADDR_STATE_DEAD; ifa->state = 0; -- cgit v1.2.3 From 3f3f7cb875c0f621485644d4fd7453b0d37f00e4 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 30 Mar 2016 16:15:37 -0700 Subject: i40e/i40evf: Limit TSO to 7 descriptors for payload instead of 8 per packet This patch addresses a bug introduced based on my interpretation of the XL710 datasheet. Specifically section 8.4.1 states that "A single transmit packet may span up to 8 buffers (up to 8 data descriptors per packet including both the header and payload buffers)." It then later goes on to say that each segment for a TSO obeys the previous rule, however it then refers to TSO header and the segment payload buffers. I believe the actual limit for fragments with TSO and a skbuff that has payload data in the header portion of the buffer is actually only 7 fragments as the skb->data portion counts as 2 buffers, one for the TSO header, and one for a segment payload buffer. Fixes: 2d37490b82af ("i40e/i40evf: Rewrite logic for 8 descriptor per packet check") Reported-by: Sowmini Varadhan Signed-off-by: Alexander Duyck Acked-by: Jesse Brandeburg Tested-by: Sowmini Varadhan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 49 +++++++++++++-------------- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 10 ++++-- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 49 +++++++++++++-------------- drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 10 ++++-- 4 files changed, 62 insertions(+), 56 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 084d0ab316b7..6a49b7ae511c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2594,35 +2594,34 @@ int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) } /** - * __i40e_chk_linearize - Check if there are more than 8 fragments per packet + * __i40e_chk_linearize - Check if there are more than 8 buffers per packet * @skb: send buffer * - * Note: Our HW can't scatter-gather more than 8 fragments to build - * a packet on the wire and so we need to figure out the cases where we - * need to linearize the skb. + * Note: Our HW can't DMA more than 8 buffers to build a packet on the wire + * and so we need to figure out the cases where we need to linearize the skb. + * + * For TSO we need to count the TSO header and segment payload separately. + * As such we need to check cases where we have 7 fragments or more as we + * can potentially require 9 DMA transactions, 1 for the TSO header, 1 for + * the segment payload in the first descriptor, and another 7 for the + * fragments. **/ bool __i40e_chk_linearize(struct sk_buff *skb) { const struct skb_frag_struct *frag, *stale; - int gso_size, nr_frags, sum; - - /* check to see if TSO is enabled, if so we may get a repreive */ - gso_size = skb_shinfo(skb)->gso_size; - if (unlikely(!gso_size)) - return true; + int nr_frags, sum; - /* no need to check if number of frags is less than 8 */ + /* no need to check if number of frags is less than 7 */ nr_frags = skb_shinfo(skb)->nr_frags; - if (nr_frags < I40E_MAX_BUFFER_TXD) + if (nr_frags < (I40E_MAX_BUFFER_TXD - 1)) return false; /* We need to walk through the list and validate that each group * of 6 fragments totals at least gso_size. However we don't need - * to perform such validation on the first or last 6 since the first - * 6 cannot inherit any data from a descriptor before them, and the - * last 6 cannot inherit any data from a descriptor after them. + * to perform such validation on the last 6 since the last 6 cannot + * inherit any data from a descriptor after them. */ - nr_frags -= I40E_MAX_BUFFER_TXD - 1; + nr_frags -= I40E_MAX_BUFFER_TXD - 2; frag = &skb_shinfo(skb)->frags[0]; /* Initialize size to the negative value of gso_size minus 1. We @@ -2631,21 +2630,21 @@ bool __i40e_chk_linearize(struct sk_buff *skb) * descriptors for a single transmit as the header and previous * fragment are already consuming 2 descriptors. */ - sum = 1 - gso_size; + sum = 1 - skb_shinfo(skb)->gso_size; - /* Add size of frags 1 through 5 to create our initial sum */ - sum += skb_frag_size(++frag); - sum += skb_frag_size(++frag); - sum += skb_frag_size(++frag); - sum += skb_frag_size(++frag); - sum += skb_frag_size(++frag); + /* Add size of frags 0 through 4 to create our initial sum */ + sum += skb_frag_size(frag++); + sum += skb_frag_size(frag++); + sum += skb_frag_size(frag++); + sum += skb_frag_size(frag++); + sum += skb_frag_size(frag++); /* Walk through fragments adding latest fragment, testing it, and * then removing stale fragments from the sum. */ stale = &skb_shinfo(skb)->frags[0]; for (;;) { - sum += skb_frag_size(++frag); + sum += skb_frag_size(frag++); /* if sum is negative we failed to make sufficient progress */ if (sum < 0) @@ -2655,7 +2654,7 @@ bool __i40e_chk_linearize(struct sk_buff *skb) if (!--nr_frags) break; - sum -= skb_frag_size(++stale); + sum -= skb_frag_size(stale++); } return false; diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index cdd5dc00aec5..a9bd70537d65 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -413,10 +413,14 @@ static inline int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) **/ static inline bool i40e_chk_linearize(struct sk_buff *skb, int count) { - /* we can only support up to 8 data buffers for a single send */ - if (likely(count <= I40E_MAX_BUFFER_TXD)) + /* Both TSO and single send will work if count is less than 8 */ + if (likely(count < I40E_MAX_BUFFER_TXD)) return false; - return __i40e_chk_linearize(skb); + if (skb_is_gso(skb)) + return __i40e_chk_linearize(skb); + + /* we can support up to 8 data buffers for a single send */ + return count != I40E_MAX_BUFFER_TXD; } #endif /* _I40E_TXRX_H_ */ diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index ebcc25c05796..cea97daa844c 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -1796,35 +1796,34 @@ static void i40e_create_tx_ctx(struct i40e_ring *tx_ring, } /** - * __i40evf_chk_linearize - Check if there are more than 8 fragments per packet + * __i40evf_chk_linearize - Check if there are more than 8 buffers per packet * @skb: send buffer * - * Note: Our HW can't scatter-gather more than 8 fragments to build - * a packet on the wire and so we need to figure out the cases where we - * need to linearize the skb. + * Note: Our HW can't DMA more than 8 buffers to build a packet on the wire + * and so we need to figure out the cases where we need to linearize the skb. + * + * For TSO we need to count the TSO header and segment payload separately. + * As such we need to check cases where we have 7 fragments or more as we + * can potentially require 9 DMA transactions, 1 for the TSO header, 1 for + * the segment payload in the first descriptor, and another 7 for the + * fragments. **/ bool __i40evf_chk_linearize(struct sk_buff *skb) { const struct skb_frag_struct *frag, *stale; - int gso_size, nr_frags, sum; - - /* check to see if TSO is enabled, if so we may get a repreive */ - gso_size = skb_shinfo(skb)->gso_size; - if (unlikely(!gso_size)) - return true; + int nr_frags, sum; - /* no need to check if number of frags is less than 8 */ + /* no need to check if number of frags is less than 7 */ nr_frags = skb_shinfo(skb)->nr_frags; - if (nr_frags < I40E_MAX_BUFFER_TXD) + if (nr_frags < (I40E_MAX_BUFFER_TXD - 1)) return false; /* We need to walk through the list and validate that each group * of 6 fragments totals at least gso_size. However we don't need - * to perform such validation on the first or last 6 since the first - * 6 cannot inherit any data from a descriptor before them, and the - * last 6 cannot inherit any data from a descriptor after them. + * to perform such validation on the last 6 since the last 6 cannot + * inherit any data from a descriptor after them. */ - nr_frags -= I40E_MAX_BUFFER_TXD - 1; + nr_frags -= I40E_MAX_BUFFER_TXD - 2; frag = &skb_shinfo(skb)->frags[0]; /* Initialize size to the negative value of gso_size minus 1. We @@ -1833,21 +1832,21 @@ bool __i40evf_chk_linearize(struct sk_buff *skb) * descriptors for a single transmit as the header and previous * fragment are already consuming 2 descriptors. */ - sum = 1 - gso_size; + sum = 1 - skb_shinfo(skb)->gso_size; - /* Add size of frags 1 through 5 to create our initial sum */ - sum += skb_frag_size(++frag); - sum += skb_frag_size(++frag); - sum += skb_frag_size(++frag); - sum += skb_frag_size(++frag); - sum += skb_frag_size(++frag); + /* Add size of frags 0 through 4 to create our initial sum */ + sum += skb_frag_size(frag++); + sum += skb_frag_size(frag++); + sum += skb_frag_size(frag++); + sum += skb_frag_size(frag++); + sum += skb_frag_size(frag++); /* Walk through fragments adding latest fragment, testing it, and * then removing stale fragments from the sum. */ stale = &skb_shinfo(skb)->frags[0]; for (;;) { - sum += skb_frag_size(++frag); + sum += skb_frag_size(frag++); /* if sum is negative we failed to make sufficient progress */ if (sum < 0) @@ -1857,7 +1856,7 @@ bool __i40evf_chk_linearize(struct sk_buff *skb) if (!--nr_frags) break; - sum -= skb_frag_size(++stale); + sum -= skb_frag_size(stale++); } return false; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h index c1dd8c5c9666..0429553fe887 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h @@ -395,10 +395,14 @@ static inline int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) **/ static inline bool i40e_chk_linearize(struct sk_buff *skb, int count) { - /* we can only support up to 8 data buffers for a single send */ - if (likely(count <= I40E_MAX_BUFFER_TXD)) + /* Both TSO and single send will work if count is less than 8 */ + if (likely(count < I40E_MAX_BUFFER_TXD)) return false; - return __i40evf_chk_linearize(skb); + if (skb_is_gso(skb)) + return __i40evf_chk_linearize(skb); + + /* we can support up to 8 data buffers for a single send */ + return count != I40E_MAX_BUFFER_TXD; } #endif /* _I40E_TXRX_H_ */ -- cgit v1.2.3 From b821646826e22f0491708768fccce58eef3f5704 Mon Sep 17 00:00:00 2001 From: Emrah Demir Date: Fri, 8 Apr 2016 22:16:11 +0300 Subject: mISDN: Fixing missing validation in base_sock_bind() Add validation code into mISDN/socket.c Signed-off-by: Emrah Demir Signed-off-by: David S. Miller --- drivers/isdn/mISDN/socket.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index 0d29b5a6356d..99e5f9751e8b 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c @@ -715,6 +715,9 @@ base_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) if (!maddr || maddr->family != AF_ISDN) return -EINVAL; + if (addr_len < sizeof(struct sockaddr_mISDN)) + return -EINVAL; + lock_sock(sk); if (_pms(sk)->dev) { -- cgit v1.2.3 From 65c66af6609f0e76617184b40efea8eea1aae505 Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 8 Apr 2016 13:37:27 -0700 Subject: net: thunderx: Fix broken of_node_put() code. commit b7d3e3d3d21a ("net: thunderx: Don't leak phy device references on -EPROBE_DEFER condition.") incorrectly moved the call to of_node_put() outside of the loop. Under normal loop exit, the node has already had of_node_put() called, so the extra call results in: [ 8.228020] ERROR: Bad of_node_put() on /soc@0/pci@848000000000/mrml-bridge0@1,0/bgx0/xlaui00 [ 8.239433] CPU: 16 PID: 608 Comm: systemd-udevd Not tainted 4.6.0-rc1-numa+ #157 [ 8.247380] Hardware name: www.cavium.com EBB8800/EBB8800, BIOS 0.3 Mar 2 2016 [ 8.273541] Call trace: [ 8.273550] [] dump_backtrace+0x0/0x210 [ 8.273557] [] show_stack+0x24/0x2c [ 8.273560] [] dump_stack+0x8c/0xb4 [ 8.273566] [] of_node_release+0xa8/0xac [ 8.273570] [] kobject_cleanup+0x8c/0x194 [ 8.273573] [] kobject_put+0x44/0x6c [ 8.273576] [] of_node_put+0x24/0x30 [ 8.273587] [] bgx_probe+0x17c/0xcd8 [thunder_bgx] [ 8.273591] [] pci_device_probe+0xa0/0x114 [ 8.273596] [] driver_probe_device+0x178/0x418 [ 8.273599] [] __driver_attach+0x100/0x118 [ 8.273602] [] bus_for_each_dev+0x6c/0xac [ 8.273605] [] driver_attach+0x30/0x38 [ 8.273608] [] bus_add_driver+0x1f8/0x29c [ 8.273611] [] driver_register+0x70/0x110 [ 8.273617] [] __pci_register_driver+0x60/0x6c [ 8.273623] [] bgx_init_module+0x40/0x48 [thunder_bgx] [ 8.273626] [] do_one_initcall+0xcc/0x1c0 [ 8.273631] [] do_init_module+0x68/0x1c8 [ 8.273635] [] load_module+0xf44/0x11f4 [ 8.273638] [] SyS_finit_module+0xb8/0xe0 [ 8.273641] [] el0_svc_naked+0x24/0x28 Go back to the previous (correct) code that only did the extra of_node_put() call on early exit from the loop. Signed-off-by: David Daney Signed-off-by: David S. Miller --- drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c index 967951582e03..d20539a6d162 100644 --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c @@ -1011,10 +1011,11 @@ static int bgx_init_of_phy(struct bgx *bgx) } lmac++; - if (lmac == MAX_LMAC_PER_BGX) + if (lmac == MAX_LMAC_PER_BGX) { + of_node_put(node); break; + } } - of_node_put(node); return 0; defer: -- cgit v1.2.3 From f808c5dbcdc393be8e9f676c61baac6a3db382c1 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Thu, 31 Mar 2016 09:52:30 -0700 Subject: fm10k: fix multi-bit VLAN update requests from VF The VF uses a multi-bit update request to clear unused VLANs whenever it resets. However, an accident in a previous refector broke multi-bit updates for VFs, due to misreading a comment in fm10k_vf.c and attempting to reduce code duplication. The problem occurs because a multi-bit request has a non-zero length, and the PF would simply drop any request with the upper 16 bits set. We can't simply remove the check of the upper 16 bits and the call to fm10k_iov_select vid, because this would remove the checks for default VID and for ensuring no other VLANs can be enabled except pf_vid when it has been set. To resolve that issue, this revision uses the iov_select_vid when we have a single-bit update, and denies any multi-bit update when the VLAN was administratively set by the PF. This should be ok since the PF properly updates VLAN_TABLE when it assigns the PF vid. This ensures that requests to add or remove the PF vid work as expected, but a rogue VF could not use the multi-bit update as a loophole to attempt receiving traffic on other VLANs. Reported-by: Ngai-Mint Kwan Signed-off-by: Jacob Keller Tested-by: Krishneil Singh Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/fm10k/fm10k_pf.c | 30 +++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c index 62ccebc5f728..8cf943db5662 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c @@ -1223,18 +1223,32 @@ s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results, if (err) return err; - /* verify upper 16 bits are zero */ - if (vid >> 16) - return FM10K_ERR_PARAM; - set = !(vid & FM10K_VLAN_CLEAR); vid &= ~FM10K_VLAN_CLEAR; - err = fm10k_iov_select_vid(vf_info, (u16)vid); - if (err < 0) - return err; + /* if the length field has been set, this is a multi-bit + * update request. For multi-bit requests, simply disallow + * them when the pf_vid has been set. In this case, the PF + * should have already cleared the VLAN_TABLE, and if we + * allowed them, it could allow a rogue VF to receive traffic + * on a VLAN it was not assigned. In the single-bit case, we + * need to modify requests for VLAN 0 to use the default PF or + * SW vid when assigned. + */ - vid = err; + if (vid >> 16) { + /* prevent multi-bit requests when PF has + * administratively set the VLAN for this VF + */ + if (vf_info->pf_vid) + return FM10K_ERR_PARAM; + } else { + err = fm10k_iov_select_vid(vf_info, (u16)vid); + if (err < 0) + return err; + + vid = err; + } /* update VSI info for VF in regards to VLAN table */ err = hw->mac.ops.update_vlan(hw, vid, vf_info->vsi, set); -- cgit v1.2.3 From d6d5e999e5df67f8ec20b6be45e2229455ee3699 Mon Sep 17 00:00:00 2001 From: Chris Friesen Date: Fri, 8 Apr 2016 15:21:30 -0600 Subject: route: do not cache fib route info on local routes with oif For local routes that require a particular output interface we do not want to cache the result. Caching the result causes incorrect behaviour when there are multiple source addresses on the interface. The end result being that if the intended recipient is waiting on that interface for the packet he won't receive it because it will be delivered on the loopback interface and the IP_PKTINFO ipi_ifindex will be set to the loopback interface as well. This can be tested by running a program such as "dhcp_release" which attempts to inject a packet on a particular interface so that it is received by another program on the same board. The receiving process should see an IP_PKTINFO ipi_ifndex value of the source interface (e.g., eth1) instead of the loopback interface (e.g., lo). The packet will still appear on the loopback interface in tcpdump but the important aspect is that the CMSG info is correct. Sample dhcp_release command line: dhcp_release eth1 192.168.204.222 02:11:33:22:44:66 Signed-off-by: Allain Legacy Signed off-by: Chris Friesen Reviewed-by: Julian Anastasov Signed-off-by: David S. Miller --- net/ipv4/route.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 2852bdf73540..60398a9370e7 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2046,6 +2046,18 @@ static struct rtable *__mkroute_output(const struct fib_result *res, */ if (fi && res->prefixlen < 4) fi = NULL; + } else if ((type == RTN_LOCAL) && (orig_oif != 0) && + (orig_oif != dev_out->ifindex)) { + /* For local routes that require a particular output interface + * we do not want to cache the result. Caching the result + * causes incorrect behaviour when there are multiple source + * addresses on the interface, the end result being that if the + * intended recipient is waiting on that interface for the + * packet he won't receive it because it will be delivered on + * the loopback interface and the IP_PKTINFO ipi_ifindex will + * be set to the loopback interface as well. + */ + fi = NULL; } fnhe = NULL; -- cgit v1.2.3 From 7403c515c49c033fec33df0814fffdc977e6acdc Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 13 Apr 2016 12:08:27 -0400 Subject: drm/radeon: fix initial connector audio value This got lost somewhere along the way. This fixes audio not working until set_property was called. Noticed-by: Hyungwon Hwang Cc: stable@vger.kernel.org Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_connectors.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index cfcc099c537d..81a63d7f5cd9 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -2002,10 +2002,12 @@ radeon_add_atom_connector(struct drm_device *dev, rdev->mode_info.dither_property, RADEON_FMT_DITHER_DISABLE); - if (radeon_audio != 0) + if (radeon_audio != 0) { drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, RADEON_AUDIO_AUTO); + radeon_connector->audio = RADEON_AUDIO_AUTO; + } if (ASIC_IS_DCE5(rdev)) drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.output_csc_property, @@ -2130,6 +2132,7 @@ radeon_add_atom_connector(struct drm_device *dev, drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, RADEON_AUDIO_AUTO); + radeon_connector->audio = RADEON_AUDIO_AUTO; } if (connector_type == DRM_MODE_CONNECTOR_DVII) { radeon_connector->dac_load_detect = true; @@ -2185,6 +2188,7 @@ radeon_add_atom_connector(struct drm_device *dev, drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, RADEON_AUDIO_AUTO); + radeon_connector->audio = RADEON_AUDIO_AUTO; } if (ASIC_IS_DCE5(rdev)) drm_object_attach_property(&radeon_connector->base.base, @@ -2237,6 +2241,7 @@ radeon_add_atom_connector(struct drm_device *dev, drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, RADEON_AUDIO_AUTO); + radeon_connector->audio = RADEON_AUDIO_AUTO; } if (ASIC_IS_DCE5(rdev)) drm_object_attach_property(&radeon_connector->base.base, -- cgit v1.2.3 From 85cc88f02eb0ecf44493c1b2ebb6f206cd5fc321 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Tue, 12 Apr 2016 19:25:52 +0800 Subject: drm/amdgpu: when suspending, if uvd/vce was running. need to cancel delay work. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix the issue that when resume back, uvd/vce dpm was disabled and uvd/vce's performace dropped. Signed-off-by: Rex Zhu Reviewed-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 338da80006b6..8d035b65d967 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -255,6 +255,8 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) if (i == AMDGPU_MAX_UVD_HANDLES) return 0; + cancel_delayed_work_sync(&adev->uvd.idle_work); + size = amdgpu_bo_size(adev->uvd.vcpu_bo); ptr = adev->uvd.cpu_addr; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 4bec0c108cea..481a64fa9b47 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -234,6 +234,7 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev) if (i == AMDGPU_MAX_VCE_HANDLES) return 0; + cancel_delayed_work_sync(&adev->vce.idle_work); /* TODO: suspending running encoding sessions isn't supported */ return -EINVAL; } -- cgit v1.2.3 From 309cf37fe2a781279b7675d4bb7173198e532867 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Sun, 10 Apr 2016 12:52:28 +0200 Subject: packet: fix heap info leak in PACKET_DIAG_MCLIST sock_diag interface Because we miss to wipe the remainder of i->addr[] in packet_mc_add(), pdiag_put_mclist() leaks uninitialized heap bytes via the PACKET_DIAG_MCLIST netlink attribute. Fix this by explicitly memset(0)ing the remaining bytes in i->addr[]. Fixes: eea68e2f1a00 ("packet: Report socket mclist info via diag module") Signed-off-by: Mathias Krause Cc: Eric W. Biederman Cc: Pavel Emelyanov Acked-by: Pavel Emelyanov Signed-off-by: David S. Miller --- net/packet/af_packet.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index f12c17f355d9..18d0becbc46d 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -3521,6 +3521,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq) i->ifindex = mreq->mr_ifindex; i->alen = mreq->mr_alen; memcpy(i->addr, mreq->mr_address, i->alen); + memset(i->addr + i->alen, 0, sizeof(i->addr) - i->alen); i->count = 1; i->next = po->mclist; po->mclist = i; -- cgit v1.2.3 From 3dcd493fbebfd631913df6e2773cc295d3bf7d22 Mon Sep 17 00:00:00 2001 From: Lars Persson Date: Tue, 12 Apr 2016 08:45:52 +0200 Subject: net: sched: do not requeue a NULL skb A failure in validate_xmit_skb_list() triggered an unconditional call to dev_requeue_skb with skb=NULL. This slowly grows the queue discipline's qlen count until all traffic through the queue stops. We take the optimistic approach and continue running the queue after a failure since it is unknown if later packets also will fail in the validate path. Fixes: 55a93b3ea780 ("qdisc: validate skb without holding lock") Signed-off-by: Lars Persson Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/sch_generic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index f18c35024207..80742edea96f 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -159,12 +159,15 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, if (validate) skb = validate_xmit_skb_list(skb, dev); - if (skb) { + if (likely(skb)) { HARD_TX_LOCK(dev, txq, smp_processor_id()); if (!netif_xmit_frozen_or_stopped(txq)) skb = dev_hard_start_xmit(skb, dev, txq, &ret); HARD_TX_UNLOCK(dev, txq); + } else { + spin_lock(root_lock); + return qdisc_qlen(q); } spin_lock(root_lock); -- cgit v1.2.3 From d82bccc69041a51f7b7b9b4a36db0772f4cdba21 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Tue, 12 Apr 2016 10:26:19 -0700 Subject: bpf/verifier: reject invalid LD_ABS | BPF_DW instruction verifier must check for reserved size bits in instruction opcode and reject BPF_LD | BPF_ABS | BPF_DW and BPF_LD | BPF_IND | BPF_DW instructions, otherwise interpreter will WARN_RATELIMIT on them during execution. Fixes: ddd872bc3098 ("bpf: verifier: add checks for BPF_ABS | BPF_IND instructions") Signed-off-by: Alexei Starovoitov Acked-by: Daniel Borkmann Signed-off-by: David S. Miller --- kernel/bpf/verifier.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 2e08f8e9b771..618ef77c302a 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1374,6 +1374,7 @@ static int check_ld_abs(struct verifier_env *env, struct bpf_insn *insn) } if (insn->dst_reg != BPF_REG_0 || insn->off != 0 || + BPF_SIZE(insn->code) == BPF_DW || (mode == BPF_ABS && insn->src_reg != BPF_REG_0)) { verbose("BPF_LD_ABS uses reserved fields\n"); return -EINVAL; -- cgit v1.2.3 From 9aaf3437aa72ed5370bf32c99580a3fa2c330e3d Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 6 Apr 2016 16:12:08 +0200 Subject: mmc: block: Use the mmc host device index as the mmcblk device index Commit 520bd7a8b415 ("mmc: core: Optimize boot time by detecting cards simultaneously") causes regressions for some platforms. These platforms relies on fixed mmcblk device indexes, instead of deploying the defacto standard with UUID/PARTUUID. In other words their rootfs needs to be available at hardcoded paths, like /dev/mmcblk0p2. Such guarantees have never been made by the kernel, but clearly the above commit changes the behaviour. More precisely, because of that the order changes of how cards becomes detected, so do their corresponding mmcblk device indexes. As the above commit significantly improves boot time for some platforms (magnitude of seconds), let's avoid reverting this change but instead restore the behaviour of how mmcblk device indexes becomes picked. By using the same index for the mmcblk device as for the corresponding mmc host device, the probe order of mmc host devices decides the index we get for the mmcblk device. For those platforms that suffers from a regression, one could expect that this updated behaviour should be sufficient to meet their expectations of "fixed" mmcblk device indexes. Another side effect from this change, is that the same index is used for the mmc host device, the mmcblk device and the mmc block queue. That should clarify their relationship. Reported-by: Peter Hurley Reported-by: Laszlo Fiat Cc: Linus Torvalds Fixes: 520bd7a8b415 ("mmc: core: Optimize boot time by detecting cards simultaneously") Cc: Signed-off-by: Ulf Hansson --- drivers/mmc/card/block.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 3bdbe50a363f..8a0147dfed27 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -86,7 +86,6 @@ static int max_devices; /* TODO: Replace these with struct ida */ static DECLARE_BITMAP(dev_use, MAX_DEVICES); -static DECLARE_BITMAP(name_use, MAX_DEVICES); /* * There is one mmc_blk_data per slot. @@ -105,7 +104,6 @@ struct mmc_blk_data { unsigned int usage; unsigned int read_only; unsigned int part_type; - unsigned int name_idx; unsigned int reset_done; #define MMC_BLK_READ BIT(0) #define MMC_BLK_WRITE BIT(1) @@ -2202,19 +2200,6 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, goto out; } - /* - * !subname implies we are creating main mmc_blk_data that will be - * associated with mmc_card with dev_set_drvdata. Due to device - * partitions, devidx will not coincide with a per-physical card - * index anymore so we keep track of a name index. - */ - if (!subname) { - md->name_idx = find_first_zero_bit(name_use, max_devices); - __set_bit(md->name_idx, name_use); - } else - md->name_idx = ((struct mmc_blk_data *) - dev_to_disk(parent)->private_data)->name_idx; - md->area_type = area_type; /* @@ -2264,7 +2249,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, */ snprintf(md->disk->disk_name, sizeof(md->disk->disk_name), - "mmcblk%u%s", md->name_idx, subname ? subname : ""); + "mmcblk%u%s", card->host->index, subname ? subname : ""); if (mmc_card_mmc(card)) blk_queue_logical_block_size(md->queue.queue, @@ -2418,7 +2403,6 @@ static void mmc_blk_remove_parts(struct mmc_card *card, struct list_head *pos, *q; struct mmc_blk_data *part_md; - __clear_bit(md->name_idx, name_use); list_for_each_safe(pos, q, &md->part) { part_md = list_entry(pos, struct mmc_blk_data, part); list_del(pos); -- cgit v1.2.3 From 70ad7f7e40af31e7ab4a1719602542856b7ea856 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Wed, 13 Apr 2016 15:35:56 +0100 Subject: mmc: tegra: Disable UHS-I modes for Tegra124 Tegra124 has been randomly hanging during system suspend when entering the Tegra LP1 low power state. The hang is caused by the Tegra SDHCI driver and linked to the UHS-I tuning sequence. Disabling the UHS-I modes for Tegra124 prevents any hangs from occurring when entering system suspend. Unfortunately, the tuning sequence described in the public Tegra documentation is incomplete and on inspection of the current tuning sequence that has been implemented is also incomplete and may cause problems. In the short-term it is safer to disable UHS-I modes for now and fix later because it would be too large of a change to simply patch now. Therefore, disable UHS-I modes for Tegra124. Signed-off-by: Jon Hunter Acked-by: Thierry Reding Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-tegra.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index f8c4762bb48d..bcc0de47fe7e 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -382,14 +382,6 @@ static const struct sdhci_tegra_soc_data soc_data_tegra114 = { .pdata = &sdhci_tegra114_pdata, }; -static const struct sdhci_tegra_soc_data soc_data_tegra124 = { - .pdata = &sdhci_tegra114_pdata, - .nvquirks = NVQUIRK_ENABLE_SDR50 | - NVQUIRK_ENABLE_DDR50 | - NVQUIRK_ENABLE_SDR104 | - NVQUIRK_HAS_PADCALIB, -}; - static const struct sdhci_pltfm_data sdhci_tegra210_pdata = { .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | @@ -407,7 +399,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = { static const struct of_device_id sdhci_tegra_dt_match[] = { { .compatible = "nvidia,tegra210-sdhci", .data = &soc_data_tegra210 }, - { .compatible = "nvidia,tegra124-sdhci", .data = &soc_data_tegra124 }, + { .compatible = "nvidia,tegra124-sdhci", .data = &soc_data_tegra114 }, { .compatible = "nvidia,tegra114-sdhci", .data = &soc_data_tegra114 }, { .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 }, { .compatible = "nvidia,tegra20-sdhci", .data = &soc_data_tegra20 }, -- cgit v1.2.3 From 6dd22a116614acf33aeef13861e32510ef9d5392 Mon Sep 17 00:00:00 2001 From: Alexander Kurz Date: Sun, 10 Apr 2016 20:41:38 +0200 Subject: pinctrl: imx: Kconfig: PINCTRL_IMX select REGMAP Regmap functionality has been integrated into pinctrl-imx.c with commit 8626ada8 which might trigger build failures when regmap is not selected otherwise. Hence, make Kconfig aware about this new dependency. Signed-off-by: Alexander Kurz Acked-by: Philipp Zabel Acked-by: Shawn Guo Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index debe1219d76d..fc8cbf611723 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -2,6 +2,7 @@ config PINCTRL_IMX bool select PINMUX select PINCONF + select REGMAP config PINCTRL_IMX1_CORE bool -- cgit v1.2.3 From ad06fdeeef1cbadf86ebbe510e8079abada8b44e Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 20 Jan 2016 18:56:22 -0800 Subject: pwm: fsl-ftm: Use flat regmap cache Use flat regmap cache to avoid lockdep warning at probe: [ 0.697285] WARNING: CPU: 0 PID: 1 at kernel/locking/lockdep.c:2755 lockdep_trace_alloc+0x15c/0x160() [ 0.697449] DEBUG_LOCKS_WARN_ON(irqs_disabled_flags(flags)) The RB-tree regmap cache needs to allocate new space on first writes. However, allocations in an atomic context (e.g. when a spinlock is held) are not allowed. The function regmap_write calls map->lock, which acquires a spinlock in the fast_io case. Since the pwm-fsl-ftm driver uses MMIO, the regmap bus of type regmap_mmio is being used which has fast_io set to true. The MMIO space of the pwm-fsl-ftm driver is reasonable condense, hence using the much faster flat regmap cache is anyway the better choice. Signed-off-by: Stefan Agner Cc: Mark Brown Signed-off-by: Thierry Reding --- drivers/pwm/pwm-fsl-ftm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c index 7225ac6b3df5..fad968eb75f6 100644 --- a/drivers/pwm/pwm-fsl-ftm.c +++ b/drivers/pwm/pwm-fsl-ftm.c @@ -392,7 +392,7 @@ static const struct regmap_config fsl_pwm_regmap_config = { .max_register = FTM_PWMLOAD, .volatile_reg = fsl_pwm_volatile_reg, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_FLAT, }; static int fsl_pwm_probe(struct platform_device *pdev) -- cgit v1.2.3 From cba2e47abcbd80e3f46f460899290402f98090ec Mon Sep 17 00:00:00 2001 From: Toshi Kani Date: Tue, 12 Apr 2016 18:10:52 -0600 Subject: pmem: fix BUG() error in pmem.h:48 on X86_32 After 'commit fc0c2028135c ("x86, pmem: use memcpy_mcsafe() for memcpy_from_pmem()")', probing a PMEM device hits the BUG() error below on X86_32 kernel. kernel BUG at include/linux/pmem.h:48! memcpy_from_pmem() calls arch_memcpy_from_pmem(), which is unimplemented since CONFIG_ARCH_HAS_PMEM_API is undefined on X86_32. Fix the BUG() error by adding default_memcpy_from_pmem(). Acked-by: Dan Williams Signed-off-by: Toshi Kani Signed-off-by: Ross Zwisler Cc: Dan Williams Cc: Ross Zwisler --- include/linux/pmem.h | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/include/linux/pmem.h b/include/linux/pmem.h index ac6d872ce067..57d146fe44dd 100644 --- a/include/linux/pmem.h +++ b/include/linux/pmem.h @@ -72,6 +72,18 @@ static inline void arch_invalidate_pmem(void __pmem *addr, size_t size) } #endif +static inline bool arch_has_pmem_api(void) +{ + return IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API); +} + +static inline int default_memcpy_from_pmem(void *dst, void __pmem const *src, + size_t size) +{ + memcpy(dst, (void __force *) src, size); + return 0; +} + /* * memcpy_from_pmem - read from persistent memory with error handling * @dst: destination buffer @@ -83,12 +95,10 @@ static inline void arch_invalidate_pmem(void __pmem *addr, size_t size) static inline int memcpy_from_pmem(void *dst, void __pmem const *src, size_t size) { - return arch_memcpy_from_pmem(dst, src, size); -} - -static inline bool arch_has_pmem_api(void) -{ - return IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API); + if (arch_has_pmem_api()) + return arch_memcpy_from_pmem(dst, src, size); + else + return default_memcpy_from_pmem(dst, src, size); } /** -- cgit v1.2.3 From 1560d15861769c23fd981e2d60dc7fd790b21e1e Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Wed, 13 Apr 2016 20:49:48 -0500 Subject: ARM: OMAP3: Fix external abort on 36xx waking from off mode idle Depending on timing during the resume path from off mode on 36xx, we may see external aborts. These seem to be caused by the following: - OMAP3 Advisory 1.62 "MPU Cannot Exit from Standby" says we need to disable intc autoidle before WFI - DM3730 Advisory 1.106 "MPU Leaves MSTANDBY State Before IDLEREQ of Interrupt Controller is Released" says we need to wait before accessing intc omap3_intc_resume_idle restores the intc autoidle for all resume paths, however in the resume path from off mode only it is also being restored by omap_intc_restore_context before this call to omap3_intc_resume_idle happens. The second restore of the intc autoidle in this path is what appears to be causing the external abort so for the off mode resume path let's rely on omap_intc_restore_context to restore intc autoidle, and for all other paths let omap3_intc_resume_idle handle it as it is now. Signed-off-by: Dave Gerlach Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pm34xx.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 2dbd3785ee6f..d44e0e2f1106 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -198,7 +198,6 @@ void omap_sram_idle(void) int per_next_state = PWRDM_POWER_ON; int core_next_state = PWRDM_POWER_ON; int per_going_off; - int core_prev_state; u32 sdrc_pwr = 0; mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); @@ -278,16 +277,20 @@ void omap_sram_idle(void) sdrc_write_reg(sdrc_pwr, SDRC_POWER); /* CORE */ - if (core_next_state < PWRDM_POWER_ON) { - core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); - if (core_prev_state == PWRDM_POWER_OFF) { - omap3_core_restore_context(); - omap3_cm_restore_context(); - omap3_sram_restore_context(); - omap2_sms_restore_context(); - } + if (core_next_state < PWRDM_POWER_ON && + pwrdm_read_prev_pwrst(core_pwrdm) == PWRDM_POWER_OFF) { + omap3_core_restore_context(); + omap3_cm_restore_context(); + omap3_sram_restore_context(); + omap2_sms_restore_context(); + } else { + /* + * In off-mode resume path above, omap3_core_restore_context + * also handles the INTC autoidle restore done here so limit + * this to non-off mode resume paths so we don't do it twice. + */ + omap3_intc_resume_idle(); } - omap3_intc_resume_idle(); pwrdm_post_transition(NULL); -- cgit v1.2.3 From 366dd4ea9d5f0eb78fdf4982d76506f99480ec0a Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 13 Apr 2016 22:27:22 +0200 Subject: parisc: Fix ftrace function tracer Fix the FTRACE function tracer for 32- and 64-bit kernel. The former code was horribly broken. Reimplement most coding in assembly and utilize optimizations, e.g. put mcount() and ftrace_stub() into one L1 cacheline. Signed-off-by: Helge Deller --- arch/parisc/Kconfig | 4 +- arch/parisc/Kconfig.debug | 4 ++ arch/parisc/Makefile | 4 +- arch/parisc/include/asm/ftrace.h | 18 +---- arch/parisc/kernel/Makefile | 4 -- arch/parisc/kernel/entry.S | 93 ++++++++++++++++++++----- arch/parisc/kernel/ftrace.c | 146 ++++++--------------------------------- arch/parisc/kernel/head.S | 9 +++ 8 files changed, 114 insertions(+), 168 deletions(-) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 14f655cf542e..86167bf85aa1 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -4,8 +4,8 @@ config PARISC select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_IDE select HAVE_OPROFILE - select HAVE_FUNCTION_TRACER if 64BIT - select HAVE_FUNCTION_GRAPH_TRACER if 64BIT + select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_GRAPH_TRACER select ARCH_WANT_FRAME_POINTERS select RTC_CLASS select RTC_DRV_GENERIC diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug index bc989e522a04..68b7cbd0810a 100644 --- a/arch/parisc/Kconfig.debug +++ b/arch/parisc/Kconfig.debug @@ -2,9 +2,13 @@ menu "Kernel hacking" source "lib/Kconfig.debug" +config TRACE_IRQFLAGS_SUPPORT + def_bool y + config DEBUG_RODATA bool "Write protect kernel read-only data structures" depends on DEBUG_KERNEL + default y help Mark the kernel read-only data as write-protected in the pagetables, in order to catch accidental (and incorrect) writes to such const diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 965a0999fc4c..75cb451b1f03 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -62,9 +62,7 @@ cflags-y += -mdisable-fpregs # Without this, "ld -r" results in .text sections that are too big # (> 0x40000) for branches to reach stubs. -ifndef CONFIG_FUNCTION_TRACER - cflags-y += -ffunction-sections -endif +cflags-y += -ffunction-sections # Use long jumps instead of long branches (needed if your linker fails to # link a too big vmlinux executable). Not enabled for building modules. diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h index 544ed8ef87eb..24cd81d58d70 100644 --- a/arch/parisc/include/asm/ftrace.h +++ b/arch/parisc/include/asm/ftrace.h @@ -4,23 +4,7 @@ #ifndef __ASSEMBLY__ extern void mcount(void); -/* - * Stack of return addresses for functions of a thread. - * Used in struct thread_info - */ -struct ftrace_ret_stack { - unsigned long ret; - unsigned long func; - unsigned long long calltime; -}; - -/* - * Primary handler of a function return. - * It relays on ftrace_return_to_handler. - * Defined in entry.S - */ -extern void return_to_handler(void); - +#define MCOUNT_INSN_SIZE 4 extern unsigned long return_address(unsigned int); diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index ff87b4603e3d..69a11183d48d 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -15,11 +15,7 @@ ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_cache.o = -pg -CFLAGS_REMOVE_irq.o = -pg -CFLAGS_REMOVE_pacache.o = -pg CFLAGS_REMOVE_perf.o = -pg -CFLAGS_REMOVE_traps.o = -pg -CFLAGS_REMOVE_unaligned.o = -pg CFLAGS_REMOVE_unwind.o = -pg endif diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 623496c11756..39127d3e70e5 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -1970,43 +1970,98 @@ pt_regs_ok: b intr_restore copy %r25,%r16 - .import schedule,code syscall_do_resched: - BL schedule,%r2 + load32 syscall_check_resched,%r2 /* if resched, we start over again */ + load32 schedule,%r19 + bv %r0(%r19) /* jumps to schedule() */ #ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #else nop #endif - b syscall_check_resched /* if resched, we start over again */ - nop ENDPROC(syscall_exit) #ifdef CONFIG_FUNCTION_TRACER + .import ftrace_function_trampoline,code -ENTRY(_mcount) - copy %r3, %arg2 + .align L1_CACHE_BYTES + .globl mcount + .type mcount, @function +ENTRY(mcount) +_mcount: + .export _mcount,data + .proc + .callinfo caller,frame=0 + .entry + /* + * The 64bit mcount() function pointer needs 4 dwords, of which the + * first two are free. We optimize it here and put 2 instructions for + * calling mcount(), and 2 instructions for ftrace_stub(). That way we + * have all on one L1 cacheline. + */ b ftrace_function_trampoline + copy %r3, %arg2 /* caller original %sp */ +ftrace_stub: + .globl ftrace_stub + .type ftrace_stub, @function +#ifdef CONFIG_64BIT + bve (%rp) +#else + bv %r0(%rp) +#endif nop -ENDPROC(_mcount) +#ifdef CONFIG_64BIT + .dword mcount + .dword 0 /* code in head.S puts value of global gp here */ +#endif + .exit + .procend +ENDPROC(mcount) + .align 8 + .globl return_to_handler + .type return_to_handler, @function ENTRY(return_to_handler) - load32 return_trampoline, %rp - copy %ret0, %arg0 - copy %ret1, %arg1 - b ftrace_return_to_handler - nop -return_trampoline: - copy %ret0, %rp - copy %r23, %ret0 - copy %r24, %ret1 + .proc + .callinfo caller,frame=FRAME_SIZE + .entry + .export parisc_return_to_handler,data +parisc_return_to_handler: + copy %r3,%r1 + STREG %r0,-RP_OFFSET(%sp) /* store 0 as %rp */ + copy %sp,%r3 + STREGM %r1,FRAME_SIZE(%sp) + STREG %ret0,8(%r3) + STREG %ret1,16(%r3) -.globl ftrace_stub -ftrace_stub: +#ifdef CONFIG_64BIT + loadgp +#endif + + /* call ftrace_return_to_handler(0) */ +#ifdef CONFIG_64BIT + ldo -16(%sp),%ret1 /* Reference param save area */ +#endif + BL ftrace_return_to_handler,%r2 + ldi 0,%r26 + copy %ret0,%rp + + /* restore original return values */ + LDREG 8(%r3),%ret0 + LDREG 16(%r3),%ret1 + + /* return from function */ +#ifdef CONFIG_64BIT + bve (%rp) +#else bv %r0(%rp) - nop +#endif + LDREGM -FRAME_SIZE(%sp),%r3 + .exit + .procend ENDPROC(return_to_handler) + #endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_IRQSTACKS diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c index 559d400f9385..b13f9ec6f294 100644 --- a/arch/parisc/kernel/ftrace.c +++ b/arch/parisc/kernel/ftrace.c @@ -1,6 +1,6 @@ /* * Code for tracing calls in Linux kernel. - * Copyright (C) 2009 Helge Deller + * Copyright (C) 2009-2016 Helge Deller * * based on code for x86 which is: * Copyright (C) 2007-2008 Steven Rostedt @@ -13,104 +13,21 @@ #include #include +#include #include #include - #ifdef CONFIG_FUNCTION_GRAPH_TRACER - -/* Add a function return address to the trace stack on thread info.*/ -static int push_return_trace(unsigned long ret, unsigned long long time, - unsigned long func, int *depth) -{ - int index; - - if (!current->ret_stack) - return -EBUSY; - - /* The return trace stack is full */ - if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) { - atomic_inc(¤t->trace_overrun); - return -EBUSY; - } - - index = ++current->curr_ret_stack; - barrier(); - current->ret_stack[index].ret = ret; - current->ret_stack[index].func = func; - current->ret_stack[index].calltime = time; - *depth = index; - - return 0; -} - -/* Retrieve a function return address to the trace stack on thread info.*/ -static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret) -{ - int index; - - index = current->curr_ret_stack; - - if (unlikely(index < 0)) { - ftrace_graph_stop(); - WARN_ON(1); - /* Might as well panic, otherwise we have no where to go */ - *ret = (unsigned long) - dereference_function_descriptor(&panic); - return; - } - - *ret = current->ret_stack[index].ret; - trace->func = current->ret_stack[index].func; - trace->calltime = current->ret_stack[index].calltime; - trace->overrun = atomic_read(¤t->trace_overrun); - trace->depth = index; - barrier(); - current->curr_ret_stack--; - -} - -/* - * Send the trace to the ring-buffer. - * @return the original return address. - */ -unsigned long ftrace_return_to_handler(unsigned long retval0, - unsigned long retval1) -{ - struct ftrace_graph_ret trace; - unsigned long ret; - - pop_return_trace(&trace, &ret); - trace.rettime = local_clock(); - ftrace_graph_return(&trace); - - if (unlikely(!ret)) { - ftrace_graph_stop(); - WARN_ON(1); - /* Might as well panic. What else to do? */ - ret = (unsigned long) - dereference_function_descriptor(&panic); - } - - /* HACK: we hand over the old functions' return values - in %r23 and %r24. Assembly in entry.S will take care - and move those to their final registers %ret0 and %ret1 */ - asm( "copy %0, %%r23 \n\t" - "copy %1, %%r24 \n" : : "r" (retval0), "r" (retval1) ); - - return ret; -} - /* * Hook the return address and push it in the stack of return addrs * in current thread info. */ -void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) +static void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) { unsigned long old; - unsigned long long calltime; struct ftrace_graph_ent trace; + extern int parisc_return_to_handler; if (unlikely(ftrace_graph_is_dead())) return; @@ -119,64 +36,47 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) return; old = *parent; - *parent = (unsigned long) - dereference_function_descriptor(&return_to_handler); - if (unlikely(!__kernel_text_address(old))) { - ftrace_graph_stop(); - *parent = old; - WARN_ON(1); - return; - } - - calltime = local_clock(); + trace.func = self_addr; + trace.depth = current->curr_ret_stack + 1; - if (push_return_trace(old, calltime, - self_addr, &trace.depth) == -EBUSY) { - *parent = old; + /* Only trace if the calling function expects to */ + if (!ftrace_graph_entry(&trace)) return; - } - trace.func = self_addr; + if (ftrace_push_return_trace(old, self_addr, &trace.depth, + 0 ) == -EBUSY) + return; - /* Only trace if the calling function expects to */ - if (!ftrace_graph_entry(&trace)) { - current->curr_ret_stack--; - *parent = old; - } + /* activate parisc_return_to_handler() as return point */ + *parent = (unsigned long) &parisc_return_to_handler; } - #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ - -void ftrace_function_trampoline(unsigned long parent, +void notrace ftrace_function_trampoline(unsigned long parent, unsigned long self_addr, unsigned long org_sp_gr3) { - extern ftrace_func_t ftrace_trace_function; + extern ftrace_func_t ftrace_trace_function; /* depends on CONFIG_DYNAMIC_FTRACE */ + extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace); if (ftrace_trace_function != ftrace_stub) { - ftrace_trace_function(parent, self_addr); + /* struct ftrace_ops *op, struct pt_regs *regs); */ + ftrace_trace_function(parent, self_addr, NULL, NULL); return; } + #ifdef CONFIG_FUNCTION_GRAPH_TRACER - if (ftrace_graph_entry && ftrace_graph_return) { - unsigned long sp; + if (ftrace_graph_return != (trace_func_graph_ret_t) ftrace_stub || + ftrace_graph_entry != ftrace_graph_entry_stub) { unsigned long *parent_rp; - asm volatile ("copy %%r30, %0" : "=r"(sp)); - /* sanity check: is stack pointer which we got from - assembler function in entry.S in a reasonable - range compared to current stack pointer? */ - if ((sp - org_sp_gr3) > 0x400) - return; - /* calculate pointer to %rp in stack */ - parent_rp = (unsigned long *) org_sp_gr3 - 0x10; + parent_rp = (unsigned long *) (org_sp_gr3 - RP_OFFSET); /* sanity check: parent_rp should hold parent */ if (*parent_rp != parent) return; - + prepare_ftrace_return(parent_rp, self_addr); return; } diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 75aa0db9f69e..bbbe360b458f 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -129,6 +129,15 @@ $pgt_fill_loop: /* And the stack pointer too */ ldo THREAD_SZ_ALGN(%r6),%sp +#if defined(CONFIG_64BIT) && defined(CONFIG_FUNCTION_TRACER) + .import _mcount,data + /* initialize mcount FPTR */ + /* Get the global data pointer */ + loadgp + load32 PA(_mcount), %r10 + std %dp,0x18(%r10) +#endif + #ifdef CONFIG_SMP /* Set the smp rendezvous address into page zero. ** It would be safer to do this in init_smp_config() but -- cgit v1.2.3 From 7dedd15dd2527055390b9742c87a02556d3180f4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Apr 2016 12:31:49 +0300 Subject: md/raid0: fix uninitialized variable bug If this function fails the callers expect that *private_conf is set to an ERR_PTR() but that isn't true for the first error path where we can't allocate "conf". It leads to some uninitialized variable bugs. Signed-off-by: Dan Carpenter Signed-off-by: Shaohua Li --- drivers/md/raid0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 2ea12c6bf659..f63dbb68e3a9 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -85,6 +85,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL); unsigned short blksize = 512; + *private_conf = ERR_PTR(-ENOMEM); if (!conf) return -ENOMEM; rdev_for_each(rdev1, mddev) { -- cgit v1.2.3 From 4046d6e81f33b7ef50d6668b78076d54c5e066b6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 14 Apr 2016 11:18:57 -0700 Subject: Revert "x86: remove the kernel code/data/bss resources from /proc/iomem" This reverts commit c4004b02f8e5b9ce357a0bb1641756cc86962664. Sadly, my hope that nobody would actually use the special kernel entries in /proc/iomem were dashed by kexec. Which reads /proc/iomem explicitly to find the kernel base address. Nasty. Anyway, that means we can't do the sane and simple thing and just remove the entries, and we'll instead have to mask them out based on permissions. Reported-by: Zhengyu Zhang Reported-by: Dave Young Reported-by: Freeman Zhang Reported-by: Emrah Demir Reported-by: Baoquan He Signed-off-by: Linus Torvalds --- arch/x86/kernel/setup.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 319b08a5b6ed..2367ae07eb76 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -146,6 +146,31 @@ int default_check_phys_apicid_present(int phys_apicid) struct boot_params boot_params; +/* + * Machine setup.. + */ +static struct resource data_resource = { + .name = "Kernel data", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM +}; + +static struct resource code_resource = { + .name = "Kernel code", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM +}; + +static struct resource bss_resource = { + .name = "Kernel bss", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM +}; + + #ifdef CONFIG_X86_32 /* cpu data as detected by the assembly code in head.S */ struct cpuinfo_x86 new_cpu_data = { @@ -924,6 +949,13 @@ void __init setup_arch(char **cmdline_p) mpx_mm_init(&init_mm); + code_resource.start = __pa_symbol(_text); + code_resource.end = __pa_symbol(_etext)-1; + data_resource.start = __pa_symbol(_etext); + data_resource.end = __pa_symbol(_edata)-1; + bss_resource.start = __pa_symbol(__bss_start); + bss_resource.end = __pa_symbol(__bss_stop)-1; + #ifdef CONFIG_CMDLINE_BOOL #ifdef CONFIG_CMDLINE_OVERRIDE strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); @@ -987,6 +1019,11 @@ void __init setup_arch(char **cmdline_p) x86_init.resources.probe_roms(); + /* after parse_early_param, so could debug it */ + insert_resource(&iomem_resource, &code_resource); + insert_resource(&iomem_resource, &data_resource); + insert_resource(&iomem_resource, &bss_resource); + e820_add_kernel_range(); trim_bios_range(); #ifdef CONFIG_X86_32 -- cgit v1.2.3 From 34dbbcdbf63360661ff7bda6c5f52f99ac515f92 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 14 Apr 2016 11:22:00 -0700 Subject: Make file credentials available to the seqfile interfaces A lot of seqfile users seem to be using things like %pK that uses the credentials of the current process, but that is actually completely wrong for filesystem interfaces. The unix semantics for permission checking files is to check permissions at _open_ time, not at read or write time, and that is not just a small detail: passing off stdin/stdout/stderr to a suid application and making the actual IO happen in privileged context is a classic exploit technique. So if we want to be able to look at permissions at read time, we need to use the file open credentials, not the current ones. Normal file accesses can just use "f_cred" (or any of the helper functions that do that, like file_ns_capable()), but the seqfile interfaces do not have any such options. It turns out that seq_file _does_ save away the user_ns information of the file, though. Since user_ns is just part of the full credential information, replace that special case with saving off the cred pointer instead, and suddenly seq_file has all the permission information it needs. Signed-off-by: Linus Torvalds --- fs/seq_file.c | 7 ++++--- include/linux/seq_file.h | 13 ++++--------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/fs/seq_file.c b/fs/seq_file.c index e85664b7c7d9..19f532e7d35e 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -72,9 +72,10 @@ int seq_open(struct file *file, const struct seq_operations *op) mutex_init(&p->lock); p->op = op; -#ifdef CONFIG_USER_NS - p->user_ns = file->f_cred->user_ns; -#endif + + // No refcounting: the lifetime of 'p' is constrained + // to the lifetime of the file. + p->file = file; /* * Wrappers around seq_open(e.g. swaps_open) need to be diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index dde00defbaa5..f3d45dd42695 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -7,13 +7,10 @@ #include #include #include +#include +#include struct seq_operations; -struct file; -struct path; -struct inode; -struct dentry; -struct user_namespace; struct seq_file { char *buf; @@ -27,9 +24,7 @@ struct seq_file { struct mutex lock; const struct seq_operations *op; int poll_event; -#ifdef CONFIG_USER_NS - struct user_namespace *user_ns; -#endif + const struct file *file; void *private; }; @@ -147,7 +142,7 @@ int seq_release_private(struct inode *, struct file *); static inline struct user_namespace *seq_user_ns(struct seq_file *seq) { #ifdef CONFIG_USER_NS - return seq->user_ns; + return seq->file->f_cred->user_ns; #else extern struct user_namespace init_user_ns; return &init_user_ns; -- cgit v1.2.3 From ab0fa82b2df96ddadb327ac39f26b5d80cb3d104 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 14 Apr 2016 12:00:21 -0700 Subject: pci-sysfs: use proper file capability helper function The PCI config access checked the file capabilities correctly, but used the itnernal security capability check rather than the helper function that is actually meant for that. The security_capable() has unusual return values and is not meant to be used elsewhere (the only other use is in the capability checking functions that we actually intend people to use, and this odd PCI usage really stood out when looking around the capability code. Signed-off-by: Linus Torvalds --- drivers/pci/pci-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index e982010f0ed1..342b6918bbde 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -636,7 +636,7 @@ static ssize_t pci_read_config(struct file *filp, struct kobject *kobj, u8 *data = (u8 *) buf; /* Several chips lock up trying to read undefined config space */ - if (security_capable(filp->f_cred, &init_user_ns, CAP_SYS_ADMIN) == 0) + if (file_ns_capable(filp, &init_user_ns, CAP_SYS_ADMIN)) size = dev->cfg_size; else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) size = 128; -- cgit v1.2.3 From 51d7b120418e99d6b3bf8df9eb3cc31e8171dee4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 14 Apr 2016 12:05:37 -0700 Subject: /proc/iomem: only expose physical resource addresses to privileged users In commit c4004b02f8e5b ("x86: remove the kernel code/data/bss resources from /proc/iomem") I was hoping to remove the phyiscal kernel address data from /proc/iomem entirely, but that had to be reverted because some system programs actually use it. This limits all the detailed resource information to properly credentialed users instead. Signed-off-by: Linus Torvalds --- kernel/resource.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/resource.c b/kernel/resource.c index 2e78ead30934..9b5f04404152 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -105,16 +105,25 @@ static int r_show(struct seq_file *m, void *v) { struct resource *root = m->private; struct resource *r = v, *p; + unsigned long long start, end; int width = root->end < 0x10000 ? 4 : 8; int depth; for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent) if (p->parent == root) break; + + if (file_ns_capable(m->file, &init_user_ns, CAP_SYS_ADMIN)) { + start = r->start; + end = r->end; + } else { + start = end = 0; + } + seq_printf(m, "%*s%0*llx-%0*llx : %s\n", depth * 2, "", - width, (unsigned long long) r->start, - width, (unsigned long long) r->end, + width, start, + width, end, r->name ? r->name : ""); return 0; } -- cgit v1.2.3 From a5229050b69cfffb690b546c357ca5a60434c0c8 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 8 Apr 2016 16:09:10 -0600 Subject: NVMe: Always use MSI/MSI-x interrupts Multiple users have reported device initialization failure due the driver not receiving legacy PCI interrupts. This is not unique to any particular controller, but has been observed on multiple platforms. There have been no issues reported or observed when with message signaled interrupts, so this patch attempts to use MSI-x during initialization, falling back to MSI. If that fails, legacy would become the default. The setup_io_queues error handling had to change as a result: the admin queue's msix_entry used to be initialized to the legacy IRQ. The case where nr_io_queues is 0 would fail request_irq when setting up the admin queue's interrupt since re-enabling MSI-x fails with 0 vectors, leaving the admin queue's msix_entry invalid. Instead, return success immediately. Reported-by: Tim Muhlemmer Reported-by: Jon Derrick Signed-off-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/nvme/host/pci.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 660ec84bc40f..4fd733ff72b1 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1478,8 +1478,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) if (result > 0) { dev_err(dev->ctrl.device, "Could not set queue count (%d)\n", result); - nr_io_queues = 0; - result = 0; + return 0; } if (dev->cmb && NVME_CMB_SQS(dev->cmbsz)) { @@ -1513,7 +1512,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) * If we enable msix early due to not intx, disable it again before * setting up the full range we need. */ - if (!pdev->irq) + if (pdev->msi_enabled) + pci_disable_msi(pdev); + else if (pdev->msix_enabled) pci_disable_msix(pdev); for (i = 0; i < nr_io_queues; i++) @@ -1696,7 +1697,6 @@ static int nvme_pci_enable(struct nvme_dev *dev) if (pci_enable_device_mem(pdev)) return result; - dev->entry[0].vector = pdev->irq; pci_set_master(pdev); if (dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(64)) && @@ -1709,13 +1709,18 @@ static int nvme_pci_enable(struct nvme_dev *dev) } /* - * Some devices don't advertse INTx interrupts, pre-enable a single - * MSIX vec for setup. We'll adjust this later. + * Some devices and/or platforms don't advertise or work with INTx + * interrupts. Pre-enable a single MSIX or MSI vec for setup. We'll + * adjust this later. */ - if (!pdev->irq) { - result = pci_enable_msix(pdev, dev->entry, 1); - if (result < 0) - goto disable; + if (pci_enable_msix(pdev, dev->entry, 1)) { + pci_enable_msi(pdev); + dev->entry[0].vector = pdev->irq; + } + + if (!dev->entry[0].vector) { + result = -ENODEV; + goto disable; } cap = lo_hi_readq(dev->bar + NVME_REG_CAP); -- cgit v1.2.3 From f1d0540db6a21395a58268f4392c7420ebae8c1d Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 12 Apr 2016 08:35:18 +0200 Subject: net: mediatek: update the IRQ part of the binding document The current binding document only describes a single interrupt. Update the document by adding the 2 other interrupts. The driver currently only uses a single interrupt. The HW is however able to using IRQ grouping to split TX and RX onto separate GIC irqs. Signed-off-by: John Crispin Cc: devicetree@vger.kernel.org Acked-by: Rob Herring Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/mediatek-net.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/net/mediatek-net.txt b/Documentation/devicetree/bindings/net/mediatek-net.txt index 5ca79290eabf..32eaaca04d9b 100644 --- a/Documentation/devicetree/bindings/net/mediatek-net.txt +++ b/Documentation/devicetree/bindings/net/mediatek-net.txt @@ -9,7 +9,8 @@ have dual GMAC each represented by a child node.. Required properties: - compatible: Should be "mediatek,mt7623-eth" - reg: Address and length of the register set for the device -- interrupts: Should contain the frame engines interrupt +- interrupts: Should contain the three frame engines interrupts in numeric + order. These are fe_int0, fe_int1 and fe_int2. - clocks: the clock used by the core - clock-names: the names of the clock listed in the clocks property. These are "ethif", "esw", "gp2", "gp1" @@ -42,7 +43,9 @@ eth: ethernet@1b100000 { <ðsys CLK_ETHSYS_GP2>, <ðsys CLK_ETHSYS_GP1>; clock-names = "ethif", "esw", "gp2", "gp1"; - interrupts = ; + interrupts = ; power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; resets = <ðsys MT2701_ETHSYS_ETH_RST>; reset-names = "eth"; -- cgit v1.2.3 From 80fbdb208f37740774652ba095a5b2045205ed59 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Mon, 11 Apr 2016 15:29:34 -0700 Subject: ipv6: datagram: Refactor flowi6 init codes to a new function Move flowi6 init codes for connected datagram sk to a newly created function ip6_datagram_flow_key_init(). Notes: 1. fl6_flowlabel is used instead of fl6.flowlabel in __ip6_datagram_connect 2. ipv6_addr_is_multicast(&fl6->daddr) is used instead of (addr_type & IPV6_ADDR_MULTICAST) in ip6_datagram_flow_key_init() This new function will be reused during pmtu update in the later patch. Signed-off-by: Martin KaFai Lau Cc: Cong Wang Cc: Eric Dumazet Cc: Wei Wang Signed-off-by: David S. Miller --- net/ipv6/datagram.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 428162155280..f07c1ddb5cac 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -40,6 +40,30 @@ static bool ipv6_mapped_addr_any(const struct in6_addr *a) return ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0); } +static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk) +{ + struct inet_sock *inet = inet_sk(sk); + struct ipv6_pinfo *np = inet6_sk(sk); + + memset(fl6, 0, sizeof(*fl6)); + fl6->flowi6_proto = sk->sk_protocol; + fl6->daddr = sk->sk_v6_daddr; + fl6->saddr = np->saddr; + fl6->flowi6_oif = sk->sk_bound_dev_if; + fl6->flowi6_mark = sk->sk_mark; + fl6->fl6_dport = inet->inet_dport; + fl6->fl6_sport = inet->inet_sport; + fl6->flowlabel = np->flow_label; + + if (!fl6->flowi6_oif) + fl6->flowi6_oif = np->sticky_pktinfo.ipi6_ifindex; + + if (!fl6->flowi6_oif && ipv6_addr_is_multicast(&fl6->daddr)) + fl6->flowi6_oif = np->mcast_oif; + + security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); +} + static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) { struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; @@ -52,6 +76,7 @@ static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int a struct ipv6_txoptions *opt; int addr_type; int err; + __be32 fl6_flowlabel = 0; if (usin->sin6_family == AF_INET) { if (__ipv6_only_sock(sk)) @@ -66,11 +91,10 @@ static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int a if (usin->sin6_family != AF_INET6) return -EAFNOSUPPORT; - memset(&fl6, 0, sizeof(fl6)); if (np->sndflow) { - fl6.flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK; - if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { - flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); + fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK; + if (fl6_flowlabel & IPV6_FLOWLABEL_MASK) { + flowlabel = fl6_sock_lookup(sk, fl6_flowlabel); if (!flowlabel) return -EINVAL; } @@ -145,7 +169,7 @@ ipv4_connected: } sk->sk_v6_daddr = *daddr; - np->flow_label = fl6.flowlabel; + np->flow_label = fl6_flowlabel; inet->inet_dport = usin->sin6_port; @@ -154,21 +178,7 @@ ipv4_connected: * destination cache for it. */ - fl6.flowi6_proto = sk->sk_protocol; - fl6.daddr = sk->sk_v6_daddr; - fl6.saddr = np->saddr; - fl6.flowi6_oif = sk->sk_bound_dev_if; - fl6.flowi6_mark = sk->sk_mark; - fl6.fl6_dport = inet->inet_dport; - fl6.fl6_sport = inet->inet_sport; - - if (!fl6.flowi6_oif) - fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex; - - if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST)) - fl6.flowi6_oif = np->mcast_oif; - - security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); + ip6_datagram_flow_key_init(&fl6, sk); rcu_read_lock(); opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt); -- cgit v1.2.3 From 7e2040db1539a904924b997a14ebd3de53172100 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Mon, 11 Apr 2016 15:29:35 -0700 Subject: ipv6: datagram: Refactor dst lookup and update codes to a new function This patch moves the route lookup and update codes for connected datagram sk to a newly created function ip6_datagram_dst_update() It will be reused during the pmtu update in the later patch. Signed-off-by: Martin KaFai Lau Cc: Cong Wang Cc: Eric Dumazet Cc: Wei Wang Signed-off-by: David S. Miller --- net/ipv6/datagram.c | 103 +++++++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index f07c1ddb5cac..669585e11294 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -64,16 +64,65 @@ static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk) security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); } +static int ip6_datagram_dst_update(struct sock *sk) +{ + struct ip6_flowlabel *flowlabel = NULL; + struct in6_addr *final_p, final; + struct ipv6_txoptions *opt; + struct dst_entry *dst; + struct inet_sock *inet = inet_sk(sk); + struct ipv6_pinfo *np = inet6_sk(sk); + struct flowi6 fl6; + int err = 0; + + if (np->sndflow && (np->flow_label & IPV6_FLOWLABEL_MASK)) { + flowlabel = fl6_sock_lookup(sk, np->flow_label); + if (!flowlabel) + return -EINVAL; + } + ip6_datagram_flow_key_init(&fl6, sk); + + 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); + if (IS_ERR(dst)) { + err = PTR_ERR(dst); + goto out; + } + + if (ipv6_addr_any(&np->saddr)) + np->saddr = fl6.saddr; + + if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { + sk->sk_v6_rcv_saddr = fl6.saddr; + inet->inet_rcv_saddr = LOOPBACK4_IPV6; + if (sk->sk_prot->rehash) + sk->sk_prot->rehash(sk); + } + + ip6_dst_store(sk, dst, + ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ? + &sk->sk_v6_daddr : NULL, +#ifdef CONFIG_IPV6_SUBTREES + ipv6_addr_equal(&fl6.saddr, &np->saddr) ? + &np->saddr : +#endif + NULL); + +out: + fl6_sock_release(flowlabel); + return err; +} + static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) { struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); - struct in6_addr *daddr, *final_p, final; - struct dst_entry *dst; - struct flowi6 fl6; - struct ip6_flowlabel *flowlabel = NULL; - struct ipv6_txoptions *opt; + struct in6_addr *daddr; int addr_type; int err; __be32 fl6_flowlabel = 0; @@ -91,14 +140,8 @@ static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int a if (usin->sin6_family != AF_INET6) return -EAFNOSUPPORT; - if (np->sndflow) { + if (np->sndflow) fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK; - if (fl6_flowlabel & IPV6_FLOWLABEL_MASK) { - flowlabel = fl6_sock_lookup(sk, fl6_flowlabel); - if (!flowlabel) - return -EINVAL; - } - } addr_type = ipv6_addr_type(&usin->sin6_addr); @@ -178,45 +221,13 @@ ipv4_connected: * destination cache for it. */ - ip6_datagram_flow_key_init(&fl6, sk); - - 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); - err = 0; - if (IS_ERR(dst)) { - err = PTR_ERR(dst); + err = ip6_datagram_dst_update(sk); + if (err) goto out; - } - - /* source address lookup done in ip6_dst_lookup */ - - if (ipv6_addr_any(&np->saddr)) - np->saddr = fl6.saddr; - - if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { - sk->sk_v6_rcv_saddr = fl6.saddr; - inet->inet_rcv_saddr = LOOPBACK4_IPV6; - if (sk->sk_prot->rehash) - sk->sk_prot->rehash(sk); - } - - ip6_dst_store(sk, dst, - ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ? - &sk->sk_v6_daddr : NULL, -#ifdef CONFIG_IPV6_SUBTREES - ipv6_addr_equal(&fl6.saddr, &np->saddr) ? - &np->saddr : -#endif - NULL); sk->sk_state = TCP_ESTABLISHED; sk_set_txhash(sk); out: - fl6_sock_release(flowlabel); return err; } -- cgit v1.2.3 From 33c162a980fe03498fcecb917f618ad7e7c55e61 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Mon, 11 Apr 2016 15:29:36 -0700 Subject: ipv6: datagram: Update dst cache of a connected datagram sk during pmtu update There is a case in connected UDP socket such that getsockopt(IPV6_MTU) will return a stale MTU value. The reproducible sequence could be the following: 1. Create a connected UDP socket 2. Send some datagrams out 3. Receive a ICMPV6_PKT_TOOBIG 4. No new outgoing datagrams to trigger the sk_dst_check() logic to update the sk->sk_dst_cache. 5. getsockopt(IPV6_MTU) returns the mtu from the invalid sk->sk_dst_cache instead of the newly created RTF_CACHE clone. This patch updates the sk->sk_dst_cache for a connected datagram sk during pmtu-update code path. Note that the sk->sk_v6_daddr is used to do the route lookup instead of skb->data (i.e. iph). It is because a UDP socket can become connected after sending out some datagrams in un-connected state. or It can be connected multiple times to different destinations. Hence, iph may not be related to where sk is currently connected to. It is done under '!sock_owned_by_user(sk)' condition because the user may make another ip6_datagram_connect() (i.e changing the sk->sk_v6_daddr) while dst lookup is happening in the pmtu-update code path. For the sock_owned_by_user(sk) == true case, the next patch will introduce a release_cb() which will update the sk->sk_dst_cache. Test: Server (Connected UDP Socket): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Route Details: [root@arch-fb-vm1 ~]# ip -6 r show | egrep '2fac' 2fac::/64 dev eth0 proto kernel metric 256 pref medium 2fac:face::/64 via 2fac::face dev eth0 metric 1024 pref medium A simple python code to create a connected UDP socket: import socket import errno HOST = '2fac::1' PORT = 8080 s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) s.bind((HOST, PORT)) s.connect(('2fac:face::face', 53)) print("connected") while True: try: data = s.recv(1024) except socket.error as se: if se.errno == errno.EMSGSIZE: pmtu = s.getsockopt(41, 24) print("PMTU:%d" % pmtu) break s.close() Python program output after getting a ICMPV6_PKT_TOOBIG: [root@arch-fb-vm1 ~]# python2 ~/devshare/kernel/tasks/fib6/udp-connect-53-8080.py connected PMTU:1300 Cache routes after recieving TOOBIG: [root@arch-fb-vm1 ~]# ip -6 r show table cache 2fac:face::face via 2fac::face dev eth0 metric 0 cache expires 463sec mtu 1300 pref medium Client (Send the ICMPV6_PKT_TOOBIG): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ scapy is used to generate the TOOBIG message. Here is the scapy script I have used: >>> p=Ether(src='da:75:4d:36:ac:32', dst='52:54:00:12:34:66', type=0x86dd)/IPv6(src='2fac::face', dst='2fac::1')/ICMPv6PacketTooBig(mtu=1300)/IPv6(src='2fac:: 1',dst='2fac:face::face', nh='UDP')/UDP(sport=8080,dport=53) >>> sendp(p, iface='qemubr0') Fixes: 45e4fd26683c ("ipv6: Only create RTF_CACHE routes after encountering pmtu exception") Signed-off-by: Martin KaFai Lau Reported-by: Wei Wang Cc: Cong Wang Cc: Eric Dumazet Cc: Wei Wang Signed-off-by: David S. Miller --- include/net/ipv6.h | 1 + net/ipv6/datagram.c | 20 +++++++++++--------- net/ipv6/route.c | 12 ++++++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index d0aeb97aec5d..fd02e90b1289 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -959,6 +959,7 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len); int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *addr, int addr_len); +int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr); int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len); diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 669585e11294..59e01f27db9f 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -64,7 +64,7 @@ static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk) security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); } -static int ip6_datagram_dst_update(struct sock *sk) +int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr) { struct ip6_flowlabel *flowlabel = NULL; struct in6_addr *final_p, final; @@ -93,14 +93,16 @@ static int ip6_datagram_dst_update(struct sock *sk) goto out; } - if (ipv6_addr_any(&np->saddr)) - np->saddr = fl6.saddr; + if (fix_sk_saddr) { + if (ipv6_addr_any(&np->saddr)) + np->saddr = fl6.saddr; - if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { - sk->sk_v6_rcv_saddr = fl6.saddr; - inet->inet_rcv_saddr = LOOPBACK4_IPV6; - if (sk->sk_prot->rehash) - sk->sk_prot->rehash(sk); + if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) { + sk->sk_v6_rcv_saddr = fl6.saddr; + inet->inet_rcv_saddr = LOOPBACK4_IPV6; + if (sk->sk_prot->rehash) + sk->sk_prot->rehash(sk); + } } ip6_dst_store(sk, dst, @@ -221,7 +223,7 @@ ipv4_connected: * destination cache for it. */ - err = ip6_datagram_dst_update(sk); + err = ip6_datagram_dst_update(sk, true); if (err) goto out; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1d8871a5ed20..d916d6ab9ad2 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1418,8 +1418,20 @@ EXPORT_SYMBOL_GPL(ip6_update_pmtu); void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu) { + struct dst_entry *dst; + ip6_update_pmtu(skb, sock_net(sk), mtu, sk->sk_bound_dev_if, sk->sk_mark); + + dst = __sk_dst_get(sk); + if (!dst || !dst->obsolete || + dst->ops->check(dst, inet6_sk(sk)->dst_cookie)) + return; + + bh_lock_sock(sk); + if (!sock_owned_by_user(sk) && !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) + ip6_datagram_dst_update(sk, false); + bh_unlock_sock(sk); } EXPORT_SYMBOL_GPL(ip6_sk_update_pmtu); -- cgit v1.2.3 From e646b657f6983017783914a951039e323120dc55 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Mon, 11 Apr 2016 15:29:37 -0700 Subject: ipv6: udp: Do a route lookup and update during release_cb This patch adds a release_cb for UDPv6. It does a route lookup and updates sk->sk_dst_cache if it is needed. It picks up the left-over job from ip6_sk_update_pmtu() if the sk was owned by user during the pmtu update. It takes a rcu_read_lock to protect the __sk_dst_get() operations because another thread may do ip6_dst_store() without taking the sk lock (e.g. sendmsg). Fixes: 45e4fd26683c ("ipv6: Only create RTF_CACHE routes after encountering pmtu exception") Signed-off-by: Martin KaFai Lau Reported-by: Wei Wang Cc: Cong Wang Cc: Eric Dumazet Cc: Wei Wang Signed-off-by: David S. Miller --- include/net/ipv6.h | 1 + net/ipv6/datagram.c | 20 ++++++++++++++++++++ net/ipv6/udp.c | 1 + 3 files changed, 22 insertions(+) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index fd02e90b1289..1be050ada8c5 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -960,6 +960,7 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len); int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *addr, int addr_len); int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr); +void ip6_datagram_release_cb(struct sock *sk); int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len); diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 59e01f27db9f..9dd3882fe6bf 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -119,6 +119,26 @@ out: return err; } +void ip6_datagram_release_cb(struct sock *sk) +{ + struct dst_entry *dst; + + if (ipv6_addr_v4mapped(&sk->sk_v6_daddr)) + return; + + rcu_read_lock(); + dst = __sk_dst_get(sk); + if (!dst || !dst->obsolete || + dst->ops->check(dst, inet6_sk(sk)->dst_cookie)) { + rcu_read_unlock(); + return; + } + rcu_read_unlock(); + + ip6_datagram_dst_update(sk, false); +} +EXPORT_SYMBOL_GPL(ip6_datagram_release_cb); + static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) { struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 8125931106be..6bc5c664fa46 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1539,6 +1539,7 @@ struct proto udpv6_prot = { .sendmsg = udpv6_sendmsg, .recvmsg = udpv6_recvmsg, .backlog_rcv = __udpv6_queue_rcv_skb, + .release_cb = ip6_datagram_release_cb, .hash = udp_lib_hash, .unhash = udp_lib_unhash, .rehash = udp_v6_rehash, -- cgit v1.2.3 From b4dfd8e92956b396d3438212bc9a0be6267b8b34 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 12 Apr 2016 13:30:45 +0200 Subject: bgmac: reset & enable Ethernet core before using it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes Ethernet on D-Link DIR-885L with BCM47094 SoC. Felix reported similar fix was needed for his BCM4709 device (Buffalo WXR-1900DHP?). I tested this for regressions on BCM4706, BCM4708A0 and BCM47081A0. Cc: Felix Fietkau Signed-off-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 99b30a952b38..38db2e4d7d54 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1572,6 +1572,11 @@ static int bgmac_probe(struct bcma_device *core) dev_warn(&core->dev, "Using random MAC: %pM\n", mac); } + /* This (reset &) enable is not preset in specs or reference driver but + * Broadcom does it in arch PCI code when enabling fake PCI device. + */ + bcma_core_enable(core, 0); + /* Allocation and references */ net_dev = alloc_etherdev(sizeof(*bgmac)); if (!net_dev) -- cgit v1.2.3 From 9567366fefddeaea4ed1d713270535d93a3b3c76 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Tue, 12 Apr 2016 12:14:46 -0400 Subject: dm cache metadata: fix READ_LOCK macros and cleanup WRITE_LOCK macros The READ_LOCK macro was incorrectly returning -EINVAL if dm_bm_is_read_only() was true -- it will always be true once the cache metadata transitions to read-only by dm_cache_metadata_set_read_only(). Wrap READ_LOCK and WRITE_LOCK multi-statement macros in do {} while(0). Also, all accesses of the 'cmd' argument passed to these related macros are now encapsulated in parenthesis. A follow-up patch can be developed to eliminate the use of macros in favor of pure C code. Avoiding that now given that this needs to apply to stable@. Reported-by: Ben Hutchings Signed-off-by: Mike Snitzer Fixes: d14fcf3dd79 ("dm cache: make sure every metadata function checks fail_io") Cc: stable@vger.kernel.org --- drivers/md/dm-cache-metadata.c | 64 ++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index 27f2ef300f8b..65ce6985f87a 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c @@ -867,39 +867,55 @@ static int blocks_are_unmapped_or_clean(struct dm_cache_metadata *cmd, return 0; } -#define WRITE_LOCK(cmd) \ - down_write(&cmd->root_lock); \ - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ - up_write(&cmd->root_lock); \ - return -EINVAL; \ +static bool cmd_write_lock(struct dm_cache_metadata *cmd) +{ + down_write(&cmd->root_lock); + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { + up_write(&cmd->root_lock); + return false; } + return true; +} -#define WRITE_LOCK_VOID(cmd) \ - down_write(&cmd->root_lock); \ - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ - up_write(&cmd->root_lock); \ - return; \ - } +#define WRITE_LOCK(cmd) \ + do { \ + if (!cmd_write_lock((cmd))) \ + return -EINVAL; \ + } while(0) + +#define WRITE_LOCK_VOID(cmd) \ + do { \ + if (!cmd_write_lock((cmd))) \ + return; \ + } while(0) #define WRITE_UNLOCK(cmd) \ - up_write(&cmd->root_lock) + up_write(&(cmd)->root_lock) -#define READ_LOCK(cmd) \ - down_read(&cmd->root_lock); \ - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ - up_read(&cmd->root_lock); \ - return -EINVAL; \ +static bool cmd_read_lock(struct dm_cache_metadata *cmd) +{ + down_write(&cmd->root_lock); + if (cmd->fail_io) { + up_write(&cmd->root_lock); + return false; } + return true; +} -#define READ_LOCK_VOID(cmd) \ - down_read(&cmd->root_lock); \ - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ - up_read(&cmd->root_lock); \ - return; \ - } +#define READ_LOCK(cmd) \ + do { \ + if (!cmd_read_lock((cmd))) \ + return -EINVAL; \ + } while(0) + +#define READ_LOCK_VOID(cmd) \ + do { \ + if (!cmd_read_lock((cmd))) \ + return; \ + } while(0) #define READ_UNLOCK(cmd) \ - up_read(&cmd->root_lock) + up_read(&(cmd)->root_lock) int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size) { -- cgit v1.2.3 From c5b5343cfbc9f46af65033fa4f407d7b7d98371d Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Tue, 12 Apr 2016 16:11:12 +0200 Subject: cdc_mbim: apply "NDP to end" quirk to all Huawei devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now have a positive report of another Huawei device needing this quirk: The ME906s-158 (12d1:15c1). This is an m.2 form factor modem with no obvious relationship to the E3372 (12d1:157d) we already have a quirk entry for. This is reason enough to believe the quirk might be necessary for any number of current and future Huawei devices. Applying the quirk to all Huawei devices, since it is crucial to any device affected by the firmware bug, while the impact on non-affected devices is negligible. The quirk can if necessary be disabled per-device by writing N to /sys/class/net//cdc_ncm/ndp_to_end Reported-by: Andreas Fett Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/cdc_mbim.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index bdd83d95ec0a..96a5028621c8 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c @@ -617,8 +617,13 @@ static const struct usb_device_id mbim_devs[] = { { USB_VENDOR_AND_INTERFACE_INFO(0x0bdb, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long)&cdc_mbim_info, }, - /* Huawei E3372 fails unless NDP comes after the IP packets */ - { USB_DEVICE_AND_INTERFACE_INFO(0x12d1, 0x157d, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), + + /* Some Huawei devices, ME906s-158 (12d1:15c1) and E3372 + * (12d1:157d), are known to fail unless the NDP is placed + * after the IP packets. Applying the quirk to all Huawei + * devices is broader than necessary, but harmless. + */ + { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end, }, /* default entry */ -- cgit v1.2.3 From d894ba18d4e449b3a7f6eb491f16c9e02933736e Mon Sep 17 00:00:00 2001 From: Craig Gallek Date: Tue, 12 Apr 2016 13:11:25 -0400 Subject: soreuseport: fix ordering for mixed v4/v6 sockets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the SO_REUSEPORT socket option, it is possible to create sockets in the AF_INET and AF_INET6 domains which are bound to the same IPv4 address. This is only possible with SO_REUSEPORT and when not using IPV6_V6ONLY on the AF_INET6 sockets. Prior to the commits referenced below, an incoming IPv4 packet would always be routed to a socket of type AF_INET when this mixed-mode was used. After those changes, the same packet would be routed to the most recently bound socket (if this happened to be an AF_INET6 socket, it would have an IPv4 mapped IPv6 address). The change in behavior occurred because the recent SO_REUSEPORT optimizations short-circuit the socket scoring logic as soon as they find a match. They did not take into account the scoring logic that favors AF_INET sockets over AF_INET6 sockets in the event of a tie. To fix this problem, this patch changes the insertion order of AF_INET and AF_INET6 addresses in the TCP and UDP socket lists when the sockets have SO_REUSEPORT set. AF_INET sockets will be inserted at the head of the list and AF_INET6 sockets with SO_REUSEPORT set will always be inserted at the tail of the list. This will force AF_INET sockets to always be considered first. Fixes: e32ea7e74727 ("soreuseport: fast reuseport UDP socket selection") Fixes: 125e80b88687 ("soreuseport: fast reuseport TCP socket selection") Reported-by: Maciej Żenczykowski Signed-off-by: Craig Gallek Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/rculist_nulls.h | 39 +++++++++++++++++++++++++++++++++++++++ include/net/sock.h | 6 +++++- net/ipv4/udp.c | 9 +++++++-- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h index 1c33dd7da4a7..4ae95f7e8597 100644 --- a/include/linux/rculist_nulls.h +++ b/include/linux/rculist_nulls.h @@ -98,6 +98,45 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n, if (!is_a_nulls(first)) first->pprev = &n->next; } + +/** + * hlist_nulls_add_tail_rcu + * @n: the element to add to the hash list. + * @h: the list to add to. + * + * Description: + * Adds the specified element to the end of the specified hlist_nulls, + * while permitting racing traversals. NOTE: tail insertion requires + * list traversal. + * + * The caller must take whatever precautions are necessary + * (such as holding appropriate locks) to avoid racing + * with another list-mutation primitive, such as hlist_nulls_add_head_rcu() + * or hlist_nulls_del_rcu(), running on this same list. + * However, it is perfectly legal to run concurrently with + * the _rcu list-traversal primitives, such as + * hlist_nulls_for_each_entry_rcu(), used to prevent memory-consistency + * problems on Alpha CPUs. Regardless of the type of CPU, the + * list-traversal primitive must be guarded by rcu_read_lock(). + */ +static inline void hlist_nulls_add_tail_rcu(struct hlist_nulls_node *n, + struct hlist_nulls_head *h) +{ + struct hlist_nulls_node *i, *last = NULL; + + for (i = hlist_nulls_first_rcu(h); !is_a_nulls(i); + i = hlist_nulls_next_rcu(i)) + last = i; + + if (last) { + n->next = last->next; + n->pprev = &last->next; + rcu_assign_pointer(hlist_nulls_next_rcu(last), n); + } else { + hlist_nulls_add_head_rcu(n, h); + } +} + /** * hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type * @tpos: the type * to use as a loop cursor. diff --git a/include/net/sock.h b/include/net/sock.h index 255d3e03727b..121ffc115c4f 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -630,7 +630,11 @@ static inline void sk_add_node_rcu(struct sock *sk, struct hlist_head *list) static inline void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) { - hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list); + if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && + sk->sk_family == AF_INET6) + hlist_nulls_add_tail_rcu(&sk->sk_nulls_node, list); + else + hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list); } static inline void sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 08eed5e16df0..a2e7f55a1f61 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -339,8 +339,13 @@ found: hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash); spin_lock(&hslot2->lock); - hlist_nulls_add_head_rcu(&udp_sk(sk)->udp_portaddr_node, - &hslot2->head); + if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && + sk->sk_family == AF_INET6) + hlist_nulls_add_tail_rcu(&udp_sk(sk)->udp_portaddr_node, + &hslot2->head); + else + hlist_nulls_add_head_rcu(&udp_sk(sk)->udp_portaddr_node, + &hslot2->head); hslot2->count++; spin_unlock(&hslot2->lock); } -- cgit v1.2.3 From d6a61f80b8718abbb82dcfc95d56404e3218e7b0 Mon Sep 17 00:00:00 2001 From: Craig Gallek Date: Tue, 12 Apr 2016 13:11:26 -0400 Subject: soreuseport: test mixed v4/v6 sockets Test to validate the behavior of SO_REUSEPORT sockets that are created with both AF_INET and AF_INET6. See the commit prior to this for a description of this behavior. Signed-off-by: Craig Gallek Signed-off-by: David S. Miller --- tools/testing/selftests/net/.gitignore | 1 + tools/testing/selftests/net/Makefile | 2 +- tools/testing/selftests/net/reuseport_dualstack.c | 208 ++++++++++++++++++++++ 3 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/net/reuseport_dualstack.c diff --git a/tools/testing/selftests/net/.gitignore b/tools/testing/selftests/net/.gitignore index 69bb3fc38fb2..0840684deb7d 100644 --- a/tools/testing/selftests/net/.gitignore +++ b/tools/testing/selftests/net/.gitignore @@ -3,3 +3,4 @@ psock_fanout psock_tpacket reuseport_bpf reuseport_bpf_cpu +reuseport_dualstack diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index c658792d47b4..0e5340742620 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -4,7 +4,7 @@ CFLAGS = -Wall -O2 -g CFLAGS += -I../../../../usr/include/ -NET_PROGS = socket psock_fanout psock_tpacket reuseport_bpf reuseport_bpf_cpu +NET_PROGS = socket psock_fanout psock_tpacket reuseport_bpf reuseport_bpf_cpu reuseport_dualstack all: $(NET_PROGS) %: %.c diff --git a/tools/testing/selftests/net/reuseport_dualstack.c b/tools/testing/selftests/net/reuseport_dualstack.c new file mode 100644 index 000000000000..90958aaaafb9 --- /dev/null +++ b/tools/testing/selftests/net/reuseport_dualstack.c @@ -0,0 +1,208 @@ +/* + * It is possible to use SO_REUSEPORT to open multiple sockets bound to + * equivalent local addresses using AF_INET and AF_INET6 at the same time. If + * the AF_INET6 socket has IPV6_V6ONLY set, it's clear which socket should + * receive a given incoming packet. However, when it is not set, incoming v4 + * packets should prefer the AF_INET socket(s). This behavior was defined with + * the original SO_REUSEPORT implementation, but broke with + * e32ea7e74727 ("soreuseport: fast reuseport UDP socket selection") + * This test creates these mixed AF_INET/AF_INET6 sockets and asserts the + * AF_INET preference for v4 packets. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const int PORT = 8888; + +static void build_rcv_fd(int family, int proto, int *rcv_fds, int count) +{ + struct sockaddr_storage addr; + struct sockaddr_in *addr4; + struct sockaddr_in6 *addr6; + int opt, i; + + switch (family) { + case AF_INET: + addr4 = (struct sockaddr_in *)&addr; + addr4->sin_family = AF_INET; + addr4->sin_addr.s_addr = htonl(INADDR_ANY); + addr4->sin_port = htons(PORT); + break; + case AF_INET6: + addr6 = (struct sockaddr_in6 *)&addr; + addr6->sin6_family = AF_INET6; + addr6->sin6_addr = in6addr_any; + addr6->sin6_port = htons(PORT); + break; + default: + error(1, 0, "Unsupported family %d", family); + } + + for (i = 0; i < count; ++i) { + rcv_fds[i] = socket(family, proto, 0); + if (rcv_fds[i] < 0) + error(1, errno, "failed to create receive socket"); + + opt = 1; + if (setsockopt(rcv_fds[i], SOL_SOCKET, SO_REUSEPORT, &opt, + sizeof(opt))) + error(1, errno, "failed to set SO_REUSEPORT"); + + if (bind(rcv_fds[i], (struct sockaddr *)&addr, sizeof(addr))) + error(1, errno, "failed to bind receive socket"); + + if (proto == SOCK_STREAM && listen(rcv_fds[i], 10)) + error(1, errno, "failed to listen on receive port"); + } +} + +static void send_from_v4(int proto) +{ + struct sockaddr_in saddr, daddr; + int fd; + + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = htonl(INADDR_ANY); + saddr.sin_port = 0; + + daddr.sin_family = AF_INET; + daddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + daddr.sin_port = htons(PORT); + + fd = socket(AF_INET, proto, 0); + if (fd < 0) + error(1, errno, "failed to create send socket"); + + if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr))) + error(1, errno, "failed to bind send socket"); + + if (connect(fd, (struct sockaddr *)&daddr, sizeof(daddr))) + error(1, errno, "failed to connect send socket"); + + if (send(fd, "a", 1, 0) < 0) + error(1, errno, "failed to send message"); + + close(fd); +} + +static int receive_once(int epfd, int proto) +{ + struct epoll_event ev; + int i, fd; + char buf[8]; + + i = epoll_wait(epfd, &ev, 1, -1); + if (i < 0) + error(1, errno, "epoll_wait failed"); + + if (proto == SOCK_STREAM) { + fd = accept(ev.data.fd, NULL, NULL); + if (fd < 0) + error(1, errno, "failed to accept"); + i = recv(fd, buf, sizeof(buf), 0); + close(fd); + } else { + i = recv(ev.data.fd, buf, sizeof(buf), 0); + } + + if (i < 0) + error(1, errno, "failed to recv"); + + return ev.data.fd; +} + +static void test(int *rcv_fds, int count, int proto) +{ + struct epoll_event ev; + int epfd, i, test_fd; + uint16_t test_family; + socklen_t len; + + epfd = epoll_create(1); + if (epfd < 0) + error(1, errno, "failed to create epoll"); + + ev.events = EPOLLIN; + for (i = 0; i < count; ++i) { + ev.data.fd = rcv_fds[i]; + if (epoll_ctl(epfd, EPOLL_CTL_ADD, rcv_fds[i], &ev)) + error(1, errno, "failed to register sock epoll"); + } + + send_from_v4(proto); + + test_fd = receive_once(epfd, proto); + if (getsockopt(test_fd, SOL_SOCKET, SO_DOMAIN, &test_family, &len)) + error(1, errno, "failed to read socket domain"); + if (test_family != AF_INET) + error(1, 0, "expected to receive on v4 socket but got v6 (%d)", + test_family); + + close(epfd); +} + +int main(void) +{ + int rcv_fds[32], i; + + fprintf(stderr, "---- UDP IPv4 created before IPv6 ----\n"); + build_rcv_fd(AF_INET, SOCK_DGRAM, rcv_fds, 5); + build_rcv_fd(AF_INET6, SOCK_DGRAM, &(rcv_fds[5]), 5); + test(rcv_fds, 10, SOCK_DGRAM); + for (i = 0; i < 10; ++i) + close(rcv_fds[i]); + + fprintf(stderr, "---- UDP IPv6 created before IPv4 ----\n"); + build_rcv_fd(AF_INET6, SOCK_DGRAM, rcv_fds, 5); + build_rcv_fd(AF_INET, SOCK_DGRAM, &(rcv_fds[5]), 5); + test(rcv_fds, 10, SOCK_DGRAM); + for (i = 0; i < 10; ++i) + close(rcv_fds[i]); + + /* NOTE: UDP socket lookups traverse a different code path when there + * are > 10 sockets in a group. + */ + fprintf(stderr, "---- UDP IPv4 created before IPv6 (large) ----\n"); + build_rcv_fd(AF_INET, SOCK_DGRAM, rcv_fds, 16); + build_rcv_fd(AF_INET6, SOCK_DGRAM, &(rcv_fds[16]), 16); + test(rcv_fds, 32, SOCK_DGRAM); + for (i = 0; i < 32; ++i) + close(rcv_fds[i]); + + fprintf(stderr, "---- UDP IPv6 created before IPv4 (large) ----\n"); + build_rcv_fd(AF_INET6, SOCK_DGRAM, rcv_fds, 16); + build_rcv_fd(AF_INET, SOCK_DGRAM, &(rcv_fds[16]), 16); + test(rcv_fds, 32, SOCK_DGRAM); + for (i = 0; i < 32; ++i) + close(rcv_fds[i]); + + fprintf(stderr, "---- TCP IPv4 created before IPv6 ----\n"); + build_rcv_fd(AF_INET, SOCK_STREAM, rcv_fds, 5); + build_rcv_fd(AF_INET6, SOCK_STREAM, &(rcv_fds[5]), 5); + test(rcv_fds, 10, SOCK_STREAM); + for (i = 0; i < 10; ++i) + close(rcv_fds[i]); + + fprintf(stderr, "---- TCP IPv6 created before IPv4 ----\n"); + build_rcv_fd(AF_INET6, SOCK_STREAM, rcv_fds, 5); + build_rcv_fd(AF_INET, SOCK_STREAM, &(rcv_fds[5]), 5); + test(rcv_fds, 10, SOCK_STREAM); + for (i = 0; i < 10; ++i) + close(rcv_fds[i]); + + fprintf(stderr, "SUCCESS\n"); + return 0; +} -- cgit v1.2.3 From c02bc350f9dbce7d637c394a6e1c4d29dc5b28b2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Apr 2016 18:27:29 +0200 Subject: bgmac: fix MAC soft-reset bit for corerev > 4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only core revisions older than 4 use BGMAC_CMDCFG_SR_REV0. This mainly fixes support for BCM4708A0KF SoCs with Ethernet core rev 5 (it means only some devices as most of BCM4708A0KF-s got core rev 4). This was tested for regressions on BCM47094 which doesn't seem to care which bit gets used. Signed-off-by: Felix Fietkau Signed-off-by: Rafał Miłecki Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 4fbb093e0d84..9a03c142b742 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -199,9 +199,9 @@ #define BGMAC_CMDCFG_TAI 0x00000200 #define BGMAC_CMDCFG_HD 0x00000400 /* Set if in half duplex mode */ #define BGMAC_CMDCFG_HD_SHIFT 10 -#define BGMAC_CMDCFG_SR_REV0 0x00000800 /* Set to reset mode, for other revs */ -#define BGMAC_CMDCFG_SR_REV4 0x00002000 /* Set to reset mode, only for core rev 4 */ -#define BGMAC_CMDCFG_SR(rev) ((rev == 4) ? BGMAC_CMDCFG_SR_REV4 : BGMAC_CMDCFG_SR_REV0) +#define BGMAC_CMDCFG_SR_REV0 0x00000800 /* Set to reset mode, for core rev 0-3 */ +#define BGMAC_CMDCFG_SR_REV4 0x00002000 /* Set to reset mode, for core rev >= 4 */ +#define BGMAC_CMDCFG_SR(rev) ((rev >= 4) ? BGMAC_CMDCFG_SR_REV4 : BGMAC_CMDCFG_SR_REV0) #define BGMAC_CMDCFG_ML 0x00008000 /* Set to activate mac loopback mode */ #define BGMAC_CMDCFG_AE 0x00400000 #define BGMAC_CMDCFG_CFE 0x00800000 -- cgit v1.2.3 From 330a106508128056b3d7b6c940a4e906da2282dc Mon Sep 17 00:00:00 2001 From: Martin Vajnar Date: Sat, 2 Apr 2016 20:11:13 +0200 Subject: hp_accel: Add support for HP ProBook 440 G3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HP ProBook 440 G3 laptop needs a non-standard mapping (x_inverted_usd). Signed-off-by: Martin Vajnar Acked-by: Éric Piel Signed-off-by: Darren Hart --- drivers/platform/x86/hp_accel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 10ce6cba4455..263002ba43eb 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -173,6 +173,7 @@ static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi) DEFINE_CONV(normal, 1, 2, 3); DEFINE_CONV(y_inverted, 1, -2, 3); DEFINE_CONV(x_inverted, -1, 2, 3); +DEFINE_CONV(x_inverted_usd, -1, 2, -3); DEFINE_CONV(z_inverted, 1, 2, -3); DEFINE_CONV(xy_swap, 2, 1, 3); DEFINE_CONV(xy_rotated_left, -2, 1, 3); @@ -236,6 +237,7 @@ static const struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted), AXIS_DMI_MATCH("HDX18", "HP HDX 18", x_inverted), AXIS_DMI_MATCH("HPB432x", "HP ProBook 432", xy_rotated_left), + AXIS_DMI_MATCH("HPB440G3", "HP ProBook 440 G3", x_inverted_usd), AXIS_DMI_MATCH("HPB442x", "HP ProBook 442", xy_rotated_left), AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted), AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap), -- cgit v1.2.3 From 5fedbb923936174ab4d1d5cc92bca1cf6b2e0ca2 Mon Sep 17 00:00:00 2001 From: Yingjoe Chen Date: Sat, 2 Apr 2016 14:57:49 +0800 Subject: pinctrl: mediatek: correct debounce time unit in mtk_gpio_set_debounce The debounce time unit for gpio_chip.set_debounce is us but mtk_gpio_set_debounce regard it as ms. Fix this by correct debounce time array dbnc_arr so it can find correct debounce setting. Debounce time for first debounce setting is 500us, correct this as well. While I'm at it, also change the debounce time array name to "debounce_time" for readability. Cc: stable@vger.kernel.org Signed-off-by: Yingjoe Chen Reviewed-by: Daniel Kurtz Acked-by: Hongzhou Yang Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index 2bbe6f7964a7..6ab8c3ccdeea 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -1004,7 +1004,8 @@ static int mtk_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, struct mtk_pinctrl *pctl = dev_get_drvdata(chip->parent); int eint_num, virq, eint_offset; unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask, dbnc; - static const unsigned int dbnc_arr[] = {0 , 1, 16, 32, 64, 128, 256}; + static const unsigned int debounce_time[] = {500, 1000, 16000, 32000, 64000, + 128000, 256000}; const struct mtk_desc_pin *pin; struct irq_data *d; @@ -1022,9 +1023,9 @@ static int mtk_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, if (!mtk_eint_can_en_debounce(pctl, eint_num)) return -ENOSYS; - dbnc = ARRAY_SIZE(dbnc_arr); - for (i = 0; i < ARRAY_SIZE(dbnc_arr); i++) { - if (debounce <= dbnc_arr[i]) { + dbnc = ARRAY_SIZE(debounce_time); + for (i = 0; i < ARRAY_SIZE(debounce_time); i++) { + if (debounce <= debounce_time[i]) { dbnc = i; break; } -- cgit v1.2.3 From 9c18fcf7ae0ef87f0723dfd74c27d608c7486e0e Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Wed, 13 Apr 2016 05:55:29 +0100 Subject: ARM: 8551/2: DMA: Fix kzalloc flags in __dma_alloc Commit 19e6e5e5392b ("ARM: 8547/1: dma-mapping: store buffer information") allocates a structure meant for internal buffer management with the GFP flags of the buffer itself. This can trigger the following safeguard in the slab/slub allocator: if (unlikely(flags & GFP_SLAB_BUG_MASK)) { pr_emerg("gfp: %un", flags & GFP_SLAB_BUG_MASK); BUG(); } Fix this by filtering the flags that make the slab allocator unhappy. Signed-off-by: Alexandre Courbot Acked-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/mm/dma-mapping.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index deac58d5f1f7..c941e93048ad 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -762,7 +762,8 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, if (!mask) return NULL; - buf = kzalloc(sizeof(*buf), gfp); + buf = kzalloc(sizeof(*buf), + gfp & ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM)); if (!buf) return NULL; -- cgit v1.2.3 From 56b367c0cd67d4c3006738e7dc9dda9273fd2bfe Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 14 Apr 2016 10:29:16 +0530 Subject: pinctrl: single: Fix pcs_parse_bits_in_pinctrl_entry to use __ffs than ffs pcs_parse_bits_in_pinctrl_entry uses ffs which gives bit indices ranging from 1 to MAX. This leads to a corner case where we try to request the pin number = MAX and fails. bit_pos value is being calculted using ffs. pin_num_from_lsb uses bit_pos value. pins array is populated with: pin + pin_num_from_lsb. The above is 1 more than usual bit indices as bit_pos uses ffs to compute first set bit. Hence the last of the pins array is populated with the MAX value and not MAX - 1 which causes error when we call pin_request. mask_pos is rightly calculated as ((pcs->fmask) << (bit_pos - 1)) Consequently val_pos and submask are correct. Hence use __ffs which gives (ffs(x) - 1) as the first bit set. fixes: 4e7e8017a8 ("pinctrl: pinctrl-single: enhance to configure multiple pins of different modules") Signed-off-by: Keerthy Acked-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index fb126d56ad40..cf9bafa10acf 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -1280,9 +1280,9 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs, /* Parse pins in each row from LSB */ while (mask) { - bit_pos = ffs(mask); + bit_pos = __ffs(mask); pin_num_from_lsb = bit_pos / pcs->bits_per_pin; - mask_pos = ((pcs->fmask) << (bit_pos - 1)); + mask_pos = ((pcs->fmask) << bit_pos); val_pos = val & mask_pos; submask = mask & mask_pos; @@ -1852,7 +1852,7 @@ static int pcs_probe(struct platform_device *pdev) ret = of_property_read_u32(np, "pinctrl-single,function-mask", &pcs->fmask); if (!ret) { - pcs->fshift = ffs(pcs->fmask) - 1; + pcs->fshift = __ffs(pcs->fmask); pcs->fmax = pcs->fmask >> pcs->fshift; } else { /* If mask property doesn't exist, function mux is invalid. */ -- cgit v1.2.3 From 7e578441a4a3bba2a79426ca0f709c801210d08e Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 14 Apr 2016 14:52:24 -0500 Subject: objtool: Add workaround for GCC switch jump table bug GCC has a rare quirk, currently only seen in three driver functions in the kernel, and only with certain obscure non-distro configs, which can cause objtool to produce "unreachable instruction" false positive warnings. As part of an optimization, GCC makes a copy of an existing switch jump table, modifies it, and then hard-codes the jump (albeit with an indirect jump) to use a single entry in the table. The rest of the jump table and some of its jump targets remain as dead code. In such a case we can just crudely ignore all unreachable instruction warnings for the entire object file. Ideally we would just ignore them for the function, but that would require redesigning the code quite a bit. And honestly that's just not worth doing: unreachable instruction warnings are of questionable value anyway, and this is a very rare issue. kbuild reports: https://lkml.kernel.org/r/201603231906.LWcVUpxm%25fengguang.wu@intel.com https://lkml.kernel.org/r/201603271114.K9i45biy%25fengguang.wu@intel.com https://lkml.kernel.org/r/201603291058.zuJ6ben1%25fengguang.wu@intel.com GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70604 Reported-by: kbuild test robot Signed-off-by: Josh Poimboeuf Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/700fa029bbb0feff34f03ffc69d666a3c3b57a61.1460663532.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar --- tools/objtool/builtin-check.c | 53 +++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 7515cb2e879a..157a0f96d64d 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -66,6 +66,7 @@ struct objtool_file { struct list_head insn_list; DECLARE_HASHTABLE(insn_hash, 16); struct section *rodata, *whitelist; + bool ignore_unreachables; }; const char *objname; @@ -664,13 +665,40 @@ static int add_func_switch_tables(struct objtool_file *file, text_rela->addend); /* - * TODO: Document where this is needed, or get rid of it. - * * rare case: jmpq *[addr](%rip) + * + * This check is for a rare gcc quirk, currently only seen in + * three driver functions in the kernel, only with certain + * obscure non-distro configs. + * + * As part of an optimization, gcc makes a copy of an existing + * switch jump table, modifies it, and then hard-codes the jump + * (albeit with an indirect jump) to use a single entry in the + * table. The rest of the jump table and some of its jump + * targets remain as dead code. + * + * In such a case we can just crudely ignore all unreachable + * instruction warnings for the entire object file. Ideally we + * would just ignore them for the function, but that would + * require redesigning the code quite a bit. And honestly + * that's just not worth doing: unreachable instruction + * warnings are of questionable value anyway, and this is such + * a rare issue. + * + * kbuild reports: + * - https://lkml.kernel.org/r/201603231906.LWcVUpxm%25fengguang.wu@intel.com + * - https://lkml.kernel.org/r/201603271114.K9i45biy%25fengguang.wu@intel.com + * - https://lkml.kernel.org/r/201603291058.zuJ6ben1%25fengguang.wu@intel.com + * + * gcc bug: + * - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70604 */ - if (!rodata_rela) + if (!rodata_rela) { rodata_rela = find_rela_by_dest(file->rodata, text_rela->addend + 4); + if (rodata_rela) + file->ignore_unreachables = true; + } if (!rodata_rela) continue; @@ -732,9 +760,6 @@ static int decode_sections(struct objtool_file *file) { int ret; - file->whitelist = find_section_by_name(file->elf, "__func_stack_frame_non_standard"); - file->rodata = find_section_by_name(file->elf, ".rodata"); - ret = decode_instructions(file); if (ret) return ret; @@ -1056,13 +1081,14 @@ static int validate_functions(struct objtool_file *file) if (insn->visited) continue; - if (!ignore_unreachable_insn(func, insn) && - !warnings) { - WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset); - warnings++; - } - insn->visited = true; + + if (file->ignore_unreachables || warnings || + ignore_unreachable_insn(func, insn)) + continue; + + WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset); + warnings++; } } } @@ -1133,6 +1159,9 @@ int cmd_check(int argc, const char **argv) INIT_LIST_HEAD(&file.insn_list); hash_init(file.insn_hash); + file.whitelist = find_section_by_name(file.elf, "__func_stack_frame_non_standard"); + file.rodata = find_section_by_name(file.elf, ".rodata"); + file.ignore_unreachables = false; ret = decode_sections(&file); if (ret < 0) -- cgit v1.2.3 From 6f0904ada402a45b3a0a3b9b6507d91d3a9da67a Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Wed, 6 Apr 2016 14:42:32 -0700 Subject: crypto: rsa-pkcs1pad - fix dst len The output buffer length has to be at least as big as the key_size. It is then updated to the actual output size by the implementation. Cc: Signed-off-by: Tadeusz Struk Signed-off-by: Herbert Xu --- crypto/rsa-pkcs1pad.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index 1cea67d43e1d..ead8dc0d084e 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c @@ -387,16 +387,16 @@ static int pkcs1pad_decrypt(struct akcipher_request *req) req_ctx->child_req.src = req->src; req_ctx->child_req.src_len = req->src_len; req_ctx->child_req.dst = req_ctx->out_sg; - req_ctx->child_req.dst_len = ctx->key_size - 1; + req_ctx->child_req.dst_len = ctx->key_size ; - req_ctx->out_buf = kmalloc(ctx->key_size - 1, + req_ctx->out_buf = kmalloc(ctx->key_size, (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL : GFP_ATOMIC); if (!req_ctx->out_buf) return -ENOMEM; pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf, - ctx->key_size - 1, NULL); + ctx->key_size, NULL); akcipher_request_set_tfm(&req_ctx->child_req, ctx->child); akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, @@ -595,16 +595,16 @@ static int pkcs1pad_verify(struct akcipher_request *req) req_ctx->child_req.src = req->src; req_ctx->child_req.src_len = req->src_len; req_ctx->child_req.dst = req_ctx->out_sg; - req_ctx->child_req.dst_len = ctx->key_size - 1; + req_ctx->child_req.dst_len = ctx->key_size; - req_ctx->out_buf = kmalloc(ctx->key_size - 1, + req_ctx->out_buf = kmalloc(ctx->key_size, (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL : GFP_ATOMIC); if (!req_ctx->out_buf) return -ENOMEM; pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf, - ctx->key_size - 1, NULL); + ctx->key_size, NULL); akcipher_request_set_tfm(&req_ctx->child_req, ctx->child); akcipher_request_set_callback(&req_ctx->child_req, req->base.flags, -- cgit v1.2.3 From 0851561d9c965df086ef8a53f981f5f95a57c2c8 Mon Sep 17 00:00:00 2001 From: Xiaodong Liu Date: Tue, 12 Apr 2016 09:45:51 +0000 Subject: crypto: sha1-mb - use corrcet pointer while completing jobs In sha_complete_job, incorrect mcryptd_hash_request_ctx pointer is used when check and complete other jobs. If the memory of first completed req is freed, while still completing other jobs in the func, kernel will crash since NULL pointer is assigned to RIP. Cc: Signed-off-by: Xiaodong Liu Acked-by: Tim Chen Signed-off-by: Herbert Xu --- arch/x86/crypto/sha-mb/sha1_mb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/crypto/sha-mb/sha1_mb.c b/arch/x86/crypto/sha-mb/sha1_mb.c index a8a0224fa0f8..081255cea1ee 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb.c +++ b/arch/x86/crypto/sha-mb/sha1_mb.c @@ -453,10 +453,10 @@ static int sha_complete_job(struct mcryptd_hash_request_ctx *rctx, req = cast_mcryptd_ctx_to_req(req_ctx); if (irqs_disabled()) - rctx->complete(&req->base, ret); + req_ctx->complete(&req->base, ret); else { local_bh_disable(); - rctx->complete(&req->base, ret); + req_ctx->complete(&req->base, ret); local_bh_enable(); } } -- cgit v1.2.3 From f709b45ec461b548c41a00044dba1f1b572783bf Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Wed, 13 Apr 2016 10:52:25 -0500 Subject: crypto: ccp - Prevent information leakage on export Prevent information from leaking to userspace by doing a memset to 0 of the export state structure before setting the structure values and copying it. This prevents un-initialized padding areas from being copied into the export area. Cc: # 3.14.x- Reported-by: Ben Hutchings Signed-off-by: Tom Lendacky Signed-off-by: Herbert Xu --- drivers/crypto/ccp/ccp-crypto-aes-cmac.c | 3 +++ drivers/crypto/ccp/ccp-crypto-sha.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c index 3d9acc53d247..60fc0fa26fd3 100644 --- a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c +++ b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c @@ -225,6 +225,9 @@ static int ccp_aes_cmac_export(struct ahash_request *req, void *out) struct ccp_aes_cmac_req_ctx *rctx = ahash_request_ctx(req); struct ccp_aes_cmac_exp_ctx state; + /* Don't let anything leak to 'out' */ + memset(&state, 0, sizeof(state)); + state.null_msg = rctx->null_msg; memcpy(state.iv, rctx->iv, sizeof(state.iv)); state.buf_count = rctx->buf_count; diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c b/drivers/crypto/ccp/ccp-crypto-sha.c index b5ad72897dc2..8f36af62fe95 100644 --- a/drivers/crypto/ccp/ccp-crypto-sha.c +++ b/drivers/crypto/ccp/ccp-crypto-sha.c @@ -212,6 +212,9 @@ static int ccp_sha_export(struct ahash_request *req, void *out) struct ccp_sha_req_ctx *rctx = ahash_request_ctx(req); struct ccp_sha_exp_ctx state; + /* Don't let anything leak to 'out' */ + memset(&state, 0, sizeof(state)); + state.type = rctx->type; state.msg_bits = rctx->msg_bits; state.first = rctx->first; -- cgit v1.2.3 From a7297a6a3a3322b054592e8e988981d2f5f29cc4 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 15 Apr 2016 18:51:28 +0800 Subject: block: loop: fix filesystem corruption in case of aio/dio Starting from commit e36f620428(block: split bios to max possible length), block core starts to split bio in the middle of bvec. Unfortunately loop dio/aio doesn't consider this situation, and always treat 'iter.iov_offset' as zero. Then filesystem corruption is observed. This patch figures out the offset of the base bvevc via 'bio->bi_iter.bi_bvec_done' and fixes the issue by passing the offset to iov iterator. Fixes: e36f6204288088f (block: split bios to max possible length) Cc: Keith Busch Cc: Al Viro Cc: stable@vger.kernel.org (4.5) Signed-off-by: Ming Lei Signed-off-by: Jens Axboe --- drivers/block/loop.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 423f4ca7d712..80cf8add46ff 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -488,6 +488,12 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, bvec = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter); iov_iter_bvec(&iter, ITER_BVEC | rw, bvec, bio_segments(bio), blk_rq_bytes(cmd->rq)); + /* + * This bio may be started from the middle of the 'bvec' + * because of bio splitting, so offset from the bvec must + * be passed to iov iterator + */ + iter.iov_offset = bio->bi_iter.bi_bvec_done; cmd->iocb.ki_pos = pos; cmd->iocb.ki_filp = file; -- cgit v1.2.3 From ff22b4806dd79ba06c78255b67e73c10e34d47cc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 15 Apr 2016 17:47:20 +0300 Subject: hp_accel: Silence an uninitialized variable warning If acpi_evaluate_integer() fails then "lret" isn't initialized. I've tweaked the error handling to avoid this issue. Signed-off-by: Dan Carpenter Signed-off-by: Darren Hart --- drivers/platform/x86/hp_accel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 263002ba43eb..09356684c32f 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -127,8 +127,10 @@ static int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret) arg0.integer.value = reg; status = acpi_evaluate_integer(dev->handle, "ALRD", &args, &lret); + if (ACPI_FAILURE(status)) + return -EINVAL; *ret = lret; - return (status != AE_OK) ? -EINVAL : 0; + return 0; } /** -- cgit v1.2.3 From d0192dca2d6b64c043db5babb40076d13a6e955b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 15 Apr 2016 17:45:58 +0300 Subject: intel_telemetry_pltdrv: Silence an uninitialized variable warning Presumably "pss_period" and "ioss_period" can't both be zero, but this function is never called so we can't infer that using static analysis alone. Silence the warning by setting "ret" to zero. Signed-off-by: Dan Carpenter Signed-off-by: Darren Hart --- drivers/platform/x86/intel_telemetry_pltdrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_telemetry_pltdrv.c b/drivers/platform/x86/intel_telemetry_pltdrv.c index 397119f83e82..781bd10ca7ac 100644 --- a/drivers/platform/x86/intel_telemetry_pltdrv.c +++ b/drivers/platform/x86/intel_telemetry_pltdrv.c @@ -659,7 +659,7 @@ static int telemetry_plt_update_events(struct telemetry_evtconfig pss_evtconfig, static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period) { u32 telem_ctrl = 0; - int ret; + int ret = 0; mutex_lock(&(telm_conf->telem_lock)); if (ioss_period) { -- cgit v1.2.3 From a7718360d91eedbedd58978ec8fff4a67a866f86 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 15 Apr 2016 17:46:34 +0300 Subject: thinkpad_acpi: Silence an uninitialized variable warning If fan_get_status() fails then "s" is not initialized. Tweak the error handling a bit to silence this warning. Signed-off-by: Dan Carpenter Signed-off-by: Darren Hart --- drivers/platform/x86/thinkpad_acpi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e305ab541a22..9255ff3ee81a 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -7972,10 +7972,12 @@ static int fan_get_status_safe(u8 *status) fan_update_desired_level(s); mutex_unlock(&fan_mutex); + if (rc) + return rc; if (status) *status = s; - return rc; + return 0; } static int fan_get_speed(unsigned int *speed) -- cgit v1.2.3 From 1378a683443753923eb22d01ce322e92a383ba8a Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Fri, 8 Apr 2016 13:23:52 +0200 Subject: s390/dcssblk: fix possible deadlock in remove vs. per-device attributes dcssblk_remove_store() holds the dcssblk_devices_sem semaphore while calling device_unregister(), which in turn tries to acquire the kernfs kn->dev_map rwsem for the device sysfs subtree. The same rwsem is also acquired when using the per-device sysfs attributes in the device sub-tree, and the attribute handlers then also acquire the dcssblk_devices_sem. This can lead to a deadlock when removing a DCSS while concurrently reading from / writing to one of its sysfs attributes. The following lockdep warning hinted towards the issue (CPU0 = dcssblk_remove_store, CPU1 = dcssblk_shared_store): [ 76.496047] Possible unsafe locking scenario: [ 76.496054] CPU0 CPU1 [ 76.496059] ---- ---- [ 76.496087] lock(&dcssblk_devices_sem); [ 76.496090] lock(s_active#175); [ 76.496106] lock(&dcssblk_devices_sem); [ 76.496110] lock(s_active#175); [ 76.496115] *** DEADLOCK *** Fix this by releasing the dcssblk_devices_sem semaphore, which only protects internal DCSS data, before calling device_unregister(). Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dcssblk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 1bce9cf51b1e..b83908670a9a 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -756,15 +756,16 @@ dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const ch blk_cleanup_queue(dev_info->dcssblk_queue); dev_info->gd->queue = NULL; put_disk(dev_info->gd); - device_unregister(&dev_info->dev); /* unload all related segments */ list_for_each_entry(entry, &dev_info->seg_list, lh) segment_unload(entry->segment_name); - put_device(&dev_info->dev); up_write(&dcssblk_devices_sem); + device_unregister(&dev_info->dev); + put_device(&dev_info->dev); + rc = count; out_buf: kfree(local_buf); -- cgit v1.2.3 From 8497695243f70fd19ed6cf28b63584f1b608b5f9 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 13 Apr 2016 11:05:20 +0200 Subject: s390/spinlock: avoid yield to non existent cpu arch_spin_lock_wait_flags() checks if a spinlock is not held before trying a compare and swap instruction. If the lock is unlocked it tries the compare and swap instruction, however if a different cpu grabbed the lock in the meantime the instruction will fail as expected. Subsequently the arch_spin_lock_wait_flags() incorrectly tries to figure out if the cpu that holds the lock is running. However it is using the wrong cpu number for this (-1) and then will also yield the current cpu to the wrong cpu. Fix this by adding a missing continue statement. Fixes: 470ada6b1a1d ("s390/spinlock: refactor arch_spin_lock_wait[_flags]") Signed-off-by: Heiko Carstens Acked-by: Martin Schwidefsky --- arch/s390/lib/spinlock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index d4549c964589..e5f50a7d2f4e 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -105,6 +105,7 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) if (_raw_compare_and_swap(&lp->lock, 0, cpu)) return; local_irq_restore(flags); + continue; } /* Check if the lock owner is running. */ if (first_diag && cpu_is_preempted(~owner)) { -- cgit v1.2.3 From 2fd92273646abad21766ddfbfa00b6f927362308 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 14 Apr 2016 09:00:27 +0200 Subject: s390: add CPU_BIG_ENDIAN config option Make sure that s390 appears to be a big endian machine by defining this config option. Without this s390 appears to be little endian as seen by e.g. the recordmount script: "perl ./scripts/recordmcount.pl "s390" "little" "64"" This has no practical impact within the script since the endian variable is only evaluated for mips. However there are already a couple of common code places which evaluate this config option. None of them is relevant for s390 currently though. To avoid any issues in the future (and fix the recordmcount oddity) add the new config option. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index aad23e3dff2c..bf24ab188921 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -4,6 +4,9 @@ config MMU config ZONE_DMA def_bool y +config CPU_BIG_ENDIAN + def_bool y + config LOCKDEP_SUPPORT def_bool y -- cgit v1.2.3 From 54dca7015a7d6c09d34623c6ec61de30896186dd Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 15 Apr 2016 13:11:56 +0100 Subject: ASoC: arizona: Free speaker thermal IRQs in CODEC remove The thermal warning IRQs for the speaker are requested in CODEC probe but never freed. This patch frees them in CODEC remove. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 12 ++++++++++++ sound/soc/codecs/arizona.h | 2 ++ sound/soc/codecs/cs47l24.c | 3 +++ sound/soc/codecs/wm5102.c | 2 ++ sound/soc/codecs/wm5110.c | 2 ++ sound/soc/codecs/wm8997.c | 2 ++ sound/soc/codecs/wm8998.c | 2 ++ 7 files changed, 25 insertions(+) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 92d22a018d68..83959312f7a0 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -249,6 +249,18 @@ int arizona_init_spk(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(arizona_init_spk); +int arizona_free_spk(struct snd_soc_codec *codec) +{ + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; + + arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN, arizona); + arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT, arizona); + + return 0; +} +EXPORT_SYMBOL_GPL(arizona_free_spk); + static const struct snd_soc_dapm_route arizona_mono_routes[] = { { "OUT1R", NULL, "OUT1L" }, { "OUT2R", NULL, "OUT2L" }, diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 1ea8e4ecf8d4..ce0531b8c632 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -307,6 +307,8 @@ extern int arizona_init_spk(struct snd_soc_codec *codec); extern int arizona_init_gpio(struct snd_soc_codec *codec); extern int arizona_init_mono(struct snd_soc_codec *codec); +extern int arizona_free_spk(struct snd_soc_codec *codec); + extern int arizona_init_dai(struct arizona_priv *priv, int dai); int arizona_set_output_mode(struct snd_soc_codec *codec, int output, diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index 576087bda330..00e9b6fc1b5c 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -1108,6 +1108,9 @@ static int cs47l24_codec_remove(struct snd_soc_codec *codec) priv->core.arizona->dapm = NULL; arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv); + + arizona_free_spk(codec); + return 0; } diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index a8b3e3f701f9..59fd3e8bf899 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1960,6 +1960,8 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec) priv->core.arizona->dapm = NULL; + arizona_free_spk(codec); + return 0; } diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 83ba70fe16e6..2728ac545ffe 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2298,6 +2298,8 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec) arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv); + arizona_free_spk(codec); + return 0; } diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 52d766efe14f..6b0785b5a5c5 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -1072,6 +1072,8 @@ static int wm8997_codec_remove(struct snd_soc_codec *codec) priv->core.arizona->dapm = NULL; + arizona_free_spk(codec); + return 0; } diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c index 012396074a8a..449f66636205 100644 --- a/sound/soc/codecs/wm8998.c +++ b/sound/soc/codecs/wm8998.c @@ -1324,6 +1324,8 @@ static int wm8998_codec_remove(struct snd_soc_codec *codec) priv->core.arizona->dapm = NULL; + arizona_free_spk(codec); + return 0; } -- cgit v1.2.3 From ab9f87c413c297cb9e7d544e0e634aaadc7fb87d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 15 Apr 2016 13:11:57 +0100 Subject: ASoC: wm5102: Free compressed IRQ in CODEC remove We request one of the DSP IRQs during CODEC probe, as such we should free it during CODEC remove, this patch does so. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 59fd3e8bf899..1bae17ee8817 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1955,11 +1955,14 @@ err_adsp2_codec_probe: static int wm5102_codec_remove(struct snd_soc_codec *codec) { struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->core.arizona; wm_adsp2_codec_remove(&priv->core.adsp[0], codec); priv->core.arizona->dapm = NULL; + arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv); + arizona_free_spk(codec); return 0; -- cgit v1.2.3 From cb92148b58a49455f3a7204eba3aee09a8b7683c Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Fri, 15 Apr 2016 13:00:11 -0500 Subject: PCI: Add pci_set_vpd_size() to set VPD size After 104daa71b396 ("PCI: Determine actual VPD size on first access"), the PCI core computes the valid VPD size by parsing the VPD starting at offset 0x0. We don't attempt to read past that valid size because that causes some devices to crash. However, some devices do have data past that valid size. For example, Chelsio adapters contain two VPD structures, and the driver needs both of them. Add pci_set_vpd_size(). If a driver knows it is safe to read past the end of the VPD data structure at offset 0, it can use pci_set_vpd_size() to allow access to as much data as it needs. [bhelgaas: changelog, split patches, rename to pci_set_vpd_size() and return int (not ssize_t)] Fixes: 104daa71b396 ("PCI: Determine actual VPD size on first access") Tested-by: Steve Wise Signed-off-by: Casey Leedom Signed-off-by: Hariprasad Shenai Signed-off-by: Bjorn Helgaas --- drivers/pci/access.c | 42 ++++++++++++++++++++++++++++++++++++++++++ drivers/pci/pci.h | 1 + include/linux/pci.h | 1 + 3 files changed, 44 insertions(+) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 01b9d0a00abc..d11cdbb8fba3 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -275,6 +275,19 @@ ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void } EXPORT_SYMBOL(pci_write_vpd); +/** + * pci_set_vpd_size - Set size of Vital Product Data space + * @dev: pci device struct + * @len: size of vpd space + */ +int pci_set_vpd_size(struct pci_dev *dev, size_t len) +{ + if (!dev->vpd || !dev->vpd->ops) + return -ENODEV; + return dev->vpd->ops->set_size(dev, len); +} +EXPORT_SYMBOL(pci_set_vpd_size); + #define PCI_VPD_MAX_SIZE (PCI_VPD_ADDR_MASK + 1) /** @@ -498,9 +511,23 @@ out: return ret ? ret : count; } +static int pci_vpd_set_size(struct pci_dev *dev, size_t len) +{ + struct pci_vpd *vpd = dev->vpd; + + if (len == 0 || len > PCI_VPD_MAX_SIZE) + return -EIO; + + vpd->valid = 1; + vpd->len = len; + + return 0; +} + static const struct pci_vpd_ops pci_vpd_ops = { .read = pci_vpd_read, .write = pci_vpd_write, + .set_size = pci_vpd_set_size, }; static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, @@ -533,9 +560,24 @@ static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, return ret; } +static int pci_vpd_f0_set_size(struct pci_dev *dev, size_t len) +{ + struct pci_dev *tdev = pci_get_slot(dev->bus, + PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); + int ret; + + if (!tdev) + return -ENODEV; + + ret = pci_set_vpd_size(tdev, len); + pci_dev_put(tdev); + return ret; +} + static const struct pci_vpd_ops pci_vpd_f0_ops = { .read = pci_vpd_f0_read, .write = pci_vpd_f0_write, + .set_size = pci_vpd_f0_set_size, }; int pci_vpd_init(struct pci_dev *dev) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d0fb93481573..a814bbb80fcb 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -97,6 +97,7 @@ static inline bool pci_has_subordinate(struct pci_dev *pci_dev) struct pci_vpd_ops { ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); + int (*set_size)(struct pci_dev *dev, size_t len); }; struct pci_vpd { diff --git a/include/linux/pci.h b/include/linux/pci.h index 004b8133417d..932ec74909c6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1111,6 +1111,7 @@ void pci_unlock_rescan_remove(void); /* Vital product data routines */ ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf); ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); +int pci_set_vpd_size(struct pci_dev *dev, size_t len); /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx); -- cgit v1.2.3 From 67e658794ca191b3221b143f2a1c10d002c40bc8 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Fri, 15 Apr 2016 13:00:18 -0500 Subject: cxgb4: Set VPD size so we can read both VPD structures Chelsio adapters have two VPD structures stored in the VPD: - offset 0x000: an abbreviated VPD, and - offset 0x400: the complete VPD. After 104daa71b396 ("PCI: Determine actual VPD size on first access"), the PCI core computes the valid VPD size by parsing the VPD starting at offset 0x0. That size only includes the abbreviated VPD structure, so reads of the complete VPD at 0x400 fail. Explicitly set the VPD size with pci_set_vpd_size() so the driver can read both VPD structures. [bhelgaas: changelog, split patches, rename to pci_set_vpd_size() and return int (not ssize_t)] Fixes: 104daa71b396 ("PCI: Determine actual VPD size on first access") Tested-by: Steve Wise Signed-off-by: Casey Leedom Signed-off-by: Hariprasad Shenai Signed-off-by: Bjorn Helgaas --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index cc1736bece0f..c7efb116b577 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2557,6 +2557,7 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) } #define EEPROM_STAT_ADDR 0x7bfc +#define VPD_SIZE 0x800 #define VPD_BASE 0x400 #define VPD_BASE_OLD 0 #define VPD_LEN 1024 @@ -2594,6 +2595,15 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p) if (!vpd) return -ENOMEM; + /* We have two VPD data structures stored in the adapter VPD area. + * By default, Linux calculates the size of the VPD area by traversing + * the first VPD area at offset 0x0, so we need to tell the OS what + * our real VPD size is. + */ + ret = pci_set_vpd_size(adapter->pdev, VPD_SIZE); + if (ret < 0) + goto out; + /* Card information normally starts at VPD_BASE but early cards had * it at 0. */ -- cgit v1.2.3 From de478a61389cacafe94dc8b035081b681b878f9d Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 12 Apr 2016 19:37:44 +0200 Subject: ath9k: ar5008_hw_cmn_spur_mitigate: add missing mask_m & mask_p initialisation by moving common code to ar5008_hw_cmn_spur_mitigate i forgot to move mask_m & mask_p initialisation. This coused a performance regression on ar9281. Fixes: f911085ffa88 ("ath9k: split ar5008_hw_spur_mitigate and reuse common code in ar9002_hw_spur_mitigate.") Reported-by: Gustav Frederiksen Tested-by: Gustav Frederiksen Cc: # 4.2+ Signed-off-by: Oleksij Rempel Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 8 +++----- drivers/net/wireless/ath/ath9k/ar9002_phy.c | 5 ----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 8f8793004b9f..1b271b99c49e 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -274,6 +274,9 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah, }; static const int inc[4] = { 0, 100, 0, 0 }; + memset(&mask_m, 0, sizeof(int8_t) * 123); + memset(&mask_p, 0, sizeof(int8_t) * 123); + cur_bin = -6000; upper = bin + 100; lower = bin - 100; @@ -424,14 +427,9 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, int tmp, new; int i; - int8_t mask_m[123]; - int8_t mask_p[123]; int cur_bb_spur; bool is2GHz = IS_CHAN_2GHZ(chan); - memset(&mask_m, 0, sizeof(int8_t) * 123); - memset(&mask_p, 0, sizeof(int8_t) * 123); - for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); if (AR_NO_SPUR == cur_bb_spur) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index db6624527d99..53d7445a5d12 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -178,14 +178,9 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah, int i; struct chan_centers centers; - int8_t mask_m[123]; - int8_t mask_p[123]; int cur_bb_spur; bool is2GHz = IS_CHAN_2GHZ(chan); - memset(&mask_m, 0, sizeof(int8_t) * 123); - memset(&mask_p, 0, sizeof(int8_t) * 123); - ath9k_hw_get_channel_centers(ah, chan, ¢ers); freq = centers.synth_center; -- cgit v1.2.3 From 0a370d261c805286cbdfa1f96661322a28cce860 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 14 Apr 2016 19:40:47 -0700 Subject: libnvdimm, pmem: clarify the write+clear_poison+write flow The ACPI specification does not specify the state of data after a clear poison operation. Potential future libnvdimm bus implementations for other architectures also might not specify or disagree on the state of data after clear poison. Clarify why we write twice. Reported-by: Jeff Moyer Reported-by: Vishal Verma Signed-off-by: Dan Williams Signed-off-by: Ross Zwisler Reviewed-by: Johannes Thumshirn Reviewed-by: Jeff Moyer Reviewed-by: Vishal Verma --- drivers/nvdimm/pmem.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 8e09c544d892..f798899338ed 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -103,6 +103,20 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page, flush_dcache_page(page); } } else { + /* + * Note that we write the data both before and after + * clearing poison. The write before clear poison + * handles situations where the latest written data is + * preserved and the clear poison operation simply marks + * the address range as valid without changing the data. + * In this case application software can assume that an + * interrupted write will either return the new good + * data or an error. + * + * However, if pmem_clear_poison() leaves the data in an + * indeterminate state we need to perform the write + * after clear poison. + */ flush_dcache_page(page); memcpy_to_pmem(pmem_addr, mem + off, len); if (unlikely(bad_pmem)) { -- cgit v1.2.3 From cfe255600154f0072d4a8695590dbd194dfd1aeb Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Wed, 13 Apr 2016 15:36:48 +0100 Subject: cpsw: Prevent NUll pointer dereference with two PHYs Adding a 2nd PHY to cpsw results in a NULL pointer dereference as below. Fix by maintaining a reference to each PHY node in slave struct instead of a single reference in the priv struct which was overwritten by the 2nd PHY. [ 17.870933] Unable to handle kernel NULL pointer dereference at virtual address 00000180 [ 17.879557] pgd = dc8bc000 [ 17.882514] [00000180] *pgd=9c882831, *pte=00000000, *ppte=00000000 [ 17.889213] Internal error: Oops: 17 [#1] ARM [ 17.893838] Modules linked in: [ 17.897102] CPU: 0 PID: 1657 Comm: connmand Not tainted 4.5.0-ge463dfb-dirty #11 [ 17.904947] Hardware name: Cambrionix whippet [ 17.909576] task: dc859240 ti: dc968000 task.ti: dc968000 [ 17.915339] PC is at phy_attached_print+0x18/0x8c [ 17.920339] LR is at phy_attached_info+0x14/0x18 [ 17.925247] pc : [] lr : [] psr: 600f0113 [ 17.925247] sp : dc969cf8 ip : dc969d28 fp : dc969d18 [ 17.937425] r10: dda7a400 r9 : 00000000 r8 : 00000000 [ 17.942971] r7 : 00000001 r6 : ddb00480 r5 : ddb8cb34 r4 : 00000000 [ 17.949898] r3 : c0954cc0 r2 : c09562b0 r1 : 00000000 r0 : 00000000 [ 17.956829] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 17.964401] Control: 10c5387d Table: 9c8bc019 DAC: 00000051 [ 17.970500] Process connmand (pid: 1657, stack limit = 0xdc968210) [ 17.977059] Stack: (0xdc969cf8 to 0xdc96a000) [ 17.981692] 9ce0: dc969d28 dc969d08 [ 17.990386] 9d00: c038f9bc c038f6b4 ddb00480 dc969d34 dc969d28 c042bb74 c042bae4 00000000 [ 17.999080] 9d20: c09562b0 c0954cc0 dc969d5c dc969d38 c043ebfc c042bb6c 00000007 00000003 [ 18.007773] 9d40: ddb00000 ddb8cb58 ddb00480 00000001 dc969dec dc969d60 c0441614 c043ea68 [ 18.016465] 9d60: 00000000 00000003 00000000 fffffff4 dc969df4 0000000d 00000000 00000000 [ 18.025159] 9d80: dc969db4 dc969d90 c005dc08 c05839e0 dc969df4 0000000d ddb00000 00001002 [ 18.033851] 9da0: 00000000 00000000 dc969dcc dc969db8 c005ddf4 c005dbc8 00000000 00000118 [ 18.042544] 9dc0: dc969dec dc969dd0 ddb00000 c06db27c ffff9003 00001002 00000000 00000000 [ 18.051237] 9de0: dc969e0c dc969df0 c057c88c c04410dc dc969e0c ddb00000 ddb00000 00000001 [ 18.059930] 9e00: dc969e34 dc969e10 c057cb44 c057c7d8 ddb00000 ddb00138 00001002 beaeda20 [ 18.068622] 9e20: 00000000 00000000 dc969e5c dc969e38 c057cc28 c057cac0 00000000 dc969e80 [ 18.077315] 9e40: dda7a40c beaeda20 00000000 00000000 dc969ecc dc969e60 c05e36d0 c057cc14 [ 18.086007] 9e60: dc969e84 00000051 beaeda20 00000000 dda7a40c 00000014 ddb00000 00008914 [ 18.094699] 9e80: 30687465 00000000 00000000 00000000 00009003 00000000 00000000 00000000 [ 18.103391] 9ea0: 00001002 00008914 dd257ae0 beaeda20 c098a428 beaeda20 00000011 00000000 [ 18.112084] 9ec0: dc969edc dc969ed0 c05e4e54 c05e3030 dc969efc dc969ee0 c055f5ac c05e4cc4 [ 18.120777] 9ee0: beaeda20 dd257ae0 dc8ab4c0 00008914 dc969f7c dc969f00 c010b388 c055f45c [ 18.129471] 9f00: c071ca40 dd257ac0 c00165e8 dc968000 dc969f3c dc969f20 dc969f64 dc969f28 [ 18.138164] 9f20: c0115708 c0683ec8 dd257ac0 dd257ac0 dc969f74 dc969f40 c055f350 c00fc66c [ 18.146857] 9f40: dd82e4d0 00000011 00000000 00080000 dd257ac0 00000000 dc8ab4c0 dc8ab4c0 [ 18.155550] 9f60: 00008914 beaeda20 00000011 00000000 dc969fa4 dc969f80 c010bc34 c010b2fc [ 18.164242] 9f80: 00000000 00000011 00000002 00000036 c00165e8 dc968000 00000000 dc969fa8 [ 18.172935] 9fa0: c00163e0 c010bbcc 00000000 00000011 00000011 00008914 beaeda20 00009003 [ 18.181628] 9fc0: 00000000 00000011 00000002 00000036 00081018 00000001 00000000 beaedc10 [ 18.190320] 9fe0: 00083188 beaeda1c 00043a5d b6d29c0c 600b0010 00000011 00000000 00000000 [ 18.198989] Backtrace: [ 18.201621] [] (phy_attached_print) from [] (phy_attached_info+0x14/0x18) [ 18.210664] r3:c0954cc0 r2:c09562b0 r1:00000000 [ 18.215588] r4:ddb00480 [ 18.218322] [] (phy_attached_info) from [] (cpsw_slave_open+0x1a0/0x280) [ 18.227293] [] (cpsw_slave_open) from [] (cpsw_ndo_open+0x544/0x674) [ 18.235874] r7:00000001 r6:ddb00480 r5:ddb8cb58 r4:ddb00000 [ 18.241944] [] (cpsw_ndo_open) from [] (__dev_open+0xc0/0x128) [ 18.249972] r9:00000000 r8:00000000 r7:00001002 r6:ffff9003 r5:c06db27c r4:ddb00000 [ 18.258255] [] (__dev_open) from [] (__dev_change_flags+0x90/0x154) [ 18.266745] r5:00000001 r4:ddb00000 [ 18.270575] [] (__dev_change_flags) from [] (dev_change_flags+0x20/0x50) [ 18.279523] r9:00000000 r8:00000000 r7:beaeda20 r6:00001002 r5:ddb00138 r4:ddb00000 [ 18.287811] [] (dev_change_flags) from [] (devinet_ioctl+0x6ac/0x76c) [ 18.296483] r9:00000000 r8:00000000 r7:beaeda20 r6:dda7a40c r5:dc969e80 r4:00000000 [ 18.304762] [] (devinet_ioctl) from [] (inet_ioctl+0x19c/0x1c8) [ 18.312882] r10:00000000 r9:00000011 r8:beaeda20 r7:c098a428 r6:beaeda20 r5:dd257ae0 [ 18.321235] r4:00008914 [ 18.323956] [] (inet_ioctl) from [] (sock_ioctl+0x15c/0x2d8) [ 18.331829] [] (sock_ioctl) from [] (do_vfs_ioctl+0x98/0x8d0) [ 18.339765] r7:00008914 r6:dc8ab4c0 r5:dd257ae0 r4:beaeda20 [ 18.345822] [] (do_vfs_ioctl) from [] (SyS_ioctl+0x74/0x84) [ 18.353573] r10:00000000 r9:00000011 r8:beaeda20 r7:00008914 r6:dc8ab4c0 r5:dc8ab4c0 [ 18.361924] r4:00000000 [ 18.364653] [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x3c) [ 18.372682] r9:dc968000 r8:c00165e8 r7:00000036 r6:00000002 r5:00000011 r4:00000000 [ 18.380960] Code: e92dd810 e24cb010 e24dd010 e59b4004 (e5902180) [ 18.387580] ---[ end trace c80529466223f3f3 ]--- Signed-off-by: Andrew Goodbody Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 42fdfd4d9d4f..5f5bb4471800 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -349,6 +349,7 @@ struct cpsw_slave { struct cpsw_slave_data *data; struct phy_device *phy; struct net_device *ndev; + struct device_node *phy_node; u32 port_vlan; u32 open_stat; }; @@ -367,7 +368,6 @@ struct cpsw_priv { spinlock_t lock; struct platform_device *pdev; struct net_device *ndev; - struct device_node *phy_node; struct napi_struct napi_rx; struct napi_struct napi_tx; struct device *dev; @@ -1148,8 +1148,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); - if (priv->phy_node) - slave->phy = of_phy_connect(priv->ndev, priv->phy_node, + if (slave->phy_node) + slave->phy = of_phy_connect(priv->ndev, slave->phy_node, &cpsw_adjust_link, 0, slave->data->phy_if); else slave->phy = phy_connect(priv->ndev, slave->data->phy_id, @@ -2033,7 +2033,8 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, if (strcmp(slave_node->name, "slave")) continue; - priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0); + priv->slaves[i].phy_node = + of_parse_phandle(slave_node, "phy-handle", 0); parp = of_get_property(slave_node, "phy_id", &lenp); if (of_phy_is_fixed_link(slave_node)) { struct device_node *phy_node; @@ -2275,12 +2276,22 @@ static int cpsw_probe(struct platform_device *pdev) /* Select default pin state */ pinctrl_pm_select_default_state(&pdev->dev); + data = &priv->data; + priv->slaves = devm_kzalloc(&pdev->dev, + sizeof(struct cpsw_slave) * data->slaves, + GFP_KERNEL); + if (!priv->slaves) { + ret = -ENOMEM; + goto clean_runtime_disable_ret; + } + for (i = 0; i < data->slaves; i++) + priv->slaves[i].slave_num = i; + if (cpsw_probe_dt(priv, pdev)) { dev_err(&pdev->dev, "cpsw: platform data missing\n"); ret = -ENODEV; goto clean_runtime_disable_ret; } - data = &priv->data; if (is_valid_ether_addr(data->slave_data[0].mac_addr)) { memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN); @@ -2292,16 +2303,6 @@ static int cpsw_probe(struct platform_device *pdev) memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN); - priv->slaves = devm_kzalloc(&pdev->dev, - sizeof(struct cpsw_slave) * data->slaves, - GFP_KERNEL); - if (!priv->slaves) { - ret = -ENOMEM; - goto clean_runtime_disable_ret; - } - for (i = 0; i < data->slaves; i++) - priv->slaves[i].slave_num = i; - priv->slaves[0].ndev = ndev; priv->emac_port = 0; -- cgit v1.2.3 From 9241e2df4fbc648a92ea0752918e05c26255649e Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Sat, 16 Apr 2016 02:27:58 +0200 Subject: vlan: pull on __vlan_insert_tag error path and fix csum correction When __vlan_insert_tag() fails from skb_vlan_push() path due to the skb_cow_head(), we need to undo the __skb_push() in the error path as well that was done earlier to move skb->data pointer to mac header. Moreover, I noticed that when in the non-error path the __skb_pull() is done and the original offset to mac header was non-zero, we fixup from a wrong skb->data offset in the checksum complete processing. So the skb_postpush_rcsum() really needs to be done before __skb_pull() where skb->data still points to the mac header start and thus operates under the same conditions as in __vlan_insert_tag(). Fixes: 93515d53b133 ("net: move vlan pop/push functions into common code") Signed-off-by: Daniel Borkmann Reviewed-by: Jiri Pirko Signed-off-by: David S. Miller --- net/core/skbuff.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d04c2d1c8c87..e561f9f07d6d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4502,13 +4502,16 @@ int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci) __skb_push(skb, offset); err = __vlan_insert_tag(skb, skb->vlan_proto, skb_vlan_tag_get(skb)); - if (err) + if (err) { + __skb_pull(skb, offset); return err; + } + skb->protocol = skb->vlan_proto; skb->mac_len += VLAN_HLEN; - __skb_pull(skb, offset); skb_postpush_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN); + __skb_pull(skb, offset); } __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); return 0; -- cgit v1.2.3 From b1547d3101e74e809b9790174b27f1080747b009 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Fri, 15 Apr 2016 09:17:10 -0500 Subject: objtool: Detect falling through to the next function There are several cases in compiled C code where a function may not return at the end, and may instead fall through to the next function. That may indicate a bug in the code, or a gcc bug, or even an objtool bug. But in each case, objtool reports an unhelpful warning, something like: drivers/scsi/qla2xxx/qla_attr.o: warning: objtool: qla2x00_get_fc_host_stats()+0x0: duplicate frame pointer save drivers/scsi/qla2xxx/qla_attr.o: warning: objtool: qla2x00_get_fc_host_stats()+0x0: frame pointer state mismatch Detect this situation and print a more useful error message: drivers/scsi/qla2xxx/qla_attr.o: warning: objtool: qla2x00_get_host_fabric_name() falls through to next function qla2x00_get_starget_node_name() Also add some information about this warning and its potential causes to the documentation. Reported-by: kbuild test robot Signed-off-by: Josh Poimboeuf Cc: Alexander Shishkin Cc: Andy Lutomirski Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/caa4ec6c687931db805e692d4e4bf06cd87d33e6.1460729697.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar --- tools/objtool/Documentation/stack-validation.txt | 38 +++++++++++++++----- tools/objtool/builtin-check.c | 46 ++++++++++++++++-------- 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/tools/objtool/Documentation/stack-validation.txt b/tools/objtool/Documentation/stack-validation.txt index 5a95896105bc..55a60d331f47 100644 --- a/tools/objtool/Documentation/stack-validation.txt +++ b/tools/objtool/Documentation/stack-validation.txt @@ -299,18 +299,38 @@ they mean, and suggestions for how to fix them. Errors in .c files ------------------ -If you're getting an objtool error in a compiled .c file, chances are -the file uses an asm() statement which has a "call" instruction. An -asm() statement with a call instruction must declare the use of the -stack pointer in its output operand. For example, on x86_64: +1. c_file.o: warning: objtool: funcA() falls through to next function funcB() - register void *__sp asm("rsp"); - asm volatile("call func" : "+r" (__sp)); + This means that funcA() doesn't end with a return instruction or an + unconditional jump, and that objtool has determined that the function + can fall through into the next function. There could be different + reasons for this: -Otherwise the stack frame may not get created before the call. + 1) funcA()'s last instruction is a call to a "noreturn" function like + panic(). In this case the noreturn function needs to be added to + objtool's hard-coded global_noreturns array. Feel free to bug the + objtool maintainer, or you can submit a patch. -Another possible cause for errors in C code is if the Makefile removes --fno-omit-frame-pointer or adds -fomit-frame-pointer to the gcc options. + 2) funcA() uses the unreachable() annotation in a section of code + that is actually reachable. + + 3) If funcA() calls an inline function, the object code for funcA() + might be corrupt due to a gcc bug. For more details, see: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70646 + +2. If you're getting any other objtool error in a compiled .c file, it + may be because the file uses an asm() statement which has a "call" + instruction. An asm() statement with a call instruction must declare + the use of the stack pointer in its output operand. For example, on + x86_64: + + register void *__sp asm("rsp"); + asm volatile("call func" : "+r" (__sp)); + + Otherwise the stack frame may not get created before the call. + +3. Another possible cause for errors in C code is if the Makefile removes + -fno-omit-frame-pointer or adds -fomit-frame-pointer to the gcc options. Also see the above section for .S file errors for more information what the individual error messages mean. diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 157a0f96d64d..e8a1e69eb92c 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -54,6 +54,7 @@ struct instruction { struct symbol *call_dest; struct instruction *jump_dest; struct list_head alts; + struct symbol *func; }; struct alternative { @@ -66,7 +67,7 @@ struct objtool_file { struct list_head insn_list; DECLARE_HASHTABLE(insn_hash, 16); struct section *rodata, *whitelist; - bool ignore_unreachables; + bool ignore_unreachables, c_file; }; const char *objname; @@ -229,7 +230,7 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func, } } - if (insn->type == INSN_JUMP_DYNAMIC) + if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts)) /* sibling call */ return 0; } @@ -249,6 +250,7 @@ static int dead_end_function(struct objtool_file *file, struct symbol *func) static int decode_instructions(struct objtool_file *file) { struct section *sec; + struct symbol *func; unsigned long offset; struct instruction *insn; int ret; @@ -282,6 +284,21 @@ static int decode_instructions(struct objtool_file *file) hash_add(file->insn_hash, &insn->hash, insn->offset); list_add_tail(&insn->list, &file->insn_list); } + + list_for_each_entry(func, &sec->symbol_list, list) { + if (func->type != STT_FUNC) + continue; + + if (!find_insn(file, sec, func->offset)) { + WARN("%s(): can't find starting instruction", + func->name); + return -1; + } + + func_for_each_insn(file, func, insn) + if (!insn->func) + insn->func = func; + } } return 0; @@ -824,6 +841,7 @@ static int validate_branch(struct objtool_file *file, struct alternative *alt; struct instruction *insn; struct section *sec; + struct symbol *func = NULL; unsigned char state; int ret; @@ -838,6 +856,16 @@ static int validate_branch(struct objtool_file *file, } while (1) { + if (file->c_file && insn->func) { + if (func && func != insn->func) { + WARN("%s() falls through to next function %s()", + func->name, insn->func->name); + return 1; + } + + func = insn->func; + } + if (insn->visited) { if (frame_state(insn->state) != frame_state(state)) { WARN_FUNC("frame pointer state mismatch", @@ -848,13 +876,6 @@ static int validate_branch(struct objtool_file *file, return 0; } - /* - * Catch a rare case where a noreturn function falls through to - * the next function. - */ - if (is_fentry_call(insn) && (state & STATE_FENTRY)) - return 0; - insn->visited = true; insn->state = state; @@ -1060,12 +1081,8 @@ static int validate_functions(struct objtool_file *file) continue; insn = find_insn(file, sec, func->offset); - if (!insn) { - WARN("%s(): can't find starting instruction", - func->name); - warnings++; + if (!insn) continue; - } ret = validate_branch(file, insn, 0); warnings += ret; @@ -1162,6 +1179,7 @@ int cmd_check(int argc, const char **argv) file.whitelist = find_section_by_name(file.elf, "__func_stack_frame_non_standard"); file.rodata = find_section_by_name(file.elf, ".rodata"); file.ignore_unreachables = false; + file.c_file = find_section_by_name(file.elf, ".comment"); ret = decode_sections(&file); if (ret < 0) -- cgit v1.2.3 From 1e2ae9ec072f3b7887f456426bc2cf23b80f661a Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 15 Apr 2016 15:50:32 +0200 Subject: x86/hyperv: Avoid reporting bogus NMI status for Gen2 instances Generation2 instances don't support reporting the NMI status on port 0x61, read from there returns 'ff' and we end up reporting nonsensical PCI error (as there is no PCI bus in these instances) on all NMIs: NMI: PCI system error (SERR) for reason ff on CPU 0. Dazed and confused, but trying to continue Fix the issue by overriding x86_platform.get_nmi_reason. Use 'booted on EFI' flag to detect Gen2 instances. Signed-off-by: Vitaly Kuznetsov Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Cathy Avery Cc: Haiyang Zhang Cc: Jiri Olsa Cc: K. Y. Srinivasan Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: devel@linuxdriverproject.org Link: http://lkml.kernel.org/r/1460728232-31433-1-git-send-email-vkuznets@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/mshyperv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 4e7c6933691c..10c11b4da31d 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -152,6 +152,11 @@ static struct clocksource hyperv_cs = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static unsigned char hv_get_nmi_reason(void) +{ + return 0; +} + static void __init ms_hyperv_init_platform(void) { /* @@ -191,6 +196,13 @@ static void __init ms_hyperv_init_platform(void) machine_ops.crash_shutdown = hv_machine_crash_shutdown; #endif mark_tsc_unstable("running on Hyper-V"); + + /* + * Generation 2 instances don't support reading the NMI status from + * 0x61 port. + */ + if (efi_enabled(EFI_BOOT)) + x86_platform.get_nmi_reason = hv_get_nmi_reason; } const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { -- cgit v1.2.3 From a7c556546f610a331c22cb7edd9d1afe63f0cd52 Mon Sep 17 00:00:00 2001 From: Qing Huang Date: Thu, 14 Apr 2016 10:43:26 -0700 Subject: RDS: fix endianness for dp_ack_seq dp->dp_ack_seq is used in big endian format. We need to do the big endianness conversion when we assign a value in host format to it. Signed-off-by: Qing Huang Signed-off-by: Santosh Shilimkar Signed-off-by: David S. Miller --- net/rds/ib_cm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 8764970f0c24..310cabce2311 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -194,7 +194,7 @@ static void rds_ib_cm_fill_conn_param(struct rds_connection *conn, dp->dp_protocol_major = RDS_PROTOCOL_MAJOR(protocol_version); dp->dp_protocol_minor = RDS_PROTOCOL_MINOR(protocol_version); dp->dp_protocol_minor_mask = cpu_to_be16(RDS_IB_SUPPORTED_PROTOCOLS); - dp->dp_ack_seq = rds_ib_piggyb_ack(ic); + dp->dp_ack_seq = cpu_to_be64(rds_ib_piggyb_ack(ic)); /* Advertise flow control */ if (ic->i_flowctl) { -- cgit v1.2.3 From e47db94e10447fc467777a40302f2b393e9af2fa Mon Sep 17 00:00:00 2001 From: "santosh.shilimkar@oracle.com" Date: Thu, 14 Apr 2016 10:43:27 -0700 Subject: RDS: Fix the atomicity for congestion map update Two different threads with different rds sockets may be in rds_recv_rcvbuf_delta() via receive path. If their ports both map to the same word in the congestion map, then using non-atomic ops to update it could cause the map to be incorrect. Lets use atomics to avoid such an issue. Full credit to Wengang for finding the issue, analysing it and also pointing out to offending code with spin lock based fix. Reviewed-by: Leon Romanovsky Signed-off-by: Wengang Wang Signed-off-by: Santosh Shilimkar Signed-off-by: David S. Miller --- net/rds/cong.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rds/cong.c b/net/rds/cong.c index e6144b8246fd..6641bcf7c185 100644 --- a/net/rds/cong.c +++ b/net/rds/cong.c @@ -299,7 +299,7 @@ void rds_cong_set_bit(struct rds_cong_map *map, __be16 port) i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS; off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS; - __set_bit_le(off, (void *)map->m_page_addrs[i]); + set_bit_le(off, (void *)map->m_page_addrs[i]); } void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port) @@ -313,7 +313,7 @@ void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port) i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS; off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS; - __clear_bit_le(off, (void *)map->m_page_addrs[i]); + clear_bit_le(off, (void *)map->m_page_addrs[i]); } static int rds_cong_test_bit(struct rds_cong_map *map, __be16 port) -- cgit v1.2.3 From 65fa40276ac1318e75264e5a204547b57c2cf397 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Thu, 14 Apr 2016 14:42:07 -0400 Subject: net: dsa: mv88e6xxx: unlock DSA and CPU ports Locking a port generates an hardware interrupt when a new SA address is received. This enables CPU directed learning, which is needed for 802.1X MAC authentication. To disable automatic learning on a port, the only configuration needed is to set its Port Association Vector to all zero. Clear PAV when SA learning should be disabled instead of locking a port. Fixes: 4c7ea3c0791e ("net: dsa: mv88e6xxx: disable SA learning for DSA and CPU ports") Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 50454be86570..028ebe2a6053 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2478,7 +2478,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) reg = 1 << port; /* Disable learning for DSA and CPU ports */ if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) - reg = PORT_ASSOC_VECTOR_LOCKED_PORT; + reg = 0; ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_ASSOC_VECTOR, reg); if (ret) -- cgit v1.2.3 From 996ecb8246676100af2a4dc1cfed747712a3c85f Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Thu, 14 Apr 2016 14:42:08 -0400 Subject: net: dsa: mv88e6xxx: enable SA learning on DSA ports In multi-chip systems, DSA Tag ports must learn SA addresses in order to correctly switch frames between interconnected chips. This fixes cross-chip hardware bridging in a VLAN filtering aware system, because a bridge group gets implemented as an hardware 802.1Q VLAN and thus DSA and user ports share the same FDB. Fixes: 4c7ea3c0791e ("net: dsa: mv88e6xxx: disable SA learning for DSA and CPU ports") Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 028ebe2a6053..169c9483566f 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2476,8 +2476,8 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) * the other bits clear. */ reg = 1 << port; - /* Disable learning for DSA and CPU ports */ - if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) + /* Disable learning for CPU port */ + if (dsa_is_cpu_port(ds, port)) reg = 0; ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_ASSOC_VECTOR, reg); -- cgit v1.2.3 From 207afda1b5036009e611df2106e6d441be397bee Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Thu, 14 Apr 2016 14:42:09 -0400 Subject: net: dsa: mv88e6xxx: share the same default FDB For hardware cross-chip bridging to work, user ports *and* DSA ports need to share a common address database, in order to switch a frame to the correct interconnected device. This is currently working for VLAN filtering aware systems, since Linux will implement a bridge group as a 802.1Q VLAN, which has its own FDB, including DSA and CPU links as members. However when the system doesn't support VLAN filtering, Linux only relies on the port-based VLAN to implement a bridge group. To fix hardware cross-chip bridging for such systems, set the same default address database 0 for user and DSA ports, instead of giving them all a different default database. Note that the bridging code prevents frames to egress between unbridged ports, and flushes FDB entries of a port when changing its STP state. Also note that the FID 0 is special and means "all" for ATU operations, but it's OK since it is used as a default forwarding address database. Fixes: 2db9ce1fd9a3 ("net: dsa: mv88e6xxx: assign default FDB to ports") Fixes: 466dfa077022 ("net: dsa: mv88e6xxx: assign dynamic FDB to bridges") Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 169c9483566f..a2904029cccc 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2181,27 +2181,10 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *bridge) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - u16 fid; int i, err; mutex_lock(&ps->smi_mutex); - /* Get or create the bridge FID and assign it to the port */ - for (i = 0; i < ps->num_ports; ++i) - if (ps->ports[i].bridge_dev == bridge) - break; - - if (i < ps->num_ports) - err = _mv88e6xxx_port_fid_get(ds, i, &fid); - else - err = _mv88e6xxx_fid_new(ds, &fid); - if (err) - goto unlock; - - err = _mv88e6xxx_port_fid_set(ds, port, fid); - if (err) - goto unlock; - /* Assign the bridge and remap each port's VLANTable */ ps->ports[port].bridge_dev = bridge; @@ -2213,7 +2196,6 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, } } -unlock: mutex_unlock(&ps->smi_mutex); return err; @@ -2223,16 +2205,10 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct net_device *bridge = ps->ports[port].bridge_dev; - u16 fid; int i; mutex_lock(&ps->smi_mutex); - /* Give the port a fresh Filtering Information Database */ - if (_mv88e6xxx_fid_new(ds, &fid) || - _mv88e6xxx_port_fid_set(ds, port, fid)) - netdev_warn(ds->ports[port], "failed to assign a new FID\n"); - /* Unassign the bridge and remap each port's VLANTable */ ps->ports[port].bridge_dev = NULL; @@ -2558,11 +2534,11 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) if (ret) goto abort; - /* Port based VLAN map: give each port its own address + /* Port based VLAN map: give each port the same default address * database, and allow bidirectional communication between the * CPU and DSA port(s), and the other ports. */ - ret = _mv88e6xxx_port_fid_set(ds, port, port + 1); + ret = _mv88e6xxx_port_fid_set(ds, port, 0); if (ret) goto abort; -- cgit v1.2.3 From 6517eb59b03965689e6bb16bb2d480096b3ef95d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 15 Apr 2016 10:47:52 -0700 Subject: net: bcmgenet: device stats are unsigned long On 64bit kernels, device stats are 64bit wide, not 32bit. Fixes: 1c1008c793fa4 ("net: bcmgenet: add main driver file") Signed-off-by: Eric Dumazet Cc: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index cf6445d148ca..44ad1490b472 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -878,7 +878,11 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev, else p = (char *)priv; p += s->stat_offset; - data[i] = *(u32 *)p; + if (sizeof(unsigned long) != sizeof(u32) && + s->stat_sizeof == sizeof(unsigned long)) + data[i] = *(unsigned long *)p; + else + data[i] = *(u32 *)p; } } -- cgit v1.2.3 From 50fd4987c4f3c3ebf0ce94d932732011bbdc7c71 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 17 Apr 2016 09:39:41 +0200 Subject: ALSA: hda - Don't trust the reported actual power state We've got a regression report that the recording on Mac with a cirrus codec doesn't work any longer. This turned out to be the missing power up to D0 by power_save_node enablement. After analyzing the traces, we found out that the culprit is that the codec advertises the "actual" power state of a few nodes to be D0 while the "target" power state is D3. This inconsistency is usually OK, as it implies the power transition. But in the case of cirrus codec, this seems to be stuck to D3 while it's not actually D0. This patch addresses the issue by checking the power state difference more strictly. It sends the power-state change verb unless both the target and the actual power states show the given value. We may introduce yet another flag indicating the possible broken hardware power state, but it's anyway safer to set the proper power state even in a transition (at least it's harmless as long as the target state is same). So this simpler change was applied now. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=116171 Cc: # v4.4+ Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 7ca5b89f088a..dfaf1a93fb8a 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -826,7 +826,7 @@ static hda_nid_t path_power_update(struct hda_codec *codec, bool allow_powerdown) { hda_nid_t nid, changed = 0; - int i, state; + int i, state, power; for (i = 0; i < path->depth; i++) { nid = path->path[i]; @@ -838,7 +838,9 @@ static hda_nid_t path_power_update(struct hda_codec *codec, state = AC_PWRST_D0; else state = AC_PWRST_D3; - if (!snd_hda_check_power_state(codec, nid, state)) { + power = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_POWER_STATE, 0); + if (power != (state | (state << 4))) { snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, state); changed = nid; -- cgit v1.2.3 From 07d2390e36ee5b3265e9cc8305f2a106c8721e16 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 4 Apr 2016 14:54:59 +0900 Subject: iio: ak8975: Fix NULL pointer exception on early interrupt In certain probe conditions the interrupt came right after registering the handler causing a NULL pointer exception because of uninitialized waitqueue: $ udevadm trigger i2c-gpio i2c-gpio-1: using pins 143 (SDA) and 144 (SCL) i2c-gpio i2c-gpio-3: using pins 53 (SDA) and 52 (SCL) Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = e8b38000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: snd_soc_i2s(+) i2c_gpio(+) snd_soc_idma snd_soc_s3c_dma snd_soc_core snd_pcm_dmaengine snd_pcm snd_timer snd soundcore ac97_bus spi_s3c64xx pwm_samsung dwc2 exynos_adc phy_exynos_usb2 exynosdrm exynos_rng rng_core rtc_s3c CPU: 0 PID: 717 Comm: data-provider-m Not tainted 4.6.0-rc1-next-20160401-00011-g1b8d87473b9e-dirty #101 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) (...) (__wake_up_common) from [] (__wake_up+0x38/0x4c) (__wake_up) from [] (ak8975_irq_handler+0x28/0x30) (ak8975_irq_handler) from [] (handle_irq_event_percpu+0x88/0x140) (handle_irq_event_percpu) from [] (handle_irq_event+0x44/0x68) (handle_irq_event) from [] (handle_edge_irq+0xf0/0x19c) (handle_edge_irq) from [] (generic_handle_irq+0x24/0x34) (generic_handle_irq) from [] (exynos_eint_gpio_irq+0x50/0x68) (exynos_eint_gpio_irq) from [] (handle_irq_event_percpu+0x88/0x140) (handle_irq_event_percpu) from [] (handle_irq_event+0x44/0x68) (handle_irq_event) from [] (handle_fasteoi_irq+0xb4/0x194) (handle_fasteoi_irq) from [] (generic_handle_irq+0x24/0x34) (generic_handle_irq) from [] (__handle_domain_irq+0x5c/0xb4) (__handle_domain_irq) from [] (gic_handle_irq+0x54/0x94) (gic_handle_irq) from [] (__irq_usr+0x50/0x80) The bug was reproduced on exynos4412-trats2 (with a max77693 device also using i2c-gpio) after building max77693 as a module. Cc: Fixes: 94a6d5cf7caa ("iio:ak8975 Implement data ready interrupt handling") Signed-off-by: Krzysztof Kozlowski Tested-by: Gregor Boirie Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 9c5c9ef3f1da..3b23a850c930 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -462,6 +462,8 @@ static int ak8975_setup_irq(struct ak8975_data *data) int rc; int irq; + init_waitqueue_head(&data->data_ready_queue); + clear_bit(0, &data->flags); if (client->irq) irq = client->irq; else @@ -477,8 +479,6 @@ static int ak8975_setup_irq(struct ak8975_data *data) return rc; } - init_waitqueue_head(&data->data_ready_queue); - clear_bit(0, &data->flags); data->eoc_irq = irq; return rc; -- cgit v1.2.3 From 05be8d4101d960bad271d32b4f6096af1ccb1534 Mon Sep 17 00:00:00 2001 From: Richard Leitner Date: Tue, 5 Apr 2016 15:03:48 +0200 Subject: iio: ak8975: fix maybe-uninitialized warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If i2c_device_id *id is NULL and acpi_match_device returns NULL too, then chipset may be unitialized when accessing &ak_def_array[chipset] in ak8975_probe. Therefore initialize chipset to AK_MAX_TYPE, which will return an error when not changed. This patch fixes the following maybe-uninitialized warning: drivers/iio/magnetometer/ak8975.c: In function ‘ak8975_probe’: drivers/iio/magnetometer/ak8975.c:788:14: warning: ‘chipset’ may be used uninitialized in this function [-Wmaybe-uninitialized] data->def = &ak_def_array[chipset]; Signed-off-by: Richard Leitner Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/ak8975.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 3b23a850c930..0e931a9a1669 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -732,7 +732,7 @@ static int ak8975_probe(struct i2c_client *client, int eoc_gpio; int err; const char *name = NULL; - enum asahi_compass_chipset chipset; + enum asahi_compass_chipset chipset = AK_MAX_TYPE; /* Grab and set up the supplied GPIO. */ if (client->dev.platform_data) -- cgit v1.2.3 From ca3704c23a3b3dfc9d721cf21953fd6b3cbfc3e0 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Sun, 17 Apr 2016 05:20:32 -0700 Subject: Input: arizona-haptic - don't assign input_dev parent We shouldn't assign the parent device of the input_dev to be the parent MFD device, because this will be used for devres which causes input_unregister_device to run after the haptics device has been removed, since it is itself a child of the MFD device. The default of using the haptics device itself as the parent is correct. Signed-off-by: Charles Keepax Signed-off-by: Dmitry Torokhov --- drivers/input/misc/arizona-haptics.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c index d5994a745ffa..982936334537 100644 --- a/drivers/input/misc/arizona-haptics.c +++ b/drivers/input/misc/arizona-haptics.c @@ -178,7 +178,6 @@ static int arizona_haptics_probe(struct platform_device *pdev) input_set_drvdata(haptics->input_dev, haptics); haptics->input_dev->name = "arizona:haptics"; - haptics->input_dev->dev.parent = pdev->dev.parent; haptics->input_dev->close = arizona_haptics_close; __set_bit(FF_RUMBLE, haptics->input_dev->ffbit); -- cgit v1.2.3 From eda5ecc0a6b865561997e177c393f0b0136fe3b7 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sun, 17 Apr 2016 05:21:42 -0700 Subject: Input: pmic8xxx-pwrkey - fix algorithm for converting trigger delay The trigger delay algorithm that converts from microseconds to the register value looks incorrect. According to most of the PMIC documentation, the equation is delay (Seconds) = (1 / 1024) * 2 ^ (x + 4) except for one case where the documentation looks to have a formatting issue and the equation looks like delay (Seconds) = (1 / 1024) * 2 x + 4 Most likely this driver was written with the improper documentation to begin with. According to the downstream sources the valid delays are from 2 seconds to 1/64 second, and the latter equation just doesn't make sense for that. Let's fix the algorithm and the range check to match the documentation and the downstream sources. Reported-by: Bjorn Andersson Fixes: 92d57a73e410 ("input: Add support for Qualcomm PMIC8XXX power key") Signed-off-by: Stephen Boyd Tested-by: John Stultz Acked-by: Bjorn Andersson Signed-off-by: Dmitry Torokhov --- drivers/input/misc/pmic8xxx-pwrkey.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index 3f02e0e03d12..67aab86048ad 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c @@ -353,7 +353,8 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev) if (of_property_read_u32(pdev->dev.of_node, "debounce", &kpd_delay)) kpd_delay = 15625; - if (kpd_delay > 62500 || kpd_delay == 0) { + /* Valid range of pwr key trigger delay is 1/64 sec to 2 seconds. */ + if (kpd_delay > USEC_PER_SEC * 2 || kpd_delay < USEC_PER_SEC / 64) { dev_err(&pdev->dev, "invalid power key trigger delay\n"); return -EINVAL; } @@ -385,8 +386,8 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev) pwr->name = "pmic8xxx_pwrkey"; pwr->phys = "pmic8xxx_pwrkey/input0"; - delay = (kpd_delay << 10) / USEC_PER_SEC; - delay = 1 + ilog2(delay); + delay = (kpd_delay << 6) / USEC_PER_SEC; + delay = ilog2(delay); err = regmap_read(regmap, PON_CNTL_1, &pon_cntl); if (err < 0) { -- cgit v1.2.3 From 6545b60baaf880b0cd29a5e89dbe745a06027e89 Mon Sep 17 00:00:00 2001 From: Ahmed Samy Date: Sun, 17 Apr 2016 05:37:09 +0000 Subject: dm cache metadata: fix cmd_read_lock() acquiring write lock Commit 9567366fefdd ("dm cache metadata: fix READ_LOCK macros and cleanup WRITE_LOCK macros") uses down_write() instead of down_read() in cmd_read_lock(), yet up_read() is used to release the lock in READ_UNLOCK(). Fix it. Fixes: 9567366fefdd ("dm cache metadata: fix READ_LOCK macros and cleanup WRITE_LOCK macros") Cc: stable@vger.kernel.org Signed-off-by: Ahmed Samy Signed-off-by: Mike Snitzer --- drivers/md/dm-cache-metadata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index 65ce6985f87a..3970cda10080 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c @@ -894,9 +894,9 @@ static bool cmd_write_lock(struct dm_cache_metadata *cmd) static bool cmd_read_lock(struct dm_cache_metadata *cmd) { - down_write(&cmd->root_lock); + down_read(&cmd->root_lock); if (cmd->fail_io) { - up_write(&cmd->root_lock); + up_read(&cmd->root_lock); return false; } return true; -- cgit v1.2.3 From ab2ed0171a50ddee8390f472bb83f60d393b4b04 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 17 Apr 2016 11:19:55 +0200 Subject: macsec: fix crypto Kconfig dependency The new MACsec driver uses the AES crypto algorithm, but can be configured even if CONFIG_CRYPTO is disabled, leading to a build error: warning: (MAC80211 && MACSEC) selects CRYPTO_GCM which has unmet direct dependencies (CRYPTO) warning: (BT && CEPH_LIB && INET && MAC802154 && MAC80211 && BLK_DEV_RBD && MACSEC && AIRO_CS && LIBIPW && HOSTAP && USB_WUSB && RTLLIB_CRYPTO_CCMP && FS_ENCRYPTION && EXT4_ENCRYPTION && CEPH_FS && BIG_KEYS && ENCRYPTED_KEYS) selects CRYPTO_AES which has unmet direct dependencies (CRYPTO) crypto/built-in.o: In function `gcm_enc_copy_hash': aes_generic.c:(.text+0x2b8): undefined reference to `crypto_xor' aes_generic.c:(.text+0x2dc): undefined reference to `scatterwalk_map_and_copy' This adds an explicit 'select CRYPTO' statement the way that other drivers handle it. Signed-off-by: Arnd Bergmann Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Signed-off-by: David S. Miller --- drivers/net/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2a1ba62b7da2..a24c18eee598 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -195,6 +195,7 @@ config GENEVE config MACSEC tristate "IEEE 802.1AE MAC-level encryption (MACsec)" + select CRYPTO select CRYPTO_AES select CRYPTO_GCM ---help--- -- cgit v1.2.3 From c3b46c73264b03000d1e18b22f5caf63332547c9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 17 Apr 2016 19:13:32 -0700 Subject: Linux 4.6-rc4 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1d0aef03eae7..873411873c03 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = Blurry Fish Butt # *DOCUMENTATION* -- cgit v1.2.3 From ed0739b577f2ddd53835f1e20d014fccab195c42 Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Mon, 18 Apr 2016 09:16:28 +0800 Subject: ALSA - hda: hdmi check NULL pointer in hdmi_set_chmap Make sure per_pin is not NULL before using it. Fixes: 9b3dc8aa3fb1 ('ALSA: hda - Register chmap obj as priv data instead of codec') Signed-off-by: Libin Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index c83c1a8d9742..40933aa33afe 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1858,6 +1858,8 @@ static void hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx, struct hdmi_spec *spec = codec->spec; struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx); + if (!per_pin) + return; mutex_lock(&per_pin->lock); per_pin->chmap_set = true; memcpy(per_pin->chmap, chmap, ARRAY_SIZE(per_pin->chmap)); -- cgit v1.2.3 From f36fdacc5fcdca7b0c0d89f031fcdc89717e0be3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 23 Feb 2016 11:01:38 +0100 Subject: video: ARM CLCD: runtime check for Versatile The current compile-time check for inversed IENB/CNTL does not work in multiplatform boots: as soon as versatile is included in the build, the IENB/CNTL is switched and breaks graphics. Convert this to a runtime switch. Cc: stable@vger.kernel.org Cc: Rob Herring Cc: Russell King Fixes: a29da136de34 ("ARM: versatile: convert to multi-platform") Signed-off-by: Linus Walleij Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/amba-clcd.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index fe274b5851c7..93e66a9148b9 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -440,13 +440,14 @@ static int clcdfb_register(struct clcd_fb *fb) fb->off_ienb = CLCD_PL111_IENB; fb->off_cntl = CLCD_PL111_CNTL; } else { -#ifdef CONFIG_ARCH_VERSATILE - fb->off_ienb = CLCD_PL111_IENB; - fb->off_cntl = CLCD_PL111_CNTL; -#else - fb->off_ienb = CLCD_PL110_IENB; - fb->off_cntl = CLCD_PL110_CNTL; -#endif + if (of_machine_is_compatible("arm,versatile-ab") || + of_machine_is_compatible("arm,versatile-pb")) { + fb->off_ienb = CLCD_PL111_IENB; + fb->off_cntl = CLCD_PL111_CNTL; + } else { + fb->off_ienb = CLCD_PL110_IENB; + fb->off_cntl = CLCD_PL110_CNTL; + } } fb->clk = clk_get(&fb->dev->dev, NULL); -- cgit v1.2.3 From 4dacad61514494f2eba9e60d5b4aa71971dac6a1 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 23 Mar 2016 00:51:54 +0200 Subject: omapfb: panel-sharp-ls037v7dw01: fix check of gpio_to_desc() return value The change fixes a check of gpio_to_desc() return value, the function returns either a valid pointer to struct gpio_desc or NULL, this makes IS_ERR() check invalid and may lead to a NULL pointer dereference in runtime. Signed-off-by: Vladimir Zapolskiy Signed-off-by: Tomi Valkeinen --- .../fbdev/omap2/omapfb/displays/panel-sharp-ls037v7dw01.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/omapfb/displays/panel-sharp-ls037v7dw01.c index abfd1f6e3327..1954ec913ce5 100644 --- a/drivers/video/fbdev/omap2/omapfb/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-sharp-ls037v7dw01.c @@ -200,20 +200,16 @@ static struct omap_dss_driver sharp_ls_ops = { static int sharp_ls_get_gpio(struct device *dev, int gpio, unsigned long flags, char *desc, struct gpio_desc **gpiod) { - struct gpio_desc *gd; int r; - *gpiod = NULL; - r = devm_gpio_request_one(dev, gpio, flags, desc); - if (r) + if (r) { + *gpiod = NULL; return r == -ENOENT ? 0 : r; + } - gd = gpio_to_desc(gpio); - if (IS_ERR(gd)) - return PTR_ERR(gd) == -ENOENT ? 0 : PTR_ERR(gd); + *gpiod = gpio_to_desc(gpio); - *gpiod = gd; return 0; } -- cgit v1.2.3 From 6e1c7d6103fe7031035cec321307c6356809adf4 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 15 Apr 2016 14:06:57 +0300 Subject: mmc: sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO hangs Baytrail eMMC/SD/SDIO host controllers have been known to hang. A change to a hardware setting has been found to reduce the occurrence of such hangs. This patch ensures the correct setting. This patch applies cleanly to v4.4+. It could go to earlier kernels also, so I will send backports to the stable list in due course. Signed-off-by: Adrian Hunter Cc: stable@vger.kernel.org # v4.4+ Signed-off-by: Ulf Hansson --- drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-acpi.c | 81 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 04feea8354cb..e657af0e95fa 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -97,6 +97,7 @@ config MMC_RICOH_MMC config MMC_SDHCI_ACPI tristate "SDHCI support for ACPI enumerated SDHCI controllers" depends on MMC_SDHCI && ACPI + select IOSF_MBI if X86 help This selects support for ACPI enumerated SDHCI controllers, identified by ACPI Compatibility ID PNP0D40 or specific diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 6839e41c6d58..bed6a494f52c 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c @@ -41,6 +41,11 @@ #include #include +#ifdef CONFIG_X86 +#include +#include +#endif + #include "sdhci.h" enum { @@ -116,6 +121,75 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = { .ops = &sdhci_acpi_ops_int, }; +#ifdef CONFIG_X86 + +static bool sdhci_acpi_byt(void) +{ + static const struct x86_cpu_id byt[] = { + { X86_VENDOR_INTEL, 6, 0x37 }, + {} + }; + + return x86_match_cpu(byt); +} + +#define BYT_IOSF_SCCEP 0x63 +#define BYT_IOSF_OCP_NETCTRL0 0x1078 +#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8) + +static void sdhci_acpi_byt_setting(struct device *dev) +{ + u32 val = 0; + + if (!sdhci_acpi_byt()) + return; + + if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0, + &val)) { + dev_err(dev, "%s read error\n", __func__); + return; + } + + if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE)) + return; + + val &= ~BYT_IOSF_OCP_TIMEOUT_BASE; + + if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0, + val)) { + dev_err(dev, "%s write error\n", __func__); + return; + } + + dev_dbg(dev, "%s completed\n", __func__); +} + +static bool sdhci_acpi_byt_defer(struct device *dev) +{ + if (!sdhci_acpi_byt()) + return false; + + if (!iosf_mbi_available()) + return true; + + sdhci_acpi_byt_setting(dev); + + return false; +} + +#else + +static inline void sdhci_acpi_byt_setting(struct device *dev) +{ +} + +static inline bool sdhci_acpi_byt_defer(struct device *dev) +{ + return false; +} + +#endif + static int bxt_get_cd(struct mmc_host *mmc) { int gpio_cd = mmc_gpio_get_cd(mmc); @@ -322,6 +396,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev) if (acpi_bus_get_status(device) || !device->status.present) return -ENODEV; + if (sdhci_acpi_byt_defer(dev)) + return -EPROBE_DEFER; + hid = acpi_device_hid(device); uid = device->pnp.unique_id; @@ -447,6 +524,8 @@ static int sdhci_acpi_resume(struct device *dev) { struct sdhci_acpi_host *c = dev_get_drvdata(dev); + sdhci_acpi_byt_setting(&c->pdev->dev); + return sdhci_resume_host(c->host); } @@ -470,6 +549,8 @@ static int sdhci_acpi_runtime_resume(struct device *dev) { struct sdhci_acpi_host *c = dev_get_drvdata(dev); + sdhci_acpi_byt_setting(&c->pdev->dev); + return sdhci_runtime_resume_host(c->host); } -- cgit v1.2.3 From 138b8638bb43d4b85eeaacde9be9c687cc7e5de7 Mon Sep 17 00:00:00 2001 From: John Youn Date: Fri, 8 Apr 2016 14:46:31 -0700 Subject: usb: gadget: composite: Clear reserved fields of SSP Dev Cap Set the reserved fields of the SuperSpeed Plus Device Capability descriptor to 0. Otherwise there might be stale data there which will cause USB CV to fail. Fixes: f228a8de242a ("usb: gadget: composite: Return SSP Dev Cap descriptor") Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index de9ffd60fcfa..524e233d48de 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -651,6 +651,8 @@ static int bos_desc(struct usb_composite_dev *cdev) ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1); ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY; ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE; + ssp_cap->bReserved = 0; + ssp_cap->wReserved = 0; /* SSAC = 1 (2 attributes) */ ssp_cap->bmAttributes = cpu_to_le32(1); -- cgit v1.2.3 From 45d49cb706e5d8f0ca5e868118b5d453afbb938f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 11 Apr 2016 17:12:33 +0300 Subject: usb: dwc3: omap: fix up error path on probe() Even if pm_runtime_get*() fails, we *MUST* call pm_runtime_put_sync() before disabling PM. While at it, remove superfluous dwc3_omap_disable_irqs() in error path. Signed-off-by: Felipe Balbi [nsekhar@ti.com: patch description updates] Signed-off-by: Sekhar Nori Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 22e9606d8e08..55da2c7f727f 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -496,7 +496,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "get_sync failed with err %d\n", ret); - goto err0; + goto err1; } dwc3_omap_map_offset(omap); @@ -516,28 +516,24 @@ static int dwc3_omap_probe(struct platform_device *pdev) ret = dwc3_omap_extcon_register(omap); if (ret < 0) - goto err2; + goto err1; ret = of_platform_populate(node, NULL, NULL, dev); if (ret) { dev_err(&pdev->dev, "failed to create dwc3 core\n"); - goto err3; + goto err2; } dwc3_omap_enable_irqs(omap); return 0; -err3: +err2: extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb); extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb); -err2: - dwc3_omap_disable_irqs(omap); err1: pm_runtime_put_sync(dev); - -err0: pm_runtime_disable(dev); return ret; -- cgit v1.2.3 From 5c4ad318de3b8e8680d654c82a254c4b65243739 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 11 Apr 2016 17:12:34 +0300 Subject: usb: dwc3: core: fix PHY handling during suspend we need to power off the PHY during suspend and power it back on during resume. Signed-off-by: Felipe Balbi [nsekhar@ti.com: fix call to usb_phy_set_suspend() in dwc3_suspend()] Signed-off-by: Sekhar Nori Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index fa20f5a99d12..34277ced26bd 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1150,6 +1150,11 @@ static int dwc3_suspend(struct device *dev) phy_exit(dwc->usb2_generic_phy); phy_exit(dwc->usb3_generic_phy); + usb_phy_set_suspend(dwc->usb2_phy, 1); + usb_phy_set_suspend(dwc->usb3_phy, 1); + WARN_ON(phy_power_off(dwc->usb2_generic_phy) < 0); + WARN_ON(phy_power_off(dwc->usb3_generic_phy) < 0); + pinctrl_pm_select_sleep_state(dev); return 0; @@ -1163,11 +1168,21 @@ static int dwc3_resume(struct device *dev) pinctrl_pm_select_default_state(dev); + usb_phy_set_suspend(dwc->usb2_phy, 0); + usb_phy_set_suspend(dwc->usb3_phy, 0); + ret = phy_power_on(dwc->usb2_generic_phy); + if (ret < 0) + return ret; + + ret = phy_power_on(dwc->usb3_generic_phy); + if (ret < 0) + goto err_usb2phy_power; + usb_phy_init(dwc->usb3_phy); usb_phy_init(dwc->usb2_phy); ret = phy_init(dwc->usb2_generic_phy); if (ret < 0) - return ret; + goto err_usb3phy_power; ret = phy_init(dwc->usb3_generic_phy); if (ret < 0) @@ -1200,6 +1215,12 @@ static int dwc3_resume(struct device *dev) err_usb2phy_init: phy_exit(dwc->usb2_generic_phy); +err_usb3phy_power: + phy_power_off(dwc->usb3_generic_phy); + +err_usb2phy_power: + phy_power_off(dwc->usb2_generic_phy); + return ret; } -- cgit v1.2.3 From e6bdf8195b4a43ebff71f25fc7ca5e436e79161a Mon Sep 17 00:00:00 2001 From: "Du, Changbin" Date: Tue, 12 Apr 2016 16:24:34 +0800 Subject: usb: dwc3: fix memory leak of dwc->regset dwc->regset is allocated on dwc3_debugfs_init, and should be released on init failure or dwc3_debugfs_exit. Btw, The line "dwc->root = NULL" is unnecessary, so remove it. Signed-off-by: Du, Changbin [ felipe.balbi@linux.intel.com : add another err label for the new error condition ] Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debugfs.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 9ac37fe1b6a7..cebf9e38b60a 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -645,7 +645,7 @@ int dwc3_debugfs_init(struct dwc3 *dwc) file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset); if (!file) { ret = -ENOMEM; - goto err1; + goto err2; } if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) { @@ -653,7 +653,7 @@ int dwc3_debugfs_init(struct dwc3 *dwc) dwc, &dwc3_mode_fops); if (!file) { ret = -ENOMEM; - goto err1; + goto err2; } } @@ -663,19 +663,22 @@ int dwc3_debugfs_init(struct dwc3 *dwc) dwc, &dwc3_testmode_fops); if (!file) { ret = -ENOMEM; - goto err1; + goto err2; } file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, dwc, &dwc3_link_state_fops); if (!file) { ret = -ENOMEM; - goto err1; + goto err2; } } return 0; +err2: + kfree(dwc->regset); + err1: debugfs_remove_recursive(root); @@ -686,5 +689,5 @@ err0: void dwc3_debugfs_exit(struct dwc3 *dwc) { debugfs_remove_recursive(dwc->root); - dwc->root = NULL; + kfree(dwc->regset); } -- cgit v1.2.3 From 9772b47a4c2916d645c551228b6085ea24acbe5d Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 12 Apr 2016 11:33:29 +0300 Subject: usb: dwc3: gadget: Fix suspend/resume during device mode Gadget controller might not be always active during system suspend/resume as gadget driver might not have yet been loaded or might have been unloaded prior to system suspend. Check if we're active and only then perform necessary actions during suspend/resume. Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index d54a028cdfeb..8e4a1b195e9b 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2936,6 +2936,9 @@ void dwc3_gadget_exit(struct dwc3 *dwc) int dwc3_gadget_suspend(struct dwc3 *dwc) { + if (!dwc->gadget_driver) + return 0; + if (dwc->pullups_connected) { dwc3_gadget_disable_irq(dwc); dwc3_gadget_run_stop(dwc, true, true); @@ -2954,6 +2957,9 @@ int dwc3_gadget_resume(struct dwc3 *dwc) struct dwc3_ep *dep; int ret; + if (!dwc->gadget_driver) + return 0; + /* Start with SuperSpeed Default */ dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); -- cgit v1.2.3 From 9aec6a08f1163fb24c23f9036891e1d5bab3f1be Mon Sep 17 00:00:00 2001 From: "Kumar, Mahesh" Date: Wed, 6 Apr 2016 08:26:39 -0700 Subject: drm/i915/skl+: Use plane size for relative data rate calculation Use plane size for relative data rate calculation. don't always use pipe source width & height. adjust height & width according to rotation. use plane size for watermark calculations also. v2: Address Matt's comments. Use intel_plane_state->visible to avoid divide-by-zero error. Where FB was present but not visible so causing total data rate to be zero, hence divide-by-zero. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93917 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94044 Cc: drm-intel-fixes@lists.freedesktop.org Signed-off-by: Kumar, Mahesh Reviewed-by: Matt Roper Signed-off-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1459956399-1296-1-git-send-email-matthew.d.roper@intel.com (cherry picked from commit a280f7dd9f1a85eed242d0f62498bfc11520a1a3) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_pm.c | 42 +++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 347d4df49a9b..8ed3cf34f82d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2876,25 +2876,28 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, const struct drm_plane_state *pstate, int y) { - struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); + struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); struct drm_framebuffer *fb = pstate->fb; + uint32_t width = 0, height = 0; + + width = drm_rect_width(&intel_pstate->src) >> 16; + height = drm_rect_height(&intel_pstate->src) >> 16; + + if (intel_rotation_90_or_270(pstate->rotation)) + swap(width, height); /* for planar format */ if (fb->pixel_format == DRM_FORMAT_NV12) { if (y) /* y-plane data rate */ - return intel_crtc->config->pipe_src_w * - intel_crtc->config->pipe_src_h * + return width * height * drm_format_plane_cpp(fb->pixel_format, 0); else /* uv-plane data rate */ - return (intel_crtc->config->pipe_src_w/2) * - (intel_crtc->config->pipe_src_h/2) * + return (width / 2) * (height / 2) * drm_format_plane_cpp(fb->pixel_format, 1); } /* for packed formats */ - return intel_crtc->config->pipe_src_w * - intel_crtc->config->pipe_src_h * - drm_format_plane_cpp(fb->pixel_format, 0); + return width * height * drm_format_plane_cpp(fb->pixel_format, 0); } /* @@ -2973,8 +2976,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, struct drm_framebuffer *fb = plane->state->fb; int id = skl_wm_plane_id(intel_plane); - if (fb == NULL) + if (!to_intel_plane_state(plane->state)->visible) continue; + if (plane->type == DRM_PLANE_TYPE_CURSOR) continue; @@ -3000,7 +3004,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, uint16_t plane_blocks, y_plane_blocks = 0; int id = skl_wm_plane_id(intel_plane); - if (pstate->fb == NULL) + if (!to_intel_plane_state(pstate)->visible) continue; if (plane->type == DRM_PLANE_TYPE_CURSOR) continue; @@ -3123,26 +3127,36 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, { struct drm_plane *plane = &intel_plane->base; struct drm_framebuffer *fb = plane->state->fb; + struct intel_plane_state *intel_pstate = + to_intel_plane_state(plane->state); uint32_t latency = dev_priv->wm.skl_latency[level]; uint32_t method1, method2; uint32_t plane_bytes_per_line, plane_blocks_per_line; uint32_t res_blocks, res_lines; uint32_t selected_result; uint8_t cpp; + uint32_t width = 0, height = 0; - if (latency == 0 || !cstate->base.active || !fb) + if (latency == 0 || !cstate->base.active || !intel_pstate->visible) return false; + width = drm_rect_width(&intel_pstate->src) >> 16; + height = drm_rect_height(&intel_pstate->src) >> 16; + + if (intel_rotation_90_or_270(plane->state->rotation)) + swap(width, height); + cpp = drm_format_plane_cpp(fb->pixel_format, 0); method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate), cpp, latency); method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate), cstate->base.adjusted_mode.crtc_htotal, - cstate->pipe_src_w, - cpp, fb->modifier[0], + width, + cpp, + fb->modifier[0], latency); - plane_bytes_per_line = cstate->pipe_src_w * cpp; + plane_bytes_per_line = width * cpp; plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || -- cgit v1.2.3 From d43f3ebf12f59c57782ec652da65ef61c2662b40 Mon Sep 17 00:00:00 2001 From: Akash Goel Date: Fri, 11 Mar 2016 14:56:42 +0530 Subject: drm/i915: Fixup the free space logic in ring_prepare Currently for the case where there is enough space at the end of Ring buffer for accommodating only the base request, the wrapround is done immediately and as a result the base request gets added at the start of Ring buffer. But there may not be enough free space at the beginning to accommodate the base request, as before the wraparound, the wait was effectively done for the reserved_size free space from the start of Ring buffer. In such a case there is a potential of Ring buffer overflow, the instructions at the head of Ring (ACTHD) can get overwritten. Since the base request can fit in the remaining space, there is no need to wraparound immediately. The wraparound will anyway happen later when the reserved part starts getting used. Cc: Chris Wilson Signed-off-by: Akash Goel Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1457688402-10411-1-git-send-email-akash.goel@intel.com Reviewed-by: Chris Wilson Cc: stable@vger.kernel.org (cherry picked from commit 782f6bc0aba037436d6a04d19b23f8b61020a576) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_lrc.c | 6 +++--- drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6a978ce80244..48b612d80784 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -841,11 +841,11 @@ static int logical_ring_prepare(struct drm_i915_gem_request *req, int bytes) if (unlikely(total_bytes > remain_usable)) { /* * The base request will fit but the reserved space - * falls off the end. So only need to to wait for the - * reserved size after flushing out the remainder. + * falls off the end. So don't need an immediate wrap + * and only need to effectively wait for the reserved + * size space from the start of ringbuffer. */ wait_bytes = remain_actual + ringbuf->reserved_size; - need_wrap = true; } else if (total_bytes > ringbuf->space) { /* No wrapping required, just waiting. */ wait_bytes = total_bytes; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 45ce45a5e122..c2ea2cd80d70 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2454,11 +2454,11 @@ static int __intel_ring_prepare(struct intel_engine_cs *ring, int bytes) if (unlikely(total_bytes > remain_usable)) { /* * The base request will fit but the reserved space - * falls off the end. So only need to to wait for the - * reserved size after flushing out the remainder. + * falls off the end. So don't need an immediate wrap + * and only need to effectively wait for the reserved + * size space from the start of ringbuffer. */ wait_bytes = remain_actual + ringbuf->reserved_size; - need_wrap = true; } else if (total_bytes > ringbuf->space) { /* No wrapping required, just waiting. */ wait_bytes = total_bytes; -- cgit v1.2.3 From db9f9203e27495b2d151b695504e286eec026e9b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 Apr 2016 15:00:00 +0100 Subject: drm/i915/userptr: Hold mmref whilst calling get-user-pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Holding a reference to the containing task_struct is not sufficient to prevent the mm_struct from being reaped under memory pressure. If this happens whilst we are calling get_user_pages(), explosions erupt - sometimes an immediate GPF, sometimes page flag corruption. To prevent the target mm from being reaped as we are reading from it, acquire a reference before we begin. Testcase: igt/gem_shrink/*userptr Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Michał Winiarski Cc: stable@vger.kernel.org Reviewed-by: Michał Winiarski Link: http://patchwork.freedesktop.org/patch/msgid/1459864801-28606-2-git-send-email-chris@chris-wilson.co.uk (cherry picked from commit 40313f0cd0b711a7a5905e5182422799e157d8aa) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem_userptr.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 18ba8139e922..4d30b60defda 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -501,19 +501,24 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) if (pvec != NULL) { struct mm_struct *mm = obj->userptr.mm->mm; - down_read(&mm->mmap_sem); - while (pinned < npages) { - ret = get_user_pages_remote(work->task, mm, - obj->userptr.ptr + pinned * PAGE_SIZE, - npages - pinned, - !obj->userptr.read_only, 0, - pvec + pinned, NULL); - if (ret < 0) - break; - - pinned += ret; + ret = -EFAULT; + if (atomic_inc_not_zero(&mm->mm_users)) { + down_read(&mm->mmap_sem); + while (pinned < npages) { + ret = get_user_pages_remote + (work->task, mm, + obj->userptr.ptr + pinned * PAGE_SIZE, + npages - pinned, + !obj->userptr.read_only, 0, + pvec + pinned, NULL); + if (ret < 0) + break; + + pinned += ret; + } + up_read(&mm->mmap_sem); + mmput(mm); } - up_read(&mm->mmap_sem); } mutex_lock(&dev->struct_mutex); -- cgit v1.2.3 From d528a6a0f3fd346bd7cc2de611a4149b6ebaab41 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 5 Apr 2016 15:56:16 +0300 Subject: drm/i915/skl: Fix rc6 based gpu/system hang For all gt3 and gt4 skylake variants, extend the usage of WaRsDisableCoarsePowerGating for all revisions. Without this gt3 and gt4 skylakes up to atleast rev 0xa can gpu hang or system hang. Cc: Abdiel Janulgue Cc: Ben Widawsky Cc: Timo Aaltonen Cc: Reported-by: Mikael Djurfeldt References: https://bugs.freedesktop.org/show_bug.cgi?id=94161 Signed-off-by: Mika Kuoppala Reviewed-by: Ben Widawsky Tested-by: Timo Aaltonen Link: http://patchwork.freedesktop.org/patch/msgid/1459860977-27751-1-git-send-email-mika.kuoppala@intel.com (cherry picked from commit 185c66e57ce725afeb58a3cfa48547706af3a7af) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 10480939159c..daba7ebb9699 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2634,8 +2634,9 @@ struct drm_i915_cmd_table { /* WaRsDisableCoarsePowerGating:skl,bxt */ #define NEEDS_WaRsDisableCoarsePowerGating(dev) (IS_BXT_REVID(dev, 0, BXT_REVID_A1) || \ - ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && \ - IS_SKL_REVID(dev, 0, SKL_REVID_F0))) + IS_SKL_GT3(dev) || \ + IS_SKL_GT4(dev)) + /* * dp aux and gmbus irq on gen4 seems to be able to generate legacy interrupts * even when in MSI mode. This results in spurious interrupt warnings if the -- cgit v1.2.3 From 510650e8b2ab965931b35e9813467439d4df0b9c Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 5 Apr 2016 15:56:17 +0300 Subject: drm/i915/skl: Fix spurious gpu hang with gt3/gt4 revs Experiments with heaven 4.0 benchmark and skylake gt3e (rev 0xa) suggest that WaForceContextSaveRestoreNonCoherent is needed for all revs. Extending this to all revs cures a gpu hang with rev 0xa when running heaven4.0 gpu benchmark. We have been here before, with problems enabling gt4e and extending up to revision F0 instead of false claims of bspec of E0 only. See commit ("drm/i915/skl: Default to noncoherent access up to F0"). In retrospect we should have covered this with this big blanket back then already, as E0 vs F0 discrepancy was suspicious enough. Previously the WaForceEnableNonCoherent has been tied to context non-coherence, atleast in relevant hsds. So keep this tie and extended this alongside. Cc: Abdiel Janulgue Cc: Ben Widawsky Cc: Timo Aaltonen Cc: stable@vger.kernel.org Reported-by: Mike Lothian References: https://bugs.freedesktop.org/show_bug.cgi?id=93491 Signed-off-by: Mika Kuoppala Reviewed-by: Ben Widawsky Tested-by: Timo Aaltonen Link: http://patchwork.freedesktop.org/patch/msgid/1459860977-27751-2-git-send-email-mika.kuoppala@intel.com (cherry picked from commit 97ea6be161c55dec896b65c95157d953c330ae05) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c2ea2cd80d70..bd7321b9bbaf 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -968,7 +968,7 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) /* WaForceContextSaveRestoreNonCoherent:skl,bxt */ tmp = HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT; - if (IS_SKL_REVID(dev, SKL_REVID_F0, SKL_REVID_F0) || + if (IS_SKL_REVID(dev, SKL_REVID_F0, REVID_FOREVER) || IS_BXT_REVID(dev, BXT_REVID_B0, REVID_FOREVER)) tmp |= HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE; WA_SET_BIT_MASKED(HDC_CHICKEN0, tmp); @@ -1085,7 +1085,8 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) WA_SET_BIT_MASKED(HIZ_CHICKEN, BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE); - if (IS_SKL_REVID(dev, 0, SKL_REVID_F0)) { + /* This is tied to WaForceContextSaveRestoreNonCoherent */ + if (IS_SKL_REVID(dev, 0, REVID_FOREVER)) { /* *Use Force Non-Coherent whenever executing a 3D context. This * is a workaround for a possible hang in the unlikely event -- cgit v1.2.3 From 537d3b10086ffae30efbc7c66777c0a08b58d3e6 Mon Sep 17 00:00:00 2001 From: Michał Winiarski Date: Tue, 12 Apr 2016 15:51:55 +0200 Subject: drm/i915: Adjust size of PIPE_CONTROL used for gen8 render seqno write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We started to use PIPE_CONTROL to write render ring seqno in order to combat seqno write vs interrupt generation problems. This was introduced by commit 7c17d377374d ("drm/i915: Use ordered seqno write interrupt generation on gen8+ execlists"). On gen8+ size of PIPE_CONTROL with Post Sync Operation should be 6 dwords. When we're using older 5-dword variant it's possible to observe inconsistent values written by PIPE_CONTROL with Post Sync Operation from user batches, resulting in rendering corruptions. v2: Fix BAT failures v3: Comments on alignment and thrashing high dword of seqno (Chris) v4: Updated commit msg (Mika) Testcase: igt/gem_pipe_control_store_loop/*-qword-write Issue: VIZ-7393 Cc: stable@vger.kernel.org Cc: Chris Wilson Cc: Mika Kuoppala Cc: Abdiel Janulgue Signed-off-by: Michał Winiarski Reviewed-by: Mika Kuoppala Reviewed-by: Chris Wilson Tested-by: Abdiel Janulgue Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1460469115-26002-1-git-send-email-michal.winiarski@intel.com (cherry picked from commit ce81a65c79d6012a384563caf76d47e28947a347) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_lrc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 48b612d80784..5c6080fd0968 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1913,15 +1913,18 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request) struct intel_ringbuffer *ringbuf = request->ringbuf; int ret; - ret = intel_logical_ring_begin(request, 6 + WA_TAIL_DWORDS); + ret = intel_logical_ring_begin(request, 8 + WA_TAIL_DWORDS); if (ret) return ret; + /* We're using qword write, seqno should be aligned to 8 bytes. */ + BUILD_BUG_ON(I915_GEM_HWS_INDEX & 1); + /* w/a for post sync ops following a GPGPU operation we * need a prior CS_STALL, which is emitted by the flush * following the batch. */ - intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(5)); + intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6)); intel_logical_ring_emit(ringbuf, (PIPE_CONTROL_GLOBAL_GTT_IVB | PIPE_CONTROL_CS_STALL | @@ -1929,7 +1932,10 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request) intel_logical_ring_emit(ringbuf, hws_seqno_address(request->ring)); intel_logical_ring_emit(ringbuf, 0); intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request)); + /* We're thrashing one dword of HWS. */ + intel_logical_ring_emit(ringbuf, 0); intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT); + intel_logical_ring_emit(ringbuf, MI_NOOP); return intel_logical_ring_advance_and_submit(request); } -- cgit v1.2.3 From 1b3e885a05d4f0a35dde035724e7c6453d2cbe71 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 13 Apr 2016 17:35:11 +0100 Subject: drm/i915: Force ringbuffers to not be at offset 0 For reasons unknown Sandybridge GT1 (at least) will eventually hang when it encounters a ring wraparound at offset 0. The test case that reproduces the bug reliably forces a large number of interrupted context switches, thereby causing very frequent ring wraparounds, but there are similar bug reports in the wild with the same symptoms, seqno writes stop just before the wrap and the ringbuffer at address 0. It is also timing crucial, but adding various delays hasn't helped pinpoint where the window lies. Whether the fault is restricted to the ringbuffer itself or the GTT addressing is unclear, but moving the ringbuffer fixes all the hangs I have been able to reproduce. References: (e.g.) https://bugs.freedesktop.org/show_bug.cgi?id=93262 Testcase: igt/gem_exec_whisper/render-contexts-interruptible #snb-gt1 Signed-off-by: Chris Wilson Cc: stable@vger.kernel.org Acked-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1460565315-7748-12-git-send-email-chris@chris-wilson.co.uk (cherry picked from commit a687a43a48f0f91ba37dce5a14b467258ed6f035) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ringbuffer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index bd7321b9bbaf..9121646d7c4d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2091,10 +2091,12 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, { struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj = ringbuf->obj; + /* Ring wraparound at offset 0 sometimes hangs. No idea why. */ + unsigned flags = PIN_OFFSET_BIAS | 4096; int ret; if (HAS_LLC(dev_priv) && !obj->stolen) { - ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, 0); + ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, flags); if (ret) return ret; @@ -2110,7 +2112,8 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, return -ENOMEM; } } else { - ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE); + ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, + flags | PIN_MAPPABLE); if (ret) return ret; -- cgit v1.2.3 From 31318a922395ec9e78d6e2ddf70779355afc7594 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 14 Apr 2016 14:39:02 +0300 Subject: drm/i915: Use fw_domains_put_with_fifo() on HSW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HSW still has the wake FIFO, so let's check it. Cc: Mika Kuoppala Cc: Deepak S Fixes: 05a2fb157e44 ("drm/i915: Consolidate forcewake code") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1460633942-24013-1-git-send-email-ville.syrjala@linux.intel.com Cc: stable@vger.kernel.org Reviewed-by: Mika Kuoppala (cherry picked from commit 3d7d0c85e41afb5a05e98b3a8a72c38357f02594) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_uncore.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 436d8f2b8682..68b6f69aa682 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1189,7 +1189,11 @@ static void intel_uncore_fw_domains_init(struct drm_device *dev) } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { dev_priv->uncore.funcs.force_wake_get = fw_domains_get_with_thread_status; - dev_priv->uncore.funcs.force_wake_put = fw_domains_put; + if (IS_HASWELL(dev)) + dev_priv->uncore.funcs.force_wake_put = + fw_domains_put_with_fifo; + else + dev_priv->uncore.funcs.force_wake_put = fw_domains_put; fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, FORCEWAKE_MT, FORCEWAKE_ACK_HSW); } else if (IS_IVYBRIDGE(dev)) { -- cgit v1.2.3 From afecb146d8d8a60a1dde9cdf570c278649617fde Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 18 Apr 2016 11:10:42 +0200 Subject: ALSA: hda/realtek - Add ALC3234 headset mode for Optiplex 9020m The Optiplex 9020m with Haswell-DT processor needs a quirk for the headset jack at the front of the machine to be able to use microphones. A quirk for this model was originally added in 3127899, but c77900e removed it in favour of a more generic version. Unfortunately, pin configurations can changed based on firmware/BIOS versions, and the generic version doesn't have any effect on newer versions of the machine/firmware anymore. With help from David Henningsson Signed-off-by: Bastien Nocera Tested-by: Bastien Nocera Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1402ba954b3d..810bceee4fd2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5449,6 +5449,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13), + SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK), SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), -- cgit v1.2.3 From 6997e57d693b07289694239e52a10d2f02c3a46f Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 15 Apr 2016 12:06:13 +1000 Subject: powerpc: scan_features() updates incorrect bits for REAL_LE The REAL_LE feature entry in the ibm_pa_feature struct is missing an MMU feature value, meaning all the remaining elements initialise the wrong values. This means instead of checking for byte 5, bit 0, we check for byte 0, bit 0, and then we incorrectly set the CPU feature bit as well as MMU feature bit 1 and CPU user feature bits 0 and 2 (5). Checking byte 0 bit 0 (IBM numbering), means we're looking at the "Memory Management Unit (MMU)" feature - ie. does the CPU have an MMU. In practice that bit is set on all platforms which have the property. This means we set CPU_FTR_REAL_LE always. In practice that seems not to matter because all the modern cpus which have this property also implement REAL_LE, and we've never needed to disable it. We're also incorrectly setting MMU feature bit 1, which is: #define MMU_FTR_TYPE_8xx 0x00000002 Luckily the only place that looks for MMU_FTR_TYPE_8xx is in Book3E code, which can't run on the same cpus as scan_features(). So this also doesn't matter in practice. Finally in the CPU user feature mask, we're setting bits 0 and 2. Bit 2 is not currently used, and bit 0 is: #define PPC_FEATURE_PPC_LE 0x00000001 Which says the CPU supports the old style "PPC Little Endian" mode. Again this should be harmless in practice as no 64-bit CPUs implement that mode. Fix the code by adding the missing initialisation of the MMU feature. Also add a comment marking CPU user feature bit 2 (0x4) as reserved. It would be unsafe to start using it as old kernels incorrectly set it. Fixes: 44ae3ab3358e ("powerpc: Free up some CPU feature bits by moving out MMU-related features") Signed-off-by: Anton Blanchard Cc: stable@vger.kernel.org [mpe: Flesh out changelog, add comment reserving 0x4] Signed-off-by: Michael Ellerman --- arch/powerpc/include/uapi/asm/cputable.h | 1 + arch/powerpc/kernel/prom.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/uapi/asm/cputable.h b/arch/powerpc/include/uapi/asm/cputable.h index 8dde19962a5b..f63c96cd3608 100644 --- a/arch/powerpc/include/uapi/asm/cputable.h +++ b/arch/powerpc/include/uapi/asm/cputable.h @@ -31,6 +31,7 @@ #define PPC_FEATURE_PSERIES_PERFMON_COMPAT \ 0x00000040 +/* Reserved - do not use 0x00000004 */ #define PPC_FEATURE_TRUE_LE 0x00000002 #define PPC_FEATURE_PPC_LE 0x00000001 diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 7030b035905d..080c96b44a7f 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -158,7 +158,7 @@ static struct ibm_pa_feature { {CPU_FTR_NOEXECUTE, 0, 0, 0, 6, 0}, {CPU_FTR_NODSISRALIGN, 0, 0, 1, 1, 1}, {0, MMU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, - {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, + {CPU_FTR_REAL_LE, 0, PPC_FEATURE_TRUE_LE, 5, 0, 0}, /* * If the kernel doesn't support TM (ie. CONFIG_PPC_TRANSACTIONAL_MEM=n), * we don't want to turn on CPU_FTR_TM here, so we use CPU_FTR_TM_COMP -- cgit v1.2.3 From beff82374b259d726e2625ec6c518a5f2613f0ae Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 15 Apr 2016 12:07:24 +1000 Subject: powerpc: Update cpu_user_features2 in scan_features() scan_features() updates cpu_user_features but not cpu_user_features2. Amongst other things, cpu_user_features2 contains the user TM feature bits which we must keep in sync with the kernel TM feature bit. Signed-off-by: Anton Blanchard Cc: stable@vger.kernel.org Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/prom.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 080c96b44a7f..03fce77e441d 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -148,23 +148,24 @@ static struct ibm_pa_feature { unsigned long cpu_features; /* CPU_FTR_xxx bit */ unsigned long mmu_features; /* MMU_FTR_xxx bit */ unsigned int cpu_user_ftrs; /* PPC_FEATURE_xxx bit */ + unsigned int cpu_user_ftrs2; /* PPC_FEATURE2_xxx bit */ unsigned char pabyte; /* byte number in ibm,pa-features */ unsigned char pabit; /* bit number (big-endian) */ unsigned char invert; /* if 1, pa bit set => clear feature */ } ibm_pa_features[] __initdata = { - {0, 0, PPC_FEATURE_HAS_MMU, 0, 0, 0}, - {0, 0, PPC_FEATURE_HAS_FPU, 0, 1, 0}, - {CPU_FTR_CTRL, 0, 0, 0, 3, 0}, - {CPU_FTR_NOEXECUTE, 0, 0, 0, 6, 0}, - {CPU_FTR_NODSISRALIGN, 0, 0, 1, 1, 1}, - {0, MMU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, - {CPU_FTR_REAL_LE, 0, PPC_FEATURE_TRUE_LE, 5, 0, 0}, + {0, 0, PPC_FEATURE_HAS_MMU, 0, 0, 0, 0}, + {0, 0, PPC_FEATURE_HAS_FPU, 0, 0, 1, 0}, + {CPU_FTR_CTRL, 0, 0, 0, 0, 3, 0}, + {CPU_FTR_NOEXECUTE, 0, 0, 0, 0, 6, 0}, + {CPU_FTR_NODSISRALIGN, 0, 0, 0, 1, 1, 1}, + {0, MMU_FTR_CI_LARGE_PAGE, 0, 0, 1, 2, 0}, + {CPU_FTR_REAL_LE, 0, PPC_FEATURE_TRUE_LE, 0, 5, 0, 0}, /* * If the kernel doesn't support TM (ie. CONFIG_PPC_TRANSACTIONAL_MEM=n), * we don't want to turn on CPU_FTR_TM here, so we use CPU_FTR_TM_COMP * which is 0 if the kernel doesn't support TM. */ - {CPU_FTR_TM_COMP, 0, 0, 22, 0, 0}, + {CPU_FTR_TM_COMP, 0, 0, 0, 22, 0, 0}, }; static void __init scan_features(unsigned long node, const unsigned char *ftrs, @@ -195,10 +196,12 @@ static void __init scan_features(unsigned long node, const unsigned char *ftrs, if (bit ^ fp->invert) { cur_cpu_spec->cpu_features |= fp->cpu_features; cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs; + cur_cpu_spec->cpu_user_features2 |= fp->cpu_user_ftrs2; cur_cpu_spec->mmu_features |= fp->mmu_features; } else { cur_cpu_spec->cpu_features &= ~fp->cpu_features; cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs; + cur_cpu_spec->cpu_user_features2 &= ~fp->cpu_user_ftrs2; cur_cpu_spec->mmu_features &= ~fp->mmu_features; } } -- cgit v1.2.3 From 4705e02498d6d5a7ab98dfee9595cd5e91db2017 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 15 Apr 2016 12:08:19 +1000 Subject: powerpc: Update TM user feature bits in scan_features() We need to update the user TM feature bits (PPC_FEATURE2_HTM and PPC_FEATURE2_HTM) to mirror what we do with the kernel TM feature bit. At the moment, if firmware reports TM is not available we turn off the kernel TM feature bit but leave the userspace ones on. Userspace thinks it can execute TM instructions and it dies trying. This (together with a QEMU patch) fixes PR KVM, which doesn't currently support TM. Signed-off-by: Anton Blanchard Cc: stable@vger.kernel.org Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/prom.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 03fce77e441d..a15fe1d4e84a 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -161,11 +161,12 @@ static struct ibm_pa_feature { {0, MMU_FTR_CI_LARGE_PAGE, 0, 0, 1, 2, 0}, {CPU_FTR_REAL_LE, 0, PPC_FEATURE_TRUE_LE, 0, 5, 0, 0}, /* - * If the kernel doesn't support TM (ie. CONFIG_PPC_TRANSACTIONAL_MEM=n), - * we don't want to turn on CPU_FTR_TM here, so we use CPU_FTR_TM_COMP - * which is 0 if the kernel doesn't support TM. + * If the kernel doesn't support TM (ie CONFIG_PPC_TRANSACTIONAL_MEM=n), + * we don't want to turn on TM here, so we use the *_COMP versions + * which are 0 if the kernel doesn't support TM. */ - {CPU_FTR_TM_COMP, 0, 0, 0, 22, 0, 0}, + {CPU_FTR_TM_COMP, 0, 0, + PPC_FEATURE2_HTM_COMP|PPC_FEATURE2_HTM_NOSC_COMP, 22, 0, 0}, }; static void __init scan_features(unsigned long node, const unsigned char *ftrs, -- cgit v1.2.3 From 1342e0b7a6c1a060c593037fbac9f4b717f1cb3b Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 18 Apr 2016 13:57:48 +0300 Subject: perf intel-pt: Fix segfault tracing transactions Tracing a workload that uses transactions gave a seg fault as follows: perf record -e intel_pt// workload perf report Program received signal SIGSEGV, Segmentation fault. 0x000000000054b58c in intel_pt_reset_last_branch_rb (ptq=0x1a36110) at util/intel-pt.c:929 929 ptq->last_branch_rb->nr = 0; (gdb) p ptq->last_branch_rb $1 = (struct branch_stack *) 0x0 (gdb) up 1148 intel_pt_reset_last_branch_rb(ptq); (gdb) l 1143 if (ret) 1144 pr_err("Intel Processor Trace: failed to deliver transaction event 1145 ret); 1146 1147 if (pt->synth_opts.callchain) 1148 intel_pt_reset_last_branch_rb(ptq); 1149 1150 return ret; 1151 } 1152 (gdb) p pt->synth_opts.callchain $2 = true (gdb) (gdb) bt #0 0x000000000054b58c in intel_pt_reset_last_branch_rb (ptq=0x1a36110) #1 0x000000000054c1e0 in intel_pt_synth_transaction_sample (ptq=0x1a36110) #2 0x000000000054c5b2 in intel_pt_sample (ptq=0x1a36110) Caused by checking the 'callchain' flag when it should have been the 'last_branch' flag. Fix that. Reported-by: Andi Kleen Signed-off-by: Adrian Hunter Cc: Jiri Olsa Cc: stable@vger.kernel.org # v4.4+ Fixes: f14445ee72c5 ("perf intel-pt: Support generating branch stack") Link: http://lkml.kernel.org/r/1460977068-11566-1-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/intel-pt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 407f11b97c8d..617578440989 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -1130,7 +1130,7 @@ static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq) pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n", ret); - if (pt->synth_opts.callchain) + if (pt->synth_opts.last_branch) intel_pt_reset_last_branch_rb(ptq); return ret; -- cgit v1.2.3 From fe0d36e03a08a6f88e5cb9f81c3b819f797e8024 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Apr 2016 13:16:35 -0400 Subject: drm/radeon: print pci revision as well as pci ids on driver load The pci revision id is useful in debugging certain things as it's part of how SKUs are defined on newer asics. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 4fd1a961012d..193261fee6e1 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1305,9 +1305,9 @@ int radeon_device_init(struct radeon_device *rdev, } rdev->fence_context = fence_context_alloc(RADEON_NUM_RINGS); - DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", - radeon_family_name[rdev->family], pdev->vendor, pdev->device, - pdev->subsystem_vendor, pdev->subsystem_device); + DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n", + radeon_family_name[rdev->family], pdev->vendor, pdev->device, + pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision); /* mutex initialization are all done here so we * can recall function without having locking issues */ -- cgit v1.2.3 From bcb31eba4a4ea356fd61cbd5dec5511c3883f57e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Apr 2016 14:15:16 -0400 Subject: drm/radeon: add a quirk for a XFX R9 270X bug: https://bugs.freedesktop.org/show_bug.cgi?id=76490 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/si_dpm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index af4df81c4e0c..e6abc09b67e3 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -2931,6 +2931,7 @@ static struct si_dpm_quirk si_dpm_quirk_list[] = { { PCI_VENDOR_ID_ATI, 0x6811, 0x1462, 0x2015, 0, 120000 }, { PCI_VENDOR_ID_ATI, 0x6811, 0x1043, 0x2015, 0, 120000 }, { PCI_VENDOR_ID_ATI, 0x6811, 0x148c, 0x2015, 0, 120000 }, + { PCI_VENDOR_ID_ATI, 0x6810, 0x1682, 0x9275, 0, 120000 }, { 0, 0, 0, 0 }, }; -- cgit v1.2.3 From 8f99455587855a5f79af08e40327ca40ab5f1999 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 13 Apr 2016 23:37:42 -0400 Subject: drm/amdgpu/acp: fix resume on CZ systems with AZ audio Nothing to do on resume on systems with AZ audio. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index d6b0bff510aa..b7b583c42ea8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -425,6 +425,10 @@ static int acp_resume(void *handle) struct acp_pm_domain *apd; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + /* return early if no ACP */ + if (!adev->acp.acp_genpd) + return 0; + /* SMU block will power on ACP irrespective of ACP runtime status. * Power off explicitly based on genpd ACP runtime status so that ACP * hw and ACP-genpd status are in sync. -- cgit v1.2.3 From bfaddd9fc8ac048b99475f000dbef6f08297417f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 18 Apr 2016 11:19:19 -0400 Subject: Revert "drm/radeon: disable runtime pm on PX laptops without dGPU power control" This reverts commit e64c952efb8e0c15ae82cec8e455ab4910690ef1. ATPX is the ACPI method for controlling AMD PowerXpress laptops. There are flags to indicate which methods are supported. If the dGPU power down flag is not supported, the driver needs to implement the dGPU power down manually. We had previously always forced the driver to assume the ATPX dGPU power down was present, but this causes problems on boards where it is not, leading to GPU hangs when attempting to power down the dGPU. Manual dGPU power down is not currently supported in the Linux driver. Some laptops indicate that the ATPX dGPU power down method is not present, but it actually apparently is. I'm not sure if this is a bios bug and it should be set or if there is a reason it was unset and the method should not be used. This is not an issue on other OSes since both the ATPX and the manual driver power down methods are supported. This is apparently fairly widespread, so just revert for now. bugs: https://bugzilla.kernel.org/show_bug.cgi?id=115321 https://bugzilla.kernel.org/show_bug.cgi?id=116581 https://bugzilla.kernel.org/show_bug.cgi?id=116251 Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_atpx_handler.c | 8 ++++---- drivers/gpu/drm/radeon/radeon_device.c | 8 +------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index fd8c4d317e60..56482e35d43e 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -62,10 +62,6 @@ bool radeon_has_atpx(void) { return radeon_atpx_priv.atpx_detected; } -bool radeon_has_atpx_dgpu_power_cntl(void) { - return radeon_atpx_priv.atpx.functions.power_cntl; -} - /** * radeon_atpx_call - call an ATPX method * @@ -145,6 +141,10 @@ static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mas */ static int radeon_atpx_validate(struct radeon_atpx *atpx) { + /* make sure required functions are enabled */ + /* dGPU power control is required */ + atpx->functions.power_cntl = true; + if (atpx->functions.px_params) { union acpi_object *info; struct atpx_px_params output; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 193261fee6e1..d0826fb0434c 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -103,12 +103,6 @@ static const char radeon_family_name[][16] = { "LAST", }; -#if defined(CONFIG_VGA_SWITCHEROO) -bool radeon_has_atpx_dgpu_power_cntl(void); -#else -static inline bool radeon_has_atpx_dgpu_power_cntl(void) { return false; } -#endif - #define RADEON_PX_QUIRK_DISABLE_PX (1 << 0) #define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1) @@ -1439,7 +1433,7 @@ int radeon_device_init(struct radeon_device *rdev, * ignore it */ vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); - if ((rdev->flags & RADEON_IS_PX) && radeon_has_atpx_dgpu_power_cntl()) + if (rdev->flags & RADEON_IS_PX) runtime = true; vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime); if (runtime) -- cgit v1.2.3 From adb4907007445ab9d392f4ce398cd7fa5d26612b Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 15 Apr 2016 12:11:21 +0200 Subject: arm64: fix invalidation of wrong __early_cpu_boot_status cacheline In head.S, the str_l macro, which takes a source register, a symbol name and a temp register, is used to store a status value to the variable __early_cpu_boot_status. Subsequently, the value of the temp register is reused to invalidate any cachelines covering this variable. However, since str_l resolves to adrp \tmp, \sym str \src, [\tmp, :lo12:\sym] the temp register never actually holds the address of the variable but only of the 4 KB window that covers it, and reusing it leads to the wrong cacheline being invalidated. So instead, take the address explicitly before doing the store, and reuse that value to perform the cache invalidation. Fixes: bb9052744f4b ("arm64: Handle early CPU boot failures") Signed-off-by: Ard Biesheuvel Acked-by: Mark Rutland Acked-by: Suzuki K Poulose Signed-off-by: Catalin Marinas --- arch/arm64/kernel/head.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 4203d5f257bc..80a709aa211a 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -734,7 +734,8 @@ ENDPROC(__secondary_switched) .macro update_early_cpu_boot_status status, tmp1, tmp2 mov \tmp2, #\status - str_l \tmp2, __early_cpu_boot_status, \tmp1 + adr_l \tmp1, __early_cpu_boot_status + str \tmp2, [\tmp1] dmb sy dc ivac, \tmp1 // Invalidate potentially stale cache line .endm -- cgit v1.2.3 From dfc4f59d901bf72f93280b7c142c8ad846359c6f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 18 Apr 2016 11:26:26 -0400 Subject: drm/radeon: print a message if ATPX dGPU power control is missing It will help identify problematic boards. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_atpx_handler.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 56482e35d43e..95f4fea89302 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -143,7 +143,10 @@ static int radeon_atpx_validate(struct radeon_atpx *atpx) { /* make sure required functions are enabled */ /* dGPU power control is required */ - atpx->functions.power_cntl = true; + if (atpx->functions.power_cntl == false) { + printk("ATPX dGPU power cntl not present, forcing\n"); + atpx->functions.power_cntl = true; + } if (atpx->functions.px_params) { union acpi_object *info; -- cgit v1.2.3 From 8e6cb470bac6b1e7afa4642a40a71f9bcd066242 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 18 Apr 2016 18:30:05 +0200 Subject: iio:adc:at91-sama5d2: Repair crash on module removal The driver never calls platform_set_drvdata() , so platform_get_drvdata() in .remove returns NULL and thus $indio_dev variable in .remove is NULL. Then it's only a matter of dereferencing the indio_dev variable to make the kernel blow as seen below. This patch adds the platform_set_drvdata() call to fix the problem. root@armhf:~# rmmod at91-sama5d2_adc Unable to handle kernel NULL pointer dereference at virtual address 000001d4 pgd = dd57c000 [000001d4] *pgd=00000000 Internal error: Oops: 5 [#1] ARM Modules linked in: at91_sama5d2_adc(-) CPU: 0 PID: 1334 Comm: rmmod Not tainted 4.6.0-rc3-next-20160418+ #3 Hardware name: Atmel SAMA5 task: dd4fcc40 ti: de910000 task.ti: de910000 PC is at mutex_lock+0x4/0x24 LR is at iio_device_unregister+0x14/0x6c pc : [] lr : [] psr: a00d0013 sp : de911f00 ip : 00000000 fp : be898bd8 r10: 00000000 r9 : de910000 r8 : c0107724 r7 : 00000081 r6 : bf001048 r5 : 000001d4 r4 : 00000000 r3 : bf000000 r2 : 00000000 r1 : 00000004 r0 : 000001d4 Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 10c53c7d Table: 3d57c059 DAC: 00000051 Process rmmod (pid: 1334, stack limit = 0xde910208) Stack: (0xde911f00 to 0xde912000) 1f00: bf000000 00000000 df5c7e10 bf000010 bf000000 df5c7e10 df5c7e10 c0351ca8 1f20: c0351c84 df5c7e10 bf001048 c0350734 bf001048 df5c7e10 df5c7e44 c035087c 1f40: bf001048 7f62dd4c 00000800 c034fb30 bf0010c0 c0158ee8 de910000 31397461 1f60: 6d61735f 32643561 6364615f 00000000 de911f90 de910000 de910000 00000000 1f80: de911fb0 10c53c7d de911f9c c05f33d8 de911fa0 00910000 be898ecb 7f62dd10 1fa0: 00000000 c0107560 be898ecb 7f62dd10 7f62dd4c 00000800 6f844800 6f844800 1fc0: be898ecb 7f62dd10 00000000 00000081 00000000 7f62dd10 be898bd8 be898bd8 1fe0: b6eedab1 be898b6c 7f61056b b6eedab6 000d0030 7f62dd4c 00000000 00000000 [] (mutex_lock) from [] (iio_device_unregister+0x14/0x6c) [] (iio_device_unregister) from [] (at91_adc_remove+0x10/0x3c [at91_sama5d2_adc]) [] (at91_adc_remove [at91_sama5d2_adc]) from [] (platform_drv_remove+0x24/0x3c) [] (platform_drv_remove) from [] (__device_release_driver+0x84/0x110) [] (__device_release_driver) from [] (driver_detach+0x8c/0x90) [] (driver_detach) from [] (bus_remove_driver+0x4c/0xa0) [] (bus_remove_driver) from [] (SyS_delete_module+0x110/0x1d0) [] (SyS_delete_module) from [] (ret_fast_syscall+0x0/0x3c) Code: e3520001 1affffd5 eafffff4 f5d0f000 (e1902f9f) ---[ end trace 86914d7ad3696fca ]--- Signed-off-by: Marek Vasut Cc: Ludovic Desroches Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91-sama5d2_adc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index dbee13ad33a3..2e154cb51685 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -451,6 +451,8 @@ static int at91_adc_probe(struct platform_device *pdev) if (ret) goto vref_disable; + platform_set_drvdata(pdev, indio_dev); + ret = iio_device_register(indio_dev); if (ret < 0) goto per_clk_disable_unprepare; -- cgit v1.2.3 From 67245ff332064c01b760afa7a384ccda024bfd24 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 16 Apr 2016 15:16:07 -0700 Subject: devpts: clean up interface to pty drivers This gets rid of the horrible notion of having that struct inode *ptmx_inode be the linchpin of the interface between the pty code and devpts. By de-emphasizing the ptmx inode, a lot of things actually get cleaner, and we will have a much saner way forward. In particular, this will allow us to associate with any particular devpts instance at open-time, and not be artificially tied to one particular ptmx inode. The patch itself is actually fairly straightforward, and apart from some locking and return path cleanups it's pretty mechanical: - the interfaces that devpts exposes all take "struct pts_fs_info *" instead of "struct inode *ptmx_inode" now. NOTE! The "struct pts_fs_info" thing is a completely opaque structure as far as the pty driver is concerned: it's still declared entirely internally to devpts. So the pty code can't actually access it in any way, just pass it as a "cookie" to the devpts code. - the "look up the pts fs info" is now a single clear operation, that also does the reference count increment on the pts superblock. So "devpts_add/del_ref()" is gone, and replaced by a "lookup and get ref" operation (devpts_get_ref(inode)), along with a "put ref" op (devpts_put_ref()). - the pty master "tty->driver_data" field now contains the pts_fs_info, not the ptmx inode. - because we don't care about the ptmx inode any more as some kind of base index, the ref counting can now drop the inode games - it just gets the ref on the superblock. - the pts_fs_info now has a back-pointer to the super_block. That's so that we can easily look up the information we actually need. Although quite often, the pts fs info was actually all we wanted, and not having to look it up based on some magical inode makes things more straightforward. In particular, now that "devpts_get_ref(inode)" operation should really be the *only* place we need to look up what devpts instance we're associated with, and we do it exactly once, at ptmx_open() time. The other side of this is that one ptmx node could now be associated with multiple different devpts instances - you could have a single /dev/ptmx node, and then have multiple mount namespaces with their own instances of devpts mounted on /dev/pts/. And that's all perfectly sane in a model where we just look up the pts instance at open time. This will eventually allow us to get rid of our odd single-vs-multiple pts instance model, but this patch in itself changes no semantics, only an internal binding model. Cc: Eric Biederman Cc: Peter Anvin Cc: Andy Lutomirski Cc: Al Viro Cc: Peter Hurley Cc: Serge Hallyn Cc: Willy Tarreau Cc: Aurelien Jarno Cc: Alan Cox Cc: Jann Horn Cc: Greg KH Cc: Jiri Slaby Cc: Florian Weimer Signed-off-by: Linus Torvalds --- drivers/tty/pty.c | 63 ++++++++++++++++++++++------------------------- fs/devpts/inode.c | 49 ++++++++++++++++++------------------ include/linux/devpts_fs.h | 34 ++++++++----------------- 3 files changed, 64 insertions(+), 82 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index e16a49b507ef..0058d9fbf931 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -663,14 +663,14 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) /* this is called once with whichever end is closed last */ static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) { - struct inode *ptmx_inode; + struct pts_fs_info *fsi; if (tty->driver->subtype == PTY_TYPE_MASTER) - ptmx_inode = tty->driver_data; + fsi = tty->driver_data; else - ptmx_inode = tty->link->driver_data; - devpts_kill_index(ptmx_inode, tty->index); - devpts_del_ref(ptmx_inode); + fsi = tty->link->driver_data; + devpts_kill_index(fsi, tty->index); + devpts_put_ref(fsi); } static const struct tty_operations ptm_unix98_ops = { @@ -720,6 +720,7 @@ static const struct tty_operations pty_unix98_ops = { static int ptmx_open(struct inode *inode, struct file *filp) { + struct pts_fs_info *fsi; struct tty_struct *tty; struct inode *slave_inode; int retval; @@ -734,47 +735,41 @@ static int ptmx_open(struct inode *inode, struct file *filp) if (retval) return retval; + fsi = devpts_get_ref(inode, filp); + retval = -ENODEV; + if (!fsi) + goto out_free_file; + /* find a device that is not in use. */ mutex_lock(&devpts_mutex); - index = devpts_new_index(inode); - if (index < 0) { - retval = index; - mutex_unlock(&devpts_mutex); - goto err_file; - } - + index = devpts_new_index(fsi); mutex_unlock(&devpts_mutex); - mutex_lock(&tty_mutex); - tty = tty_init_dev(ptm_driver, index); + retval = index; + if (index < 0) + goto out_put_ref; - if (IS_ERR(tty)) { - retval = PTR_ERR(tty); - goto out; - } + mutex_lock(&tty_mutex); + tty = tty_init_dev(ptm_driver, index); /* The tty returned here is locked so we can safely drop the mutex */ mutex_unlock(&tty_mutex); - set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ - tty->driver_data = inode; + retval = PTR_ERR(tty); + if (IS_ERR(tty)) + goto out; /* - * In the case where all references to ptmx inode are dropped and we - * still have /dev/tty opened pointing to the master/slave pair (ptmx - * is closed/released before /dev/tty), we must make sure that the inode - * is still valid when we call the final pty_unix98_shutdown, thus we - * hold an additional reference to the ptmx inode. For the same /dev/tty - * last close case, we also need to make sure the super_block isn't - * destroyed (devpts instance unmounted), before /dev/tty is closed and - * on its release devpts_kill_index is called. + * From here on out, the tty is "live", and the index and + * fsi will be killed/put by the tty_release() */ - devpts_add_ref(inode); + set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ + tty->driver_data = fsi; tty_add_file(tty, filp); - slave_inode = devpts_pty_new(inode, + slave_inode = devpts_pty_new(fsi, MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index, tty->link); if (IS_ERR(slave_inode)) { @@ -793,12 +788,14 @@ static int ptmx_open(struct inode *inode, struct file *filp) return 0; err_release: tty_unlock(tty); + // This will also put-ref the fsi tty_release(inode, filp); return retval; out: - mutex_unlock(&tty_mutex); - devpts_kill_index(inode, index); -err_file: + devpts_kill_index(fsi, index); +out_put_ref: + devpts_put_ref(fsi); +out_free_file: tty_free_file(filp); return retval; } diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 655f21f99160..0af8e7d70d27 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -128,6 +128,7 @@ static const match_table_t tokens = { struct pts_fs_info { struct ida allocated_ptys; struct pts_mount_opts mount_opts; + struct super_block *sb; struct dentry *ptmx_dentry; }; @@ -358,7 +359,7 @@ static const struct super_operations devpts_sops = { .show_options = devpts_show_options, }; -static void *new_pts_fs_info(void) +static void *new_pts_fs_info(struct super_block *sb) { struct pts_fs_info *fsi; @@ -369,6 +370,7 @@ static void *new_pts_fs_info(void) ida_init(&fsi->allocated_ptys); fsi->mount_opts.mode = DEVPTS_DEFAULT_MODE; fsi->mount_opts.ptmxmode = DEVPTS_DEFAULT_PTMX_MODE; + fsi->sb = sb; return fsi; } @@ -384,7 +386,7 @@ devpts_fill_super(struct super_block *s, void *data, int silent) s->s_op = &devpts_sops; s->s_time_gran = 1; - s->s_fs_info = new_pts_fs_info(); + s->s_fs_info = new_pts_fs_info(s); if (!s->s_fs_info) goto fail; @@ -524,17 +526,14 @@ static struct file_system_type devpts_fs_type = { * to the System V naming convention */ -int devpts_new_index(struct inode *ptmx_inode) +int devpts_new_index(struct pts_fs_info *fsi) { - struct super_block *sb = pts_sb_from_inode(ptmx_inode); - struct pts_fs_info *fsi; int index; int ida_ret; - if (!sb) + if (!fsi) return -ENODEV; - fsi = DEVPTS_SB(sb); retry: if (!ida_pre_get(&fsi->allocated_ptys, GFP_KERNEL)) return -ENOMEM; @@ -564,11 +563,8 @@ retry: return index; } -void devpts_kill_index(struct inode *ptmx_inode, int idx) +void devpts_kill_index(struct pts_fs_info *fsi, int idx) { - struct super_block *sb = pts_sb_from_inode(ptmx_inode); - struct pts_fs_info *fsi = DEVPTS_SB(sb); - mutex_lock(&allocated_ptys_lock); ida_remove(&fsi->allocated_ptys, idx); pty_count--; @@ -578,21 +574,25 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx) /* * pty code needs to hold extra references in case of last /dev/tty close */ - -void devpts_add_ref(struct inode *ptmx_inode) +struct pts_fs_info *devpts_get_ref(struct inode *ptmx_inode, struct file *file) { - struct super_block *sb = pts_sb_from_inode(ptmx_inode); + struct super_block *sb; + struct pts_fs_info *fsi; + + sb = pts_sb_from_inode(ptmx_inode); + if (!sb) + return NULL; + fsi = DEVPTS_SB(sb); + if (!fsi) + return NULL; atomic_inc(&sb->s_active); - ihold(ptmx_inode); + return fsi; } -void devpts_del_ref(struct inode *ptmx_inode) +void devpts_put_ref(struct pts_fs_info *fsi) { - struct super_block *sb = pts_sb_from_inode(ptmx_inode); - - iput(ptmx_inode); - deactivate_super(sb); + deactivate_super(fsi->sb); } /** @@ -604,22 +604,21 @@ void devpts_del_ref(struct inode *ptmx_inode) * * The created inode is returned. Remove it from /dev/pts/ by devpts_pty_kill. */ -struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, +struct inode *devpts_pty_new(struct pts_fs_info *fsi, dev_t device, int index, void *priv) { struct dentry *dentry; - struct super_block *sb = pts_sb_from_inode(ptmx_inode); + struct super_block *sb; struct inode *inode; struct dentry *root; - struct pts_fs_info *fsi; struct pts_mount_opts *opts; char s[12]; - if (!sb) + if (!fsi) return ERR_PTR(-ENODEV); + sb = fsi->sb; root = sb->s_root; - fsi = DEVPTS_SB(sb); opts = &fsi->mount_opts; inode = new_inode(sb); diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h index e0ee0b3000b2..358a4db72a27 100644 --- a/include/linux/devpts_fs.h +++ b/include/linux/devpts_fs.h @@ -15,38 +15,24 @@ #include +struct pts_fs_info; + #ifdef CONFIG_UNIX98_PTYS -int devpts_new_index(struct inode *ptmx_inode); -void devpts_kill_index(struct inode *ptmx_inode, int idx); -void devpts_add_ref(struct inode *ptmx_inode); -void devpts_del_ref(struct inode *ptmx_inode); +/* Look up a pts fs info and get a ref to it */ +struct pts_fs_info *devpts_get_ref(struct inode *, struct file *); +void devpts_put_ref(struct pts_fs_info *); + +int devpts_new_index(struct pts_fs_info *); +void devpts_kill_index(struct pts_fs_info *, int); + /* mknod in devpts */ -struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, - void *priv); +struct inode *devpts_pty_new(struct pts_fs_info *, dev_t, int, void *); /* get private structure */ void *devpts_get_priv(struct inode *pts_inode); /* unlink */ void devpts_pty_kill(struct inode *inode); -#else - -/* Dummy stubs in the no-pty case */ -static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; } -static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { } -static inline void devpts_add_ref(struct inode *ptmx_inode) { } -static inline void devpts_del_ref(struct inode *ptmx_inode) { } -static inline struct inode *devpts_pty_new(struct inode *ptmx_inode, - dev_t device, int index, void *priv) -{ - return ERR_PTR(-EINVAL); -} -static inline void *devpts_get_priv(struct inode *pts_inode) -{ - return NULL; -} -static inline void devpts_pty_kill(struct inode *inode) { } - #endif -- cgit v1.2.3 From c9d9c929e6741118776eb0f385339d3c2b84d5f8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 10 Apr 2016 05:59:33 +0200 Subject: cpufreq: Abort cpufreq_update_current_freq() for cpufreq_suspended set Since governor operations are generally skipped if cpufreq_suspended is set, cpufreq_start_governor() should do nothing in that case. That function is called in the cpufreq_online() path, and may also be called from cpufreq_offline() in some cases, which are invoked by the nonboot CPUs disabing/enabling code during system suspend to RAM and resume. That happens when all devices have been suspended, so if the cpufreq driver relies on things like I2C to get the current frequency, it may not be ready to do that then. To prevent problems from happening for this reason, make cpufreq_update_current_freq(), which is the only function invoked by cpufreq_start_governor() that doesn't check cpufreq_suspended already, return 0 upfront if cpufreq_suspended is set. Fixes: 3bbf8fe3ae08 (cpufreq: Always update current frequency before startig governor) Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index b87596b591b3..e93405f0eac4 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1491,6 +1491,9 @@ static unsigned int cpufreq_update_current_freq(struct cpufreq_policy *policy) { unsigned int new_freq; + if (cpufreq_suspended) + return 0; + new_freq = cpufreq_driver->get(policy->cpu); if (!new_freq) return 0; -- cgit v1.2.3 From 9220ebffda4aa23fe683c9ca6c94fb72d7c131c2 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Mon, 11 Apr 2016 20:23:31 +0530 Subject: Revert "serial-uartlite: Constify uartlite_be/uartlite_le" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 2905697a82eaf20606ced164d853b52d1b94aaa8. The commit introduced two build warnings: drivers/tty/serial/uartlite.c: In function ‘ulite_request_port’: drivers/tty/serial/uartlite.c:348:21: warning: assignment discards ‘const’ qualifier from pointer target type port->private_data = &uartlite_be; ^ drivers/tty/serial/uartlite.c:354:22: warning: assignment discards ‘const’ qualifier from pointer target type port->private_data = &uartlite_le; ^ Signed-off-by: Sudip Mukherjee Cc: Maarten Brock Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/uartlite.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index c9fdfc8bf47f..d08baa668d5d 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -72,7 +72,7 @@ static void uartlite_outbe32(u32 val, void __iomem *addr) iowrite32be(val, addr); } -static const struct uartlite_reg_ops uartlite_be = { +static struct uartlite_reg_ops uartlite_be = { .in = uartlite_inbe32, .out = uartlite_outbe32, }; @@ -87,21 +87,21 @@ static void uartlite_outle32(u32 val, void __iomem *addr) iowrite32(val, addr); } -static const struct uartlite_reg_ops uartlite_le = { +static struct uartlite_reg_ops uartlite_le = { .in = uartlite_inle32, .out = uartlite_outle32, }; static inline u32 uart_in32(u32 offset, struct uart_port *port) { - const struct uartlite_reg_ops *reg_ops = port->private_data; + struct uartlite_reg_ops *reg_ops = port->private_data; return reg_ops->in(port->membase + offset); } static inline void uart_out32(u32 val, u32 offset, struct uart_port *port) { - const struct uartlite_reg_ops *reg_ops = port->private_data; + struct uartlite_reg_ops *reg_ops = port->private_data; reg_ops->out(val, port->membase + offset); } -- cgit v1.2.3 From 0c66940d584d1aac92f6a78460dc0ba2efd3b7ba Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Thu, 24 Mar 2016 09:03:45 +0100 Subject: tty/serial/8250: fix RS485 half-duplex RX When in half-duplex mode RX will be disabled before TX, but not enabled after deactivating transmitter. This patch enables UART_IER_RLSI and UART_IER_RDI interrupts after TX is over. Cc: Matwey V. Kornilov Signed-off-by: Yegor Yefremov Fixes: e490c9144cfa ("tty: Add software emulated RS485 support for 8250") Acked-by: Matwey V. Kornilov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index e213da01a3d7..00ad2637b08c 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1403,9 +1403,18 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p) /* * Empty the RX FIFO, we are not interested in anything * received during the half-duplex transmission. + * Enable previously disabled RX interrupts. */ - if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) + if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) { serial8250_clear_fifos(p); + + serial8250_rpm_get(p); + + p->ier |= UART_IER_RLSI | UART_IER_RDI; + serial_port_out(&p->port, UART_IER, p->ier); + + serial8250_rpm_put(p); + } } static void serial8250_em485_handle_stop_tx(unsigned long arg) -- cgit v1.2.3 From f077b73682910bc7dc9439e50e7b1ad97f28f3f1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 19 Apr 2016 15:17:37 +0900 Subject: Revert "serial: 8250: Add hardware dependency to RT288X option" This reverts commit 8d2acdb9fc3a544ab0442634531834d6007b5467. It's causing problems, and somehow I missed that Peter didn't like it at all :( So revert it for now until it gets sorted out. Reported-by: Mason Cc: Peter Hurley Cc: Jean Delvare Cc: Mans Rullgard Cc: Jiri Slaby Cc: John Crispin Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/8250/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 64742a086ae3..4d7cb9c04fce 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -324,7 +324,6 @@ config SERIAL_8250_EM config SERIAL_8250_RT288X bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support" depends on SERIAL_8250 - depends on MIPS || COMPILE_TEST default y if MIPS_ALCHEMY || SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 help Selecting this option will add support for the alternate register -- cgit v1.2.3 From 6687659568e2ec5b3ac24b39c5d26ce8b9d90434 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Sun, 17 Apr 2016 23:31:41 -0700 Subject: locking/pvqspinlock: Fix division by zero in qstat_read() While playing with the qstat statistics (in /qlockstat/) I ran into the following splat on a VM when opening pv_hash_hops: divide error: 0000 [#1] SMP ... RIP: 0010:[] [] qstat_read+0x12e/0x1e0 ... Call Trace: [] ? mem_cgroup_commit_charge+0x6c/0xd0 [] ? page_add_new_anon_rmap+0x8c/0xd0 [] ? handle_mm_fault+0x1439/0x1b40 [] ? do_mmap+0x449/0x550 [] ? __vfs_read+0x23/0xd0 [] ? rw_verify_area+0x52/0xd0 [] ? vfs_read+0x81/0x120 [] ? SyS_read+0x42/0xa0 [] ? entry_SYSCALL_64_fastpath+0x1e/0xa8 Fix this by verifying that qstat_pv_kick_unlock is in fact non-zero, similarly to what the qstat_pv_latency_wake case does, as if nothing else, this can come from resetting the statistics, thus having 0 kicks should be quite valid in this context. Signed-off-by: Davidlohr Bueso Reviewed-by: Waiman Long Cc: Andrew Morton Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: dave@stgolabs.net Cc: waiman.long@hpe.com Link: http://lkml.kernel.org/r/1460961103-24953-1-git-send-email-dave@stgolabs.net Signed-off-by: Ingo Molnar --- kernel/locking/qspinlock_stat.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/locking/qspinlock_stat.h b/kernel/locking/qspinlock_stat.h index eb2a2c9bc3fc..d734b7502001 100644 --- a/kernel/locking/qspinlock_stat.h +++ b/kernel/locking/qspinlock_stat.h @@ -136,10 +136,12 @@ static ssize_t qstat_read(struct file *file, char __user *user_buf, } if (counter == qstat_pv_hash_hops) { - u64 frac; + u64 frac = 0; - frac = 100ULL * do_div(stat, kicks); - frac = DIV_ROUND_CLOSEST_ULL(frac, kicks); + if (kicks) { + frac = 100ULL * do_div(stat, kicks); + frac = DIV_ROUND_CLOSEST_ULL(frac, kicks); + } /* * Return a X.XX decimal number -- cgit v1.2.3 From 3d51ae172d759198b2e47e104c31a92d20d17927 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 19 Apr 2016 08:01:05 -0700 Subject: Revert "ARM: OMAP: Catch callers of revision information prior to it being populated" This reverts commit 571afb4c8a4bbe88541364e7f6827340562f2736. --- arch/arm/mach-omap1/id.c | 1 - arch/arm/mach-omap2/id.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c index bfabc065d331..52de382fc804 100644 --- a/arch/arm/mach-omap1/id.c +++ b/arch/arm/mach-omap1/id.c @@ -65,7 +65,6 @@ static struct omap_id omap_ids[] __initdata = { unsigned int omap_rev(void) { - WARN_ON_ONCE(!omap_revision || omap_revision == -1); return omap_revision; } EXPORT_SYMBOL(omap_rev); diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 75fb6c006e86..d85c24918c17 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -46,7 +46,6 @@ u32 omap_features; unsigned int omap_rev(void) { - WARN_ON_ONCE(!omap_revision || omap_revision == -1); return omap_revision; } EXPORT_SYMBOL(omap_rev); -- cgit v1.2.3 From 52dee2c9f0850704327d976ea5c5fa7f4696dab5 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Mon, 18 Apr 2016 14:46:30 -0700 Subject: Input: twl6040-vibra - fix NULL pointer dereference by removing workqueue commit 21fb9f0d5e91 ("Input: twl6040-vibra - use system workqueue") says that it switches to use the system workqueue but it did neither - remove the workqueue struct variable - replace code to really use the system workqueue Instead it calls queue_work() on uninitialized info->workqueue. The result is a NULL pointer dereference in vibra_play(). Solution: use schedule_work Signed-off-by: H. Nikolaus Schaller Signed-off-by: Dmitry Torokhov --- drivers/input/misc/twl6040-vibra.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index ea63fad48de6..3a196ada6892 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -45,7 +45,6 @@ struct vibra_info { struct device *dev; struct input_dev *input_dev; - struct workqueue_struct *workqueue; struct work_struct play_work; struct mutex mutex; int irq; @@ -213,7 +212,7 @@ static int vibra_play(struct input_dev *input, void *data, info->strong_speed = effect->u.rumble.strong_magnitude; info->direction = effect->direction < EFFECT_DIR_180_DEG ? 1 : -1; - ret = queue_work(info->workqueue, &info->play_work); + ret = schedule_work(&info->play_work); if (!ret) { dev_info(&input->dev, "work is already on queue\n"); return ret; -- cgit v1.2.3 From 5f7fb6f1e514e0ed47aee97752d6ae10491b4841 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Mon, 18 Apr 2016 14:47:14 -0700 Subject: Input: twl6040-vibra - ignore return value of schedule_work Returning ret is wrong. And checking for an error as well. User space may call multiple times until the work is really scheduled. twl4030-vibra.c also ignores the return value. Signed-off-by: H. Nikolaus Schaller Signed-off-by: Dmitry Torokhov --- drivers/input/misc/twl6040-vibra.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 3a196ada6892..0c853c2c57f8 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -212,11 +212,7 @@ static int vibra_play(struct input_dev *input, void *data, info->strong_speed = effect->u.rumble.strong_magnitude; info->direction = effect->direction < EFFECT_DIR_180_DEG ? 1 : -1; - ret = schedule_work(&info->play_work); - if (!ret) { - dev_info(&input->dev, "work is already on queue\n"); - return ret; - } + schedule_work(&info->play_work); return 0; } -- cgit v1.2.3 From 03f1217e5fafac8eb9e28aa8d04a67b6db1e435b Mon Sep 17 00:00:00 2001 From: Vladimir Murzin Date: Tue, 19 Apr 2016 12:35:20 +0100 Subject: ARM: 8563/1: fix demoting HWCAP_SWP Commit b8c9592 "ARM: 8318/1: treat CPU feature register fields as signed quantities" accidentally altered cpuid register used to demote HWCAP_SWP. ARM ARM says that SyncPrim_instrs bits in ID_ISAR3 should be used with SynchPrim_instrs_frac from ID_ISAR4. So, follow this rule. Signed-off-by: Vladimir Murzin Acked-by: Ard Biesheuvel Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index a28fce0bdbbe..2c4bea39cf22 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -512,7 +512,7 @@ static void __init elf_hwcap_fixup(void) */ if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 || (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 && - cpuid_feature_extract(CPUID_EXT_ISAR3, 20) >= 3)) + cpuid_feature_extract(CPUID_EXT_ISAR4, 20) >= 3)) elf_hwcap &= ~HWCAP_SWP; } -- cgit v1.2.3 From ac36a881b72a1e9831f1c59abf935868c90685cf Mon Sep 17 00:00:00 2001 From: Vladimir Murzin Date: Tue, 19 Apr 2016 12:35:55 +0100 Subject: ARM: 8564/1: fix cpu feature extracting helper Commit b8c9592 "ARM: 8318/1: treat CPU feature register fields as signed quantities" introduced helper to extract signed quantities of 4-bit blocks. However, with a current code feature with value 0b1000 isn't rejected as negative. So fix the "if" condition. Reported-by: Jonathan Brawn Signed-off-by: Vladimir Murzin Acked-by: Ard Biesheuvel Signed-off-by: Russell King --- arch/arm/include/asm/cputype.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index b23c6c81c9ad..1ee94c716a7f 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -276,7 +276,7 @@ static inline int __attribute_const__ cpuid_feature_extract_field(u32 features, int feature = (features >> field) & 15; /* feature registers are signed values */ - if (feature > 8) + if (feature > 7) feature -= 16; return feature; -- cgit v1.2.3 From de3df8a986b635082a1d94bae2c361d043c57106 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 19 Apr 2016 22:07:50 +0200 Subject: ALSA: hda - Keep powering up ADCs on Cirrus codecs Although one weird behavior about the input path (inconsistent D0/D3 switch) on Cirrus CS420x codecs was fixed in the previous commit, there is still an issue on some Mac machines: the capture stream stalls when switching the ADCs on the fly. More badly, this keeps stuck until the next reboot. The dynamic ADC switching is already a bit fragile and assuming optimistically that the chip accepts the frequent power changes. On Cirrus codecs, this doesn't seem applicable. As a quick workaround, we pin down the ADCs to keep up in D0 when spec->dyn_adc_switch is set. In this way, the ADCs are kept up only for the system that were confirmed to be broken. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=116171 Cc: # v4.4+ Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_cirrus.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index a47e8ae0eb30..80bbadc83721 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -361,6 +361,7 @@ static int cs_parse_auto_config(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; int err; + int i; err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); if (err < 0) @@ -370,6 +371,19 @@ static int cs_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; + /* keep the ADCs powered up when it's dynamically switchable */ + if (spec->gen.dyn_adc_switch) { + unsigned int done = 0; + for (i = 0; i < spec->gen.input_mux.num_items; i++) { + int idx = spec->gen.dyn_adc_idx[i]; + if (done & (1 << idx)) + continue; + snd_hda_gen_fix_pin_power(codec, + spec->gen.adc_nids[idx]); + done |= 1 << idx; + } + } + return 0; } -- cgit v1.2.3 From 5d07163334ba016c053b033cd0bb3c92d7dc0229 Mon Sep 17 00:00:00 2001 From: Aubrey Li Date: Thu, 31 Mar 2016 14:28:09 -0500 Subject: platform:x86 decouple telemetry driver from the optional IPC resources Currently the optional IPC resources prevent telemetry driver from probing if these resources are not in ACPI table. This patch decouples telemetry driver from these optional resources, so that telemetry driver has dependency only on the necessary ACPI resources. Signed-off-by: Aubrey Li Signed-off-by: Darren Hart --- drivers/platform/x86/intel_pmc_ipc.c | 48 ++++++++++++++++------------------ drivers/platform/x86/intel_punit_ipc.c | 48 ++++++++++++++++++++++------------ 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index 3fb1d85c70a8..6f497e80c9df 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c @@ -687,8 +687,8 @@ static int ipc_plat_get_res(struct platform_device *pdev) ipcdev.acpi_io_size = size; dev_info(&pdev->dev, "io res: %pR\n", res); - /* This is index 0 to cover BIOS data register */ punit_res = punit_res_array; + /* This is index 0 to cover BIOS data register */ res = platform_get_resource(pdev, IORESOURCE_MEM, PLAT_RESOURCE_BIOS_DATA_INDEX); if (!res) { @@ -698,55 +698,51 @@ static int ipc_plat_get_res(struct platform_device *pdev) *punit_res = *res; dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res); + /* This is index 1 to cover BIOS interface register */ res = platform_get_resource(pdev, IORESOURCE_MEM, PLAT_RESOURCE_BIOS_IFACE_INDEX); if (!res) { dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n"); return -ENXIO; } - /* This is index 1 to cover BIOS interface register */ *++punit_res = *res; dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res); + /* This is index 2 to cover ISP data register, optional */ res = platform_get_resource(pdev, IORESOURCE_MEM, PLAT_RESOURCE_ISP_DATA_INDEX); - if (!res) { - dev_err(&pdev->dev, "Failed to get res of punit ISP data\n"); - return -ENXIO; + ++punit_res; + if (res) { + *punit_res = *res; + dev_info(&pdev->dev, "punit ISP data res: %pR\n", res); } - /* This is index 2 to cover ISP data register */ - *++punit_res = *res; - dev_info(&pdev->dev, "punit ISP data res: %pR\n", res); + /* This is index 3 to cover ISP interface register, optional */ res = platform_get_resource(pdev, IORESOURCE_MEM, PLAT_RESOURCE_ISP_IFACE_INDEX); - if (!res) { - dev_err(&pdev->dev, "Failed to get res of punit ISP iface\n"); - return -ENXIO; + ++punit_res; + if (res) { + *punit_res = *res; + dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res); } - /* This is index 3 to cover ISP interface register */ - *++punit_res = *res; - dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res); + /* This is index 4 to cover GTD data register, optional */ res = platform_get_resource(pdev, IORESOURCE_MEM, PLAT_RESOURCE_GTD_DATA_INDEX); - if (!res) { - dev_err(&pdev->dev, "Failed to get res of punit GTD data\n"); - return -ENXIO; + ++punit_res; + if (res) { + *punit_res = *res; + dev_info(&pdev->dev, "punit GTD data res: %pR\n", res); } - /* This is index 4 to cover GTD data register */ - *++punit_res = *res; - dev_info(&pdev->dev, "punit GTD data res: %pR\n", res); + /* This is index 5 to cover GTD interface register, optional */ res = platform_get_resource(pdev, IORESOURCE_MEM, PLAT_RESOURCE_GTD_IFACE_INDEX); - if (!res) { - dev_err(&pdev->dev, "Failed to get res of punit GTD iface\n"); - return -ENXIO; + ++punit_res; + if (res) { + *punit_res = *res; + dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res); } - /* This is index 5 to cover GTD interface register */ - *++punit_res = *res; - dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res); res = platform_get_resource(pdev, IORESOURCE_MEM, PLAT_RESOURCE_IPC_INDEX); diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c index bd875409a02d..a47a41fc10ad 100644 --- a/drivers/platform/x86/intel_punit_ipc.c +++ b/drivers/platform/x86/intel_punit_ipc.c @@ -227,6 +227,11 @@ static int intel_punit_get_bars(struct platform_device *pdev) struct resource *res; void __iomem *addr; + /* + * The following resources are required + * - BIOS_IPC BASE_DATA + * - BIOS_IPC BASE_IFACE + */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); addr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(addr)) @@ -239,29 +244,40 @@ static int intel_punit_get_bars(struct platform_device *pdev) return PTR_ERR(addr); punit_ipcdev->base[BIOS_IPC][BASE_IFACE] = addr; + /* + * The following resources are optional + * - ISPDRIVER_IPC BASE_DATA + * - ISPDRIVER_IPC BASE_IFACE + * - GTDRIVER_IPC BASE_DATA + * - GTDRIVER_IPC BASE_IFACE + */ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); - addr = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(addr)) - return PTR_ERR(addr); - punit_ipcdev->base[ISPDRIVER_IPC][BASE_DATA] = addr; + if (res) { + addr = devm_ioremap_resource(&pdev->dev, res); + if (!IS_ERR(addr)) + punit_ipcdev->base[ISPDRIVER_IPC][BASE_DATA] = addr; + } res = platform_get_resource(pdev, IORESOURCE_MEM, 3); - addr = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(addr)) - return PTR_ERR(addr); - punit_ipcdev->base[ISPDRIVER_IPC][BASE_IFACE] = addr; + if (res) { + addr = devm_ioremap_resource(&pdev->dev, res); + if (!IS_ERR(addr)) + punit_ipcdev->base[ISPDRIVER_IPC][BASE_IFACE] = addr; + } res = platform_get_resource(pdev, IORESOURCE_MEM, 4); - addr = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(addr)) - return PTR_ERR(addr); - punit_ipcdev->base[GTDRIVER_IPC][BASE_DATA] = addr; + if (res) { + addr = devm_ioremap_resource(&pdev->dev, res); + if (!IS_ERR(addr)) + punit_ipcdev->base[GTDRIVER_IPC][BASE_DATA] = addr; + } res = platform_get_resource(pdev, IORESOURCE_MEM, 5); - addr = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(addr)) - return PTR_ERR(addr); - punit_ipcdev->base[GTDRIVER_IPC][BASE_IFACE] = addr; + if (res) { + addr = devm_ioremap_resource(&pdev->dev, res); + if (!IS_ERR(addr)) + punit_ipcdev->base[GTDRIVER_IPC][BASE_IFACE] = addr; + } return 0; } -- cgit v1.2.3 From ac6908b3049397b10bcfd8143d79cbdbbd266f02 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Wed, 6 Apr 2016 14:52:53 +0200 Subject: ARM: dts: r8a7791: Don't disable referenced optional clocks clk_get on a disabled clock node will return EPROBE_DEFER, which can cause drivers to be deferred forever if such clocks are referenced in their clocks property. Update the various disabled external clock nodes to default to a frequency of 0, but don't disable them to prevent this. Signed-off-by: Sjoerd Simons Reviewed-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-koelsch.dts | 1 + arch/arm/boot/dts/r8a7791-porter.dts | 1 + arch/arm/boot/dts/r8a7791.dtsi | 5 +---- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 0ad71b81d3a2..cc6e28f81fe4 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -661,6 +661,7 @@ }; &pcie_bus_clk { + clock-frequency = <100000000>; status = "okay"; }; diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts index 6c08314427d6..76c5b2ef8b7e 100644 --- a/arch/arm/boot/dts/r8a7791-porter.dts +++ b/arch/arm/boot/dts/r8a7791-porter.dts @@ -414,6 +414,7 @@ }; &pcie_bus_clk { + clock-frequency = <100000000>; status = "okay"; }; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 6439f0569fe2..1cd1b6a3a72a 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -1083,9 +1083,8 @@ pcie_bus_clk: pcie_bus_clk { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <100000000>; + clock-frequency = <0>; clock-output-names = "pcie_bus"; - status = "disabled"; }; /* External SCIF clock */ @@ -1094,7 +1093,6 @@ #clock-cells = <0>; /* This value must be overridden by the board. */ clock-frequency = <0>; - status = "disabled"; }; /* External USB clock - can be overridden by the board */ @@ -1112,7 +1110,6 @@ /* This value must be overridden by the board. */ clock-frequency = <0>; clock-output-names = "can_clk"; - status = "disabled"; }; /* Special CPG clocks */ -- cgit v1.2.3 From 01638a7f5ef967e94e8aff455874d62e12fe32ed Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Wed, 6 Apr 2016 21:32:06 +0200 Subject: Revert "ARM: dts: porter: Enable SCIF_CLK frequency and pins" This reverts commit 19417bd9c511 ("ARM: dts: porter: Enable SCIF_CLK frequency and pins") as according to http://elinux.org/File:R-CarM2-KOELSCH_PORTER-B_PORTER_C_Comparison.pdf the external oscillator for SCIF_CLK is not mounted on the porter boards. Signed-off-by: Sjoerd Simons Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-porter.dts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts index 76c5b2ef8b7e..a9285d9a57cd 100644 --- a/arch/arm/boot/dts/r8a7791-porter.dts +++ b/arch/arm/boot/dts/r8a7791-porter.dts @@ -143,19 +143,11 @@ }; &pfc { - pinctrl-0 = <&scif_clk_pins>; - pinctrl-names = "default"; - scif0_pins: serial0 { renesas,groups = "scif0_data_d"; renesas,function = "scif0"; }; - scif_clk_pins: scif_clk { - renesas,groups = "scif_clk"; - renesas,function = "scif_clk"; - }; - ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -229,11 +221,6 @@ status = "okay"; }; -&scif_clk { - clock-frequency = <14745600>; - status = "okay"; -}; - ðer { pinctrl-0 = <ðer_pins &phy1_pins>; pinctrl-names = "default"; -- cgit v1.2.3 From c531fb27e9699eaee478ee5686a3cca5dee73602 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 11 Jan 2016 19:41:12 +0100 Subject: ARM: shmobile: timer: Fix preset_lpj leading to too short delays On all shmobile ARM SoCs, loop-based delays may complete early, which can be after only 1/3 (Cortex A9) or 1/2 (Cortex A7 or A15) of the minimum required time. This is caused by calculating preset_lpj based on incorrect assumptions about the number of clock cycles per loop: - All of Cortex A7, A9, and A15 run __loop_delay() at 1 loop per CPU clock cycle, - As of commit 11d4bb1bd067f9d0 ("ARM: 7907/1: lib: delay-loop: Add align directive to fix BogoMIPS calculation"), Cortex A8 runs __loop_delay() at 1 loop per 2 instead of 3 CPU clock cycles. On SoCs with Cortex A7 and/or A15 CPU cores, this went unnoticed, as delays use the ARM arch timer if available. R-Car Gen2 doesn't work if the arch timer is disabled. However, APE6 can be used without the arch timer. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/timer.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index ad008e4b0c49..67d79f9c6bad 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c @@ -40,8 +40,7 @@ static void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz, void __init shmobile_init_delay(void) { struct device_node *np, *cpus; - bool is_a7_a8_a9 = false; - bool is_a15 = false; + unsigned int div = 0; bool has_arch_timer = false; u32 max_freq = 0; @@ -55,27 +54,22 @@ void __init shmobile_init_delay(void) if (!of_property_read_u32(np, "clock-frequency", &freq)) max_freq = max(max_freq, freq); - if (of_device_is_compatible(np, "arm,cortex-a8") || - of_device_is_compatible(np, "arm,cortex-a9")) { - is_a7_a8_a9 = true; - } else if (of_device_is_compatible(np, "arm,cortex-a7")) { - is_a7_a8_a9 = true; - has_arch_timer = true; - } else if (of_device_is_compatible(np, "arm,cortex-a15")) { - is_a15 = true; + if (of_device_is_compatible(np, "arm,cortex-a8")) { + div = 2; + } else if (of_device_is_compatible(np, "arm,cortex-a9")) { + div = 1; + } else if (of_device_is_compatible(np, "arm,cortex-a7") || + of_device_is_compatible(np, "arm,cortex-a15")) { + div = 1; has_arch_timer = true; } } of_node_put(cpus); - if (!max_freq) + if (!max_freq || !div) return; - if (!has_arch_timer || !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) { - if (is_a7_a8_a9) - shmobile_setup_delay_hz(max_freq, 1, 3); - else if (is_a15) - shmobile_setup_delay_hz(max_freq, 2, 4); - } + if (!has_arch_timer || !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) + shmobile_setup_delay_hz(max_freq, 1, div); } -- cgit v1.2.3 From 04aeb56a173282210c5dab5c9b3071fa3613806f Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Mon, 18 Apr 2016 14:33:54 +0300 Subject: net/mlx4_en: allocate non 0-order pages for RX ring with __GFP_NOMEMALLOC High order pages are optional here since commit 51151a16a60f ("mlx4: allow order-0 memory allocations in RX path"), so here is no reason for depleting reserves. Generic __netdev_alloc_frag() implements the same logic. Signed-off-by: Konstantin Khlebnikov Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 86bcfe510e4e..56d070d9cf01 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -61,7 +61,7 @@ static int mlx4_alloc_pages(struct mlx4_en_priv *priv, gfp_t gfp = _gfp; if (order) - gfp |= __GFP_COMP | __GFP_NOWARN; + gfp |= __GFP_COMP | __GFP_NOWARN | __GFP_NOMEMALLOC; page = alloc_pages(gfp, order); if (likely(page)) break; -- cgit v1.2.3 From 851b10d60879539bec8acecb35ed361393399282 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Mon, 18 Apr 2016 14:34:05 +0300 Subject: net/mlx4_en: do batched put_page using atomic_sub This patch fixes couple error paths after allocation failures. Atomic set of page reference counter is safe only if it is zero, otherwise set can race with any speculative get_page_unless_zero. Signed-off-by: Konstantin Khlebnikov Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 56d070d9cf01..7d25bc9c1b22 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -126,7 +126,9 @@ out: dma_unmap_page(priv->ddev, page_alloc[i].dma, page_alloc[i].page_size, PCI_DMA_FROMDEVICE); page = page_alloc[i].page; - set_page_count(page, 1); + /* Revert changes done by mlx4_alloc_pages */ + page_ref_sub(page, page_alloc[i].page_size / + priv->frag_info[i].frag_stride - 1); put_page(page); } } @@ -176,7 +178,9 @@ out: dma_unmap_page(priv->ddev, page_alloc->dma, page_alloc->page_size, PCI_DMA_FROMDEVICE); page = page_alloc->page; - set_page_count(page, 1); + /* Revert changes done by mlx4_alloc_pages */ + page_ref_sub(page, page_alloc->page_size / + priv->frag_info[i].frag_stride - 1); put_page(page); page_alloc->page = NULL; } -- cgit v1.2.3 From 2309236c13feae619572324efd3e910e66ef6bd0 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Mon, 18 Apr 2016 14:37:10 +0300 Subject: cls_cgroup: get sk_classid only from full sockets skb->sk could point to timewait or request socket which has no sk_classid. Detected as "BUG: KASAN: slab-out-of-bounds in cls_cgroup_classify". Signed-off-by: Konstantin Khlebnikov Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/cls_cgroup.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h index c0a92e2c286d..74c9693d4941 100644 --- a/include/net/cls_cgroup.h +++ b/include/net/cls_cgroup.h @@ -17,6 +17,7 @@ #include #include #include +#include #ifdef CONFIG_CGROUP_NET_CLASSID struct cgroup_cls_state { @@ -63,11 +64,13 @@ static inline u32 task_get_classid(const struct sk_buff *skb) * softirqs always disables bh. */ if (in_serving_softirq()) { + struct sock *sk = skb_to_full_sk(skb); + /* If there is an sock_cgroup_classid we'll use that. */ - if (!skb->sk) + if (!sk || !sk_fullsock(sk)) return 0; - classid = sock_cgroup_classid(&skb->sk->sk_cgrp_data); + classid = sock_cgroup_classid(&sk->sk_cgrp_data); } return classid; -- cgit v1.2.3 From 9c995cc9a206a008699da82f6cd01e9b2615649a Mon Sep 17 00:00:00 2001 From: Jorgen Hansen Date: Mon, 18 Apr 2016 23:58:52 -0700 Subject: VSOCK: Only check error on skb_recv_datagram when skb is NULL If skb_recv_datagram returns an skb, we should ignore the err value returned. Otherwise, datagram receives will return EAGAIN when they have to wait for a datagram. Acked-by: Adit Ranadive Signed-off-by: Jorgen Hansen Signed-off-by: David S. Miller --- net/vmw_vsock/vmci_transport.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 662bdd20a748..56214736fe88 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -1735,11 +1735,8 @@ static int vmci_transport_dgram_dequeue(struct vsock_sock *vsk, /* Retrieve the head sk_buff from the socket's receive queue. */ err = 0; skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err); - if (err) - return err; - if (!skb) - return -EAGAIN; + return err; dg = (struct vmci_datagram *)skb->data; if (!dg) @@ -2154,7 +2151,7 @@ module_exit(vmci_transport_exit); MODULE_AUTHOR("VMware, Inc."); MODULE_DESCRIPTION("VMCI transport for Virtual Sockets"); -MODULE_VERSION("1.0.3.0-k"); +MODULE_VERSION("1.0.4.0-k"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("vmware_vsock"); MODULE_ALIAS_NETPROTO(PF_VSOCK); -- cgit v1.2.3 From 38740a5b87d53ceb89eb2c970150f6e94e00373a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 14 Apr 2016 17:01:17 +0200 Subject: usb: gadget: f_fs: Fix use-after-free When using asynchronous read or write operations on the USB endpoints the issuer of the IO request is notified by calling the ki_complete() callback of the submitted kiocb when the URB has been completed. Calling this ki_complete() callback will free kiocb. Make sure that the structure is no longer accessed beyond that point, otherwise undefined behaviour might occur. Fixes: 2e4c7553cd6f ("usb: gadget: f_fs: add aio support") Cc: # v3.15+ Signed-off-by: Lars-Peter Clausen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_fs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index e21ca2bd6839..15b648cbc75c 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -646,6 +646,7 @@ static void ffs_user_copy_worker(struct work_struct *work) work); int ret = io_data->req->status ? io_data->req->status : io_data->req->actual; + bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD; if (io_data->read && ret > 0) { use_mm(io_data->mm); @@ -657,13 +658,11 @@ static void ffs_user_copy_worker(struct work_struct *work) io_data->kiocb->ki_complete(io_data->kiocb, ret, ret); - if (io_data->ffs->ffs_eventfd && - !(io_data->kiocb->ki_flags & IOCB_EVENTFD)) + if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd) eventfd_signal(io_data->ffs->ffs_eventfd, 1); usb_ep_free_request(io_data->ep, io_data->req); - io_data->kiocb->private = NULL; if (io_data->read) kfree(io_data->to_free); kfree(io_data->buf); -- cgit v1.2.3 From 9859a971ca228725425238756ee89c6133306ec8 Mon Sep 17 00:00:00 2001 From: "Lu, Han" Date: Wed, 20 Apr 2016 10:08:43 +0800 Subject: ALSA: hda - add PCI ID for Intel Broxton-T Add HD Audio Device PCI ID for the Intel Broxton-T platform. It is an HDA Intel PCH controller. Signed-off-by: Lu, Han Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b680be0e937d..637b8a0e2a91 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2232,6 +2232,9 @@ static const struct pci_device_id azx_ids[] = { /* Broxton-P(Apollolake) */ { PCI_DEVICE(0x8086, 0x5a98), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON }, + /* Broxton-T */ + { PCI_DEVICE(0x8086, 0x1a98), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON }, /* Haswell */ { PCI_DEVICE(0x8086, 0x0a0c), .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL }, -- cgit v1.2.3 From 2fee7d5b08b6419bb59de9e875d895e3a6e7bf5a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 20 Apr 2016 10:23:31 +0900 Subject: arm64: spin-table: add missing of_node_put() Since of_get_cpu_node() increments refcount, the node should be put. Signed-off-by: Masahiro Yamada Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/smp_spin_table.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c index aef3605a8c47..18a71bcd26ee 100644 --- a/arch/arm64/kernel/smp_spin_table.c +++ b/arch/arm64/kernel/smp_spin_table.c @@ -52,6 +52,7 @@ static void write_pen_release(u64 val) static int smp_spin_table_cpu_init(unsigned int cpu) { struct device_node *dn; + int ret; dn = of_get_cpu_node(cpu, NULL); if (!dn) @@ -60,15 +61,15 @@ static int smp_spin_table_cpu_init(unsigned int cpu) /* * Determine the address from which the CPU is polling. */ - if (of_property_read_u64(dn, "cpu-release-addr", - &cpu_release_addr[cpu])) { + ret = of_property_read_u64(dn, "cpu-release-addr", + &cpu_release_addr[cpu]); + if (ret) pr_err("CPU %d: missing or invalid cpu-release-addr property\n", cpu); - return -1; - } + of_node_put(dn); - return 0; + return ret; } static int smp_spin_table_cpu_prepare(unsigned int cpu) -- cgit v1.2.3 From 89d124cb61b39900959e2839ac06b6339b6a54cb Mon Sep 17 00:00:00 2001 From: Jonas Eymann Date: Tue, 19 Apr 2016 20:33:47 +0300 Subject: crypto: talitos - fix crash in talitos_cra_init() Conversion of talitos driver to the new AEAD interface hasn't been properly tested. AEAD algorithms crash in talitos_cra_init as follows: [...] [ 1.141095] talitos ffe30000.crypto: hwrng [ 1.145381] Unable to handle kernel paging request for data at address 0x00000058 [ 1.152913] Faulting instruction address: 0xc02accc0 [ 1.157910] Oops: Kernel access of bad area, sig: 11 [#1] [ 1.163315] SMP NR_CPUS=2 P1020 RDB [ 1.166810] Modules linked in: [ 1.169875] CPU: 0 PID: 1007 Comm: cryptomgr_test Not tainted 4.4.6 #1 [ 1.176415] task: db5ec200 ti: db4d6000 task.ti: db4d6000 [ 1.181821] NIP: c02accc0 LR: c02acd18 CTR: c02acd04 [ 1.186793] REGS: db4d7d30 TRAP: 0300 Not tainted (4.4.6) [ 1.192457] MSR: 00029000 CR: 95009359 XER: e0000000 [ 1.198585] DEAR: 00000058 ESR: 00000000 GPR00: c017bdc0 db4d7de0 db5ec200 df424b48 00000000 00000000 df424bfc db75a600 GPR08: df424b48 00000000 db75a628 db4d6000 00000149 00000000 c0044cac db5acda0 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000400 df424940 GPR24: df424900 00003083 00000400 c0180000 db75a640 c03e9f84 df424b40 df424b48 [ 1.230978] NIP [c02accc0] talitos_cra_init+0x28/0x6c [ 1.236039] LR [c02acd18] talitos_cra_init_aead+0x14/0x28 [ 1.241443] Call Trace: [ 1.243894] [db4d7de0] [c03e9f84] 0xc03e9f84 (unreliable) [ 1.249322] [db4d7df0] [c017bdc0] crypto_create_tfm+0x5c/0xf0 [ 1.255083] [db4d7e10] [c017beec] crypto_alloc_tfm+0x98/0xf8 [ 1.260769] [db4d7e40] [c0186a20] alg_test_aead+0x28/0xc8 [ 1.266181] [db4d7e60] [c0186718] alg_test+0x260/0x2e0 [ 1.271333] [db4d7ee0] [c0183860] cryptomgr_test+0x30/0x54 [ 1.276843] [db4d7ef0] [c0044d80] kthread+0xd4/0xd8 [ 1.281741] [db4d7f40] [c000e4a4] ret_from_kernel_thread+0x5c/0x64 [ 1.287930] Instruction dump: [ 1.290902] 38600000 4e800020 81230028 7c681b78 81490010 38e9ffc0 3929ffe8 554a073e [ 1.298691] 2b8a000a 7d474f9e 812a0008 91230030 <80e90058> 39270060 7c0004ac 7cc04828 Cc: # 4.3+ Fixes: aeb4c132f33d ("crypto: talitos - Convert to new AEAD interface") Signed-off-by: Jonas Eymann Fix typo - replaced parameter of __crypto_ahash_alg(): s/tfm/alg Remove checkpatch warnings. Add commit message. Signed-off-by: Horia Geant? Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index a0d4a08313ae..35198804d6d3 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -2629,21 +2629,11 @@ struct talitos_crypto_alg { struct talitos_alg_template algt; }; -static int talitos_cra_init(struct crypto_tfm *tfm) +static int talitos_init_common(struct talitos_ctx *ctx, + struct talitos_crypto_alg *talitos_alg) { - struct crypto_alg *alg = tfm->__crt_alg; - struct talitos_crypto_alg *talitos_alg; - struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); struct talitos_private *priv; - if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH) - talitos_alg = container_of(__crypto_ahash_alg(alg), - struct talitos_crypto_alg, - algt.alg.hash); - else - talitos_alg = container_of(alg, struct talitos_crypto_alg, - algt.alg.crypto); - /* update context with ptr to dev */ ctx->dev = talitos_alg->dev; @@ -2661,10 +2651,33 @@ static int talitos_cra_init(struct crypto_tfm *tfm) return 0; } +static int talitos_cra_init(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg = tfm->__crt_alg; + struct talitos_crypto_alg *talitos_alg; + struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); + + if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH) + talitos_alg = container_of(__crypto_ahash_alg(alg), + struct talitos_crypto_alg, + algt.alg.hash); + else + talitos_alg = container_of(alg, struct talitos_crypto_alg, + algt.alg.crypto); + + return talitos_init_common(ctx, talitos_alg); +} + static int talitos_cra_init_aead(struct crypto_aead *tfm) { - talitos_cra_init(crypto_aead_tfm(tfm)); - return 0; + struct aead_alg *alg = crypto_aead_alg(tfm); + struct talitos_crypto_alg *talitos_alg; + struct talitos_ctx *ctx = crypto_aead_ctx(tfm); + + talitos_alg = container_of(alg, struct talitos_crypto_alg, + algt.alg.aead); + + return talitos_init_common(ctx, talitos_alg); } static int talitos_cra_init_ahash(struct crypto_tfm *tfm) -- cgit v1.2.3 From 340ff60ae93a5db2b2be6f38868df9a1293b6007 Mon Sep 17 00:00:00 2001 From: Horia Geant? Date: Tue, 19 Apr 2016 20:33:48 +0300 Subject: crypto: talitos - fix AEAD tcrypt tests After conversion to new AEAD interface, tcrypt tests fail as follows: [...] [ 1.145414] alg: aead: Test 1 failed on encryption for authenc-hmac-sha1-cbc-aes-talitos [ 1.153564] 00000000: 53 69 6e 67 6c 65 20 62 6c 6f 63 6b 20 6d 73 67 [ 1.160041] 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 1.166509] 00000020: 00 00 00 00 [...] Fix them by providing the correct cipher in & cipher out pointers, i.e. must skip over associated data in src and dst S/G. While here, fix a problem with the HW S/G table index usage: tbl_off must be updated after the pointer to the table entries is set. Cc: # 4.3+ Fixes: aeb4c132f33d ("crypto: talitos - Convert to new AEAD interface") Reported-by: Jonas Eymann Signed-off-by: Horia Geant? Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 35198804d6d3..aae05547b924 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -63,6 +63,14 @@ static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr, ptr->eptr = upper_32_bits(dma_addr); } +static void copy_talitos_ptr(struct talitos_ptr *dst_ptr, + struct talitos_ptr *src_ptr, bool is_sec1) +{ + dst_ptr->ptr = src_ptr->ptr; + if (!is_sec1) + dst_ptr->eptr = src_ptr->eptr; +} + static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len, bool is_sec1) { @@ -1083,21 +1091,20 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ?: 1, (areq->src == areq->dst) ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE); - /* hmac data */ desc->ptr[1].len = cpu_to_be16(areq->assoclen); if (sg_count > 1 && (ret = sg_to_link_tbl_offset(areq->src, sg_count, 0, areq->assoclen, &edesc->link_tbl[tbl_off])) > 1) { - tbl_off += ret; - to_talitos_ptr(&desc->ptr[1], edesc->dma_link_tbl + tbl_off * sizeof(struct talitos_ptr), 0); desc->ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP; dma_sync_single_for_device(dev, edesc->dma_link_tbl, edesc->dma_len, DMA_BIDIRECTIONAL); + + tbl_off += ret; } else { to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->src), 0); desc->ptr[1].j_extent = 0; @@ -1126,11 +1133,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV) sg_link_tbl_len += authsize; - if (sg_count > 1 && - (ret = sg_to_link_tbl_offset(areq->src, sg_count, areq->assoclen, - sg_link_tbl_len, - &edesc->link_tbl[tbl_off])) > 1) { - tbl_off += ret; + if (sg_count == 1) { + to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src) + + areq->assoclen, 0); + } else if ((ret = sg_to_link_tbl_offset(areq->src, sg_count, + areq->assoclen, sg_link_tbl_len, + &edesc->link_tbl[tbl_off])) > + 1) { desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; to_talitos_ptr(&desc->ptr[4], edesc->dma_link_tbl + tbl_off * @@ -1138,8 +1147,10 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, dma_sync_single_for_device(dev, edesc->dma_link_tbl, edesc->dma_len, DMA_BIDIRECTIONAL); - } else - to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src), 0); + tbl_off += ret; + } else { + copy_talitos_ptr(&desc->ptr[4], &edesc->link_tbl[tbl_off], 0); + } /* cipher out */ desc->ptr[5].len = cpu_to_be16(cryptlen); @@ -1151,11 +1162,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, edesc->icv_ool = false; - if (sg_count > 1 && - (sg_count = sg_to_link_tbl_offset(areq->dst, sg_count, + if (sg_count == 1) { + to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst) + + areq->assoclen, 0); + } else if ((sg_count = + sg_to_link_tbl_offset(areq->dst, sg_count, areq->assoclen, cryptlen, - &edesc->link_tbl[tbl_off])) > - 1) { + &edesc->link_tbl[tbl_off])) > 1) { struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off]; to_talitos_ptr(&desc->ptr[5], edesc->dma_link_tbl + @@ -1178,8 +1191,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, edesc->dma_len, DMA_BIDIRECTIONAL); edesc->icv_ool = true; - } else - to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst), 0); + } else { + copy_talitos_ptr(&desc->ptr[5], &edesc->link_tbl[tbl_off], 0); + } /* iv out */ map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, -- cgit v1.2.3 From 89e9e66ba1b3bde9d8ea90566c2aee20697ad681 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 15 Apr 2016 14:35:39 +0200 Subject: futex: Handle unlock_pi race gracefully If userspace calls UNLOCK_PI unconditionally without trying the TID -> 0 transition in user space first then the user space value might not have the waiters bit set. This opens the following race: CPU0 CPU1 uval = get_user(futex) lock(hb) lock(hb) futex |= FUTEX_WAITERS .... unlock(hb) cmpxchg(futex, uval, newval) So the cmpxchg fails and returns -EINVAL to user space, which is wrong because the futex value is valid. To handle this (yes, yet another) corner case gracefully, check for a flag change and retry. [ tglx: Massaged changelog and slightly reworked implementation ] Fixes: ccf9e6a80d9e ("futex: Make unlock_pi more robust") Signed-off-by: Sebastian Andrzej Siewior Cc: stable@vger.kernel.org Cc: Davidlohr Bueso Cc: Darren Hart Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1460723739-5195-1-git-send-email-bigeasy@linutronix.de Signed-off-by: Thomas Gleixner --- kernel/futex.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index a5d2e74c89e0..fd204e1670c9 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1295,10 +1295,20 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this, if (unlikely(should_fail_futex(true))) ret = -EFAULT; - if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) + if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) { ret = -EFAULT; - else if (curval != uval) - ret = -EINVAL; + } else if (curval != uval) { + /* + * If a unconditional UNLOCK_PI operation (user space did not + * try the TID->0 transition) raced with a waiter setting the + * FUTEX_WAITERS flag between get_user() and locking the hash + * bucket lock, retry the operation. + */ + if ((FUTEX_TID_MASK & curval) == uval) + ret = -EAGAIN; + else + ret = -EINVAL; + } if (ret) { raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); return ret; @@ -2622,6 +2632,15 @@ retry: */ if (ret == -EFAULT) goto pi_faulted; + /* + * A unconditional UNLOCK_PI op raced against a waiter + * setting the FUTEX_WAITERS bit. Try again. + */ + if (ret == -EAGAIN) { + spin_unlock(&hb->lock); + put_futex_key(&key); + goto retry; + } /* * wake_futex_pi has detected invalid state. Tell user * space. -- cgit v1.2.3 From df637193906a6b645d8678c748149a71852e63e9 Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Wed, 20 Apr 2016 16:14:51 +0100 Subject: Revert "Prevent NUll pointer dereference with two PHYs on cpsw" This reverts commit cfe255600154f0072d4a8695590dbd194dfd1aeb This can result in a "Unable to handle kernel paging request" during boot. This was due to using an uninitialised struct member, data->slaves. Signed-off-by: Andrew Goodbody Tested-by: Tony Lindgren Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 5f5bb4471800..42fdfd4d9d4f 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -349,7 +349,6 @@ struct cpsw_slave { struct cpsw_slave_data *data; struct phy_device *phy; struct net_device *ndev; - struct device_node *phy_node; u32 port_vlan; u32 open_stat; }; @@ -368,6 +367,7 @@ struct cpsw_priv { spinlock_t lock; struct platform_device *pdev; struct net_device *ndev; + struct device_node *phy_node; struct napi_struct napi_rx; struct napi_struct napi_tx; struct device *dev; @@ -1148,8 +1148,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); - if (slave->phy_node) - slave->phy = of_phy_connect(priv->ndev, slave->phy_node, + if (priv->phy_node) + slave->phy = of_phy_connect(priv->ndev, priv->phy_node, &cpsw_adjust_link, 0, slave->data->phy_if); else slave->phy = phy_connect(priv->ndev, slave->data->phy_id, @@ -2033,8 +2033,7 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, if (strcmp(slave_node->name, "slave")) continue; - priv->slaves[i].phy_node = - of_parse_phandle(slave_node, "phy-handle", 0); + priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0); parp = of_get_property(slave_node, "phy_id", &lenp); if (of_phy_is_fixed_link(slave_node)) { struct device_node *phy_node; @@ -2276,22 +2275,12 @@ static int cpsw_probe(struct platform_device *pdev) /* Select default pin state */ pinctrl_pm_select_default_state(&pdev->dev); - data = &priv->data; - priv->slaves = devm_kzalloc(&pdev->dev, - sizeof(struct cpsw_slave) * data->slaves, - GFP_KERNEL); - if (!priv->slaves) { - ret = -ENOMEM; - goto clean_runtime_disable_ret; - } - for (i = 0; i < data->slaves; i++) - priv->slaves[i].slave_num = i; - if (cpsw_probe_dt(priv, pdev)) { dev_err(&pdev->dev, "cpsw: platform data missing\n"); ret = -ENODEV; goto clean_runtime_disable_ret; } + data = &priv->data; if (is_valid_ether_addr(data->slave_data[0].mac_addr)) { memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN); @@ -2303,6 +2292,16 @@ static int cpsw_probe(struct platform_device *pdev) memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN); + priv->slaves = devm_kzalloc(&pdev->dev, + sizeof(struct cpsw_slave) * data->slaves, + GFP_KERNEL); + if (!priv->slaves) { + ret = -ENOMEM; + goto clean_runtime_disable_ret; + } + for (i = 0; i < data->slaves; i++) + priv->slaves[i].slave_num = i; + priv->slaves[0].ndev = ndev; priv->emac_port = 0; -- cgit v1.2.3 From d5468d7afaa9c9e961e150f0455a14a9f4872a98 Mon Sep 17 00:00:00 2001 From: Vladis Dronov Date: Sun, 31 Jan 2016 14:14:52 -0200 Subject: [media] usbvision: revert commit 588afcc1 Commit 588afcc1c0e4 ("[media] usbvision fix overflow of interfaces array")' should be reverted, because: * "!dev->actconfig->interface[ifnum]" won't catch a case where the value is not NULL but some garbage. This way the system may crash later with GPF. * "(ifnum >= USB_MAXINTERFACES)" does not cover all the error conditions. "ifnum" should be compared to "dev->actconfig-> desc.bNumInterfaces", i.e. compared to the number of "struct usb_interface" kzalloc()-ed, not to USB_MAXINTERFACES. * There is a "struct usb_device" leak in this error path, as there is usb_get_dev(), but no usb_put_dev() on this path. * There is a bug of the same type several lines below with number of endpoints. The code is accessing hard-coded second endpoint ("interface->endpoint[1].desc") which may not exist. It would be great to handle this in the same patch too. * All the concerns above are resolved by already-accepted commit fa52bd50 ("[media] usbvision: fix crash on detecting device with invalid configuration") * Mailing list message: http://www.spinics.net/lists/linux-media/msg94832.html Signed-off-by: Vladis Dronov Signed-off-by: Hans Verkuil Cc: # for v4.5 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbvision/usbvision-video.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index 12f5ebbd0436..ad2f3d27b266 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -1452,13 +1452,6 @@ static int usbvision_probe(struct usb_interface *intf, printk(KERN_INFO "%s: %s found\n", __func__, usbvision_device_data[model].model_string); - /* - * this is a security check. - * an exploit using an incorrect bInterfaceNumber is known - */ - if (ifnum >= USB_MAXINTERFACES || !dev->actconfig->interface[ifnum]) - return -ENODEV; - if (usbvision_device_data[model].interface >= 0) interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0]; else if (ifnum < dev->actconfig->desc.bNumInterfaces) -- cgit v1.2.3 From 8bbb6568428fa14c5bef120d443c20e0e7d52699 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Apr 2016 08:58:10 -0300 Subject: [media] davinci_vpfe: Revert "staging: media: davinci_vpfe: remove,unnecessary ret variable" This reverts commit afa5d19a2b5f ("staging: media: davinci_vpfe: remove unnecessary ret variable"). This patch is completely bogus and messed up the code big time. I'm not sure what was intended, but this isn't it. Cc: Thaissa Falbo Cc: Greg Kroah-Hartman Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/davinci_vpfe/vpfe_video.c | 54 ++++++++++++++++--------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index b793c04028a3..be72a8e5f221 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -172,9 +172,11 @@ static int vpfe_prepare_pipeline(struct vpfe_video_device *video) static int vpfe_update_pipe_state(struct vpfe_video_device *video) { struct vpfe_pipeline *pipe = &video->pipe; + int ret; - if (vpfe_prepare_pipeline(video)) - return vpfe_prepare_pipeline(video); + ret = vpfe_prepare_pipeline(video); + if (ret) + return ret; /* * Find out if there is any input video @@ -182,9 +184,10 @@ static int vpfe_update_pipe_state(struct vpfe_video_device *video) */ if (pipe->input_num == 0) { pipe->state = VPFE_PIPELINE_STREAM_CONTINUOUS; - if (vpfe_update_current_ext_subdev(video)) { + ret = vpfe_update_current_ext_subdev(video); + if (ret) { pr_err("Invalid external subdev\n"); - return vpfe_update_current_ext_subdev(video); + return ret; } } else { pipe->state = VPFE_PIPELINE_STREAM_SINGLESHOT; @@ -667,6 +670,7 @@ static int vpfe_enum_fmt(struct file *file, void *priv, struct v4l2_subdev *subdev; struct v4l2_format format; struct media_pad *remote; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt\n"); @@ -695,10 +699,11 @@ static int vpfe_enum_fmt(struct file *file, void *priv, sd_fmt.pad = remote->index; sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; /* get output format of remote subdev */ - if (v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt)) { + ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt); + if (ret) { v4l2_err(&vpfe_dev->v4l2_dev, "invalid remote subdev for video node\n"); - return v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt); + return ret; } /* convert to pix format */ mbus.code = sd_fmt.format.code; @@ -725,6 +730,7 @@ static int vpfe_s_fmt(struct file *file, void *priv, struct vpfe_video_device *video = video_drvdata(file); struct vpfe_device *vpfe_dev = video->vpfe_dev; struct v4l2_format format; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt\n"); /* If streaming is started, return error */ @@ -733,8 +739,9 @@ static int vpfe_s_fmt(struct file *file, void *priv, return -EBUSY; } /* get adjacent subdev's output pad format */ - if (__vpfe_video_get_format(video, &format)) - return __vpfe_video_get_format(video, &format); + ret = __vpfe_video_get_format(video, &format); + if (ret) + return ret; *fmt = format; video->fmt = *fmt; return 0; @@ -757,11 +764,13 @@ static int vpfe_try_fmt(struct file *file, void *priv, struct vpfe_video_device *video = video_drvdata(file); struct vpfe_device *vpfe_dev = video->vpfe_dev; struct v4l2_format format; + int ret; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt\n"); /* get adjacent subdev's output pad format */ - if (__vpfe_video_get_format(video, &format)) - return __vpfe_video_get_format(video, &format); + ret = __vpfe_video_get_format(video, &format); + if (ret) + return ret; *fmt = format; return 0; @@ -838,8 +847,9 @@ static int vpfe_s_input(struct file *file, void *priv, unsigned int index) v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n"); - if (mutex_lock_interruptible(&video->lock)) - return mutex_lock_interruptible(&video->lock); + ret = mutex_lock_interruptible(&video->lock); + if (ret) + return ret; /* * If streaming is started return device busy * error @@ -940,8 +950,9 @@ static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id) v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n"); /* Call decoder driver function to set the standard */ - if (mutex_lock_interruptible(&video->lock)) - return mutex_lock_interruptible(&video->lock); + ret = mutex_lock_interruptible(&video->lock); + if (ret) + return ret; sdinfo = video->current_ext_subdev; /* If streaming is started, return device busy error */ if (video->started) { @@ -1327,8 +1338,9 @@ static int vpfe_reqbufs(struct file *file, void *priv, return -EINVAL; } - if (mutex_lock_interruptible(&video->lock)) - return mutex_lock_interruptible(&video->lock); + ret = mutex_lock_interruptible(&video->lock); + if (ret) + return ret; if (video->io_usrs != 0) { v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n"); @@ -1354,10 +1366,11 @@ static int vpfe_reqbufs(struct file *file, void *priv, q->buf_struct_size = sizeof(struct vpfe_cap_buffer); q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - if (vb2_queue_init(q)) { + ret = vb2_queue_init(q); + if (ret) { v4l2_err(&vpfe_dev->v4l2_dev, "vb2_queue_init() failed\n"); vb2_dma_contig_cleanup_ctx(vpfe_dev->pdev); - return vb2_queue_init(q); + return ret; } fh->io_allowed = 1; @@ -1533,8 +1546,9 @@ static int vpfe_streamoff(struct file *file, void *priv, return -EINVAL; } - if (mutex_lock_interruptible(&video->lock)) - return mutex_lock_interruptible(&video->lock); + ret = mutex_lock_interruptible(&video->lock); + if (ret) + return ret; vpfe_stop_capture(video); ret = vb2_streamoff(&video->buffer_queue, buf_type); -- cgit v1.2.3 From 4bfeefd085acf1ab70ecda6087fad6c32b2b065f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 19 Apr 2016 09:50:09 -0700 Subject: Input: twl6040-vibra - do not reparent to grandparent For devm-managed input devices we should not modify input device's parent, otherwise automatic release of resources will not work properly. Tested-by: "H. Nikolaus Schaller" Signed-off-by: Dmitry Torokhov --- drivers/input/misc/twl6040-vibra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 0c853c2c57f8..53e33fab3f7a 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -357,7 +357,6 @@ static int twl6040_vibra_probe(struct platform_device *pdev) info->input_dev->name = "twl6040:vibrator"; info->input_dev->id.version = 1; - info->input_dev->dev.parent = pdev->dev.parent; info->input_dev->close = twl6040_vibra_close; __set_bit(FF_RUMBLE, info->input_dev->ffbit); -- cgit v1.2.3 From dcc7597116c6713353522eb13c765063ff88bb89 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 19 Apr 2016 09:54:32 -0700 Subject: Input: twl4030-vibra - do not reparent to grandparent For devm-managed input devices we should not modify input device's parent, otherwise automatic release of resources will not work properly. Signed-off-by: Dmitry Torokhov --- drivers/input/misc/twl4030-vibra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index 10c4e3d462f1..caa5a62c42fb 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c @@ -222,7 +222,6 @@ static int twl4030_vibra_probe(struct platform_device *pdev) info->input_dev->name = "twl4030:vibrator"; info->input_dev->id.version = 1; - info->input_dev->dev.parent = pdev->dev.parent; info->input_dev->close = twl4030_vibra_close; __set_bit(FF_RUMBLE, info->input_dev->ffbit); -- cgit v1.2.3 From c0ff8aaae369559fbef0e9f2606a9ae92db14f2f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 19 Apr 2016 14:33:32 +0200 Subject: thermal: of: add __init attribute Add __init attribute on a function that is only called from other __init functions and that is not inlined, at least with gcc version 4.8.4 on an x86 machine with allyesconfig. Currently, the function is put in the .text.unlikely segment. Declaring it as __init will cause it to be put in the .init.text and to disappear after initialization. The result of objdump -x on the function before the change is as follows: 0000000000000086 l F .text.unlikely 0000000000000739 thermal_of_build_thermal_zone And after the change it is as follows: 0000000000000000 l F .init.text 0000000000000734 thermal_of_build_thermal_zone Done with the help of Coccinelle. The semantic patch checks for local static non-init functions that are called from an __init function and are not called from any other function. Signed-off-by: Julia Lawall Signed-off-by: Eduardo Valentin --- drivers/thermal/of-thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index 49ac23d3e776..d8ec44b194d6 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -803,8 +803,8 @@ static int thermal_of_populate_trip(struct device_node *np, * otherwise, it returns a corresponding ERR_PTR(). Caller must * check the return value with help of IS_ERR() helper. */ -static struct __thermal_zone * -thermal_of_build_thermal_zone(struct device_node *np) +static struct __thermal_zone +__init *thermal_of_build_thermal_zone(struct device_node *np) { struct device_node *child = NULL, *gchild; struct __thermal_zone *tz; -- cgit v1.2.3 From f9d038144a171d42e057143b247ff7a12a5b06f5 Mon Sep 17 00:00:00 2001 From: Javi Merino Date: Wed, 6 Apr 2016 19:30:18 +0100 Subject: thermal: power_allocator: req_range multiplication should be a 64 bit type req_range is declared as a u64 to cope with overflows in the multiplication of two u32. As both req_power and power_range are u32, we need to make sure the multiplication is done with u64 types. Reported-by: Dan Carpenter Cc: Zhang Rui Cc: Eduardo Valentin Signed-off-by: Javi Merino Signed-off-by: Eduardo Valentin --- drivers/thermal/power_allocator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/power_allocator.c b/drivers/thermal/power_allocator.c index 1246aa6fcab0..2f1a863a8e15 100644 --- a/drivers/thermal/power_allocator.c +++ b/drivers/thermal/power_allocator.c @@ -301,7 +301,7 @@ static void divvy_up_power(u32 *req_power, u32 *max_power, int num_actors, capped_extra_power = 0; extra_power = 0; for (i = 0; i < num_actors; i++) { - u64 req_range = req_power[i] * power_range; + u64 req_range = (u64)req_power[i] * power_range; granted_power[i] = DIV_ROUND_CLOSEST_ULL(req_range, total_req_power); -- cgit v1.2.3 From 9ebfb4e09959b03b58b65b5a6c04f70dd57d4f6b Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 19 Apr 2016 16:45:01 -0700 Subject: thermal: minor mtk_thermal.c cleanups Trivial cleanups: - delete one duplicate #include - end email address with closing '>' Signed-off-by: Randy Dunlap Cc: Zhang Rui Cc: Eduardo Valentin Cc: Sascha Hauer Cc: Hanyi Wu Signed-off-by: Eduardo Valentin --- drivers/thermal/mtk_thermal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 3d93b1c07cee..507632b9648e 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -27,7 +27,6 @@ #include #include #include -#include /* AUXADC Registers */ #define AUXADC_CON0_V 0x000 @@ -619,7 +618,7 @@ static struct platform_driver mtk_thermal_driver = { module_platform_driver(mtk_thermal_driver); -MODULE_AUTHOR("Sascha Hauer "); MODULE_AUTHOR("Hanyi Wu "); MODULE_DESCRIPTION("Mediatek thermal driver"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 62e14f6fd383f756ff3fe5f6fb7aa5b546bb47e3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 19 Apr 2016 09:44:23 -0700 Subject: thermal: fix mtk_thermal build dependency Fix build errors when MTK_THERMAL=y and NVMEM=m by preventing that Kconfig combination. drivers/built-in.o: In function `mtk_thermal_probe': mtk_thermal.c:(.text+0xffa8f): undefined reference to `nvmem_cell_get' mtk_thermal.c:(.text+0xffabe): undefined reference to `nvmem_cell_read' mtk_thermal.c:(.text+0xffac9): undefined reference to `nvmem_cell_put' Signed-off-by: Randy Dunlap Cc: Zhang Rui Cc: Eduardo Valentin Cc: Cc: Sascha Hauer Cc: Hanyi Wu Signed-off-by: Eduardo Valentin --- drivers/thermal/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index c37eedc35a24..5c7711091964 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -376,6 +376,7 @@ config MTK_THERMAL tristate "Temperature sensor driver for mediatek SoCs" depends on ARCH_MEDIATEK || COMPILE_TEST depends on HAS_IOMEM + depends on NVMEM || NVMEM=n default y help Enable this option if you want to have support for thermal management -- cgit v1.2.3 From 1d0fd42fa31d18ba0a3e0dd008c9e93e1cebe451 Mon Sep 17 00:00:00 2001 From: Wei Ni Date: Thu, 3 Mar 2016 17:33:46 +0800 Subject: thermal: consistently use int for trip temp The commit 17e8351a7739 consistently use int for temperature, however it missed a few in trip temperature and thermal_core. In current codes, the trip->temperature used "unsigned long" and zone->temperature used"int", if the temperature is negative value, it will get wrong result when compare temperature with trip temperature. This patch can fix it. Signed-off-by: Wei Ni Signed-off-by: Eduardo Valentin --- drivers/thermal/thermal_core.c | 8 ++++---- include/linux/thermal.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index d4b54653ecf8..f1db49625555 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -688,7 +688,7 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, { struct thermal_zone_device *tz = to_thermal_zone(dev); int trip, ret; - unsigned long temperature; + int temperature; if (!tz->ops->set_trip_temp) return -EPERM; @@ -696,7 +696,7 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip)) return -EINVAL; - if (kstrtoul(buf, 10, &temperature)) + if (kstrtoint(buf, 10, &temperature)) return -EINVAL; ret = tz->ops->set_trip_temp(tz, trip, temperature); @@ -899,9 +899,9 @@ emul_temp_store(struct device *dev, struct device_attribute *attr, { struct thermal_zone_device *tz = to_thermal_zone(dev); int ret = 0; - unsigned long temperature; + int temperature; - if (kstrtoul(buf, 10, &temperature)) + if (kstrtoint(buf, 10, &temperature)) return -EINVAL; if (!tz->ops->set_emul_temp) { diff --git a/include/linux/thermal.h b/include/linux/thermal.h index a55d0523f75d..1b8a5a7876ce 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -352,8 +352,8 @@ struct thermal_zone_of_device_ops { struct thermal_trip { struct device_node *np; - unsigned long int temperature; - unsigned long int hysteresis; + int temperature; + int hysteresis; enum thermal_trip_type type; }; -- cgit v1.2.3 From a6f4850dbca66e46a73b8774e85aaf9fc0caf265 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 14 Apr 2016 15:15:20 +0200 Subject: thermal: fix Mediatek thermal controller build At least with CONFIG_COMPILE_TEST, there's no reason to assume that CONFIG_RESET_CONTROLLER is set, but the code for this controller requires it since it calls device_reset(). Make CONFIG_MTK_THERMAL properly depend on CONFIG_RESET_CONTROLLER. Signed-off-by: Johannes Berg Signed-off-by: Eduardo Valentin --- drivers/thermal/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 5c7711091964..3c3dc4a3d52c 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -377,6 +377,7 @@ config MTK_THERMAL depends on ARCH_MEDIATEK || COMPILE_TEST depends on HAS_IOMEM depends on NVMEM || NVMEM=n + depends on RESET_CONTROLLER default y help Enable this option if you want to have support for thermal management -- cgit v1.2.3 From dba599091c191d209b1499511a524ad9657c0e5a Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 15 Apr 2016 09:41:35 +0200 Subject: s390/pci: fix use after free in dma_init After a failure during registration of the dma_table (because of the function being in error state) we free its memory but don't reset the associated pointer to zero. When we then receive a notification from firmware (about the function being in error state) we'll try to walk and free the dma_table again. Fix this by resetting the dma_table pointer. In addition to that make sure that we free the iommu_bitmap when appropriate. Signed-off-by: Sebastian Ott Reviewed-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/pci/pci_dma.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index e595e89eac65..1ea8c07eab84 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -457,7 +457,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) zdev->dma_table = dma_alloc_cpu_table(); if (!zdev->dma_table) { rc = -ENOMEM; - goto out_clean; + goto out; } /* @@ -477,18 +477,22 @@ int zpci_dma_init_device(struct zpci_dev *zdev) zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); if (!zdev->iommu_bitmap) { rc = -ENOMEM; - goto out_reg; + goto free_dma_table; } rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, (u64) zdev->dma_table); if (rc) - goto out_reg; - return 0; + goto free_bitmap; -out_reg: + return 0; +free_bitmap: + vfree(zdev->iommu_bitmap); + zdev->iommu_bitmap = NULL; +free_dma_table: dma_free_cpu_table(zdev->dma_table); -out_clean: + zdev->dma_table = NULL; +out: return rc; } -- cgit v1.2.3 From 723cacbd9dc79582e562c123a0bacf8bfc69e72a Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Fri, 15 Apr 2016 16:38:40 +0200 Subject: s390/mm: fix asce_bits handling with dynamic pagetable levels There is a race with multi-threaded applications between context switch and pagetable upgrade. In switch_mm() a new user_asce is built from mm->pgd and mm->context.asce_bits, w/o holding any locks. A concurrent mmap with a pagetable upgrade on another thread in crst_table_upgrade() could already have set new asce_bits, but not yet the new mm->pgd. This would result in a corrupt user_asce in switch_mm(), and eventually in a kernel panic from a translation exception. Fix this by storing the complete asce instead of just the asce_bits, which can then be read atomically from switch_mm(), so that it either sees the old value or the new value, but no mixture. Both cases are OK. Having the old value would result in a page fault on access to the higher level memory, but the fault handler would see the new mm->pgd, if it was a valid access after the mmap on the other thread has completed. So as worst-case scenario we would have a page fault loop for the racing thread until the next time slice. Also remove dead code and simplify the upgrade/downgrade path, there are no upgrades from 2 levels, and only downgrades from 3 levels for compat tasks. There are also no concurrent upgrades, because the mmap_sem is held with down_write() in do_mmap, so the flush and table checks during upgrade can be removed. Reported-by: Michael Munday Reviewed-by: Martin Schwidefsky Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/mmu.h | 2 +- arch/s390/include/asm/mmu_context.h | 28 +++++++++--- arch/s390/include/asm/pgalloc.h | 4 +- arch/s390/include/asm/processor.h | 2 +- arch/s390/include/asm/tlbflush.h | 9 ++-- arch/s390/mm/init.c | 3 +- arch/s390/mm/mmap.c | 6 +-- arch/s390/mm/pgalloc.c | 85 ++++++++++++------------------------- 8 files changed, 62 insertions(+), 77 deletions(-) diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index d29ad9545b41..081b2ad99d73 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h @@ -11,7 +11,7 @@ typedef struct { spinlock_t list_lock; struct list_head pgtable_list; struct list_head gmap_list; - unsigned long asce_bits; + unsigned long asce; unsigned long asce_limit; unsigned long vdso_base; /* The mmu context allocates 4K page tables. */ diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index d321469eeda7..c837b79b455d 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -26,12 +26,28 @@ static inline int init_new_context(struct task_struct *tsk, mm->context.has_pgste = 0; mm->context.use_skey = 0; #endif - if (mm->context.asce_limit == 0) { + switch (mm->context.asce_limit) { + case 1UL << 42: + /* + * forked 3-level task, fall through to set new asce with new + * mm->pgd + */ + case 0: /* context created by exec, set asce limit to 4TB */ - mm->context.asce_bits = _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | _ASCE_TYPE_REGION3; mm->context.asce_limit = STACK_TOP_MAX; - } else if (mm->context.asce_limit == (1UL << 31)) { + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_REGION3; + break; + case 1UL << 53: + /* forked 4-level task, set new asce with new mm->pgd */ + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_REGION2; + break; + case 1UL << 31: + /* forked 2-level compat task, set new asce with new mm->pgd */ + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; + /* pgd_alloc() did not increase mm->nr_pmds */ mm_inc_nr_pmds(mm); } crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); @@ -42,7 +58,7 @@ static inline int init_new_context(struct task_struct *tsk, static inline void set_user_asce(struct mm_struct *mm) { - S390_lowcore.user_asce = mm->context.asce_bits | __pa(mm->pgd); + S390_lowcore.user_asce = mm->context.asce; if (current->thread.mm_segment.ar4) __ctl_load(S390_lowcore.user_asce, 7, 7); set_cpu_flag(CIF_ASCE); @@ -71,7 +87,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, { int cpu = smp_processor_id(); - S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd); + S390_lowcore.user_asce = next->context.asce; if (prev == next) return; if (MACHINE_HAS_TLB_LC) diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index 9b3d9b6099f2..da34cb6b1f3b 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -52,8 +52,8 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) return _REGION2_ENTRY_EMPTY; } -int crst_table_upgrade(struct mm_struct *, unsigned long limit); -void crst_table_downgrade(struct mm_struct *, unsigned long limit); +int crst_table_upgrade(struct mm_struct *); +void crst_table_downgrade(struct mm_struct *); static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) { diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index d6fd22ea270d..18cdede1aeda 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -175,7 +175,7 @@ extern __vector128 init_task_fpu_regs[__NUM_VXRS]; regs->psw.mask = PSW_USER_BITS | PSW_MASK_BA; \ regs->psw.addr = new_psw; \ regs->gprs[15] = new_stackp; \ - crst_table_downgrade(current->mm, 1UL << 31); \ + crst_table_downgrade(current->mm); \ execve_tail(); \ } while (0) diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index ca148f7c3eaa..a2e6ef32e054 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h @@ -110,8 +110,7 @@ static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce) static inline void __tlb_flush_kernel(void) { if (MACHINE_HAS_IDTE) - __tlb_flush_idte((unsigned long) init_mm.pgd | - init_mm.context.asce_bits); + __tlb_flush_idte(init_mm.context.asce); else __tlb_flush_global(); } @@ -133,8 +132,7 @@ static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce) static inline void __tlb_flush_kernel(void) { if (MACHINE_HAS_TLB_LC) - __tlb_flush_idte_local((unsigned long) init_mm.pgd | - init_mm.context.asce_bits); + __tlb_flush_idte_local(init_mm.context.asce); else __tlb_flush_local(); } @@ -148,8 +146,7 @@ static inline void __tlb_flush_mm(struct mm_struct * mm) * only ran on the local cpu. */ if (MACHINE_HAS_IDTE && list_empty(&mm->context.gmap_list)) - __tlb_flush_asce(mm, (unsigned long) mm->pgd | - mm->context.asce_bits); + __tlb_flush_asce(mm, mm->context.asce); else __tlb_flush_full(mm); } diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index c7b0451397d6..2489b2e917c8 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -89,7 +89,8 @@ void __init paging_init(void) asce_bits = _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH; pgd_type = _REGION3_ENTRY_EMPTY; } - S390_lowcore.kernel_asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits; + init_mm.context.asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits; + S390_lowcore.kernel_asce = init_mm.context.asce; clear_table((unsigned long *) init_mm.pgd, pgd_type, sizeof(unsigned long)*2048); vmem_map_init(); diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 45c4daa49930..89cf09e5f168 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -174,7 +174,7 @@ int s390_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) if (!(flags & MAP_FIXED)) addr = 0; if ((addr + len) >= TASK_SIZE) - return crst_table_upgrade(current->mm, TASK_MAX_SIZE); + return crst_table_upgrade(current->mm); return 0; } @@ -191,7 +191,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, return area; if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) { /* Upgrade the page table to 4 levels and retry. */ - rc = crst_table_upgrade(mm, TASK_MAX_SIZE); + rc = crst_table_upgrade(mm); if (rc) return (unsigned long) rc; area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); @@ -213,7 +213,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, return area; if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < TASK_MAX_SIZE) { /* Upgrade the page table to 4 levels and retry. */ - rc = crst_table_upgrade(mm, TASK_MAX_SIZE); + rc = crst_table_upgrade(mm); if (rc) return (unsigned long) rc; area = arch_get_unmapped_area_topdown(filp, addr, len, diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c index f6c3de26cda8..e8b5962ac12a 100644 --- a/arch/s390/mm/pgalloc.c +++ b/arch/s390/mm/pgalloc.c @@ -76,81 +76,52 @@ static void __crst_table_upgrade(void *arg) __tlb_flush_local(); } -int crst_table_upgrade(struct mm_struct *mm, unsigned long limit) +int crst_table_upgrade(struct mm_struct *mm) { unsigned long *table, *pgd; - unsigned long entry; - int flush; - BUG_ON(limit > TASK_MAX_SIZE); - flush = 0; -repeat: + /* upgrade should only happen from 3 to 4 levels */ + BUG_ON(mm->context.asce_limit != (1UL << 42)); + table = crst_table_alloc(mm); if (!table) return -ENOMEM; + spin_lock_bh(&mm->page_table_lock); - if (mm->context.asce_limit < limit) { - pgd = (unsigned long *) mm->pgd; - if (mm->context.asce_limit <= (1UL << 31)) { - entry = _REGION3_ENTRY_EMPTY; - mm->context.asce_limit = 1UL << 42; - mm->context.asce_bits = _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | - _ASCE_TYPE_REGION3; - } else { - entry = _REGION2_ENTRY_EMPTY; - mm->context.asce_limit = 1UL << 53; - mm->context.asce_bits = _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | - _ASCE_TYPE_REGION2; - } - crst_table_init(table, entry); - pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); - mm->pgd = (pgd_t *) table; - mm->task_size = mm->context.asce_limit; - table = NULL; - flush = 1; - } + pgd = (unsigned long *) mm->pgd; + crst_table_init(table, _REGION2_ENTRY_EMPTY); + pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); + mm->pgd = (pgd_t *) table; + mm->context.asce_limit = 1UL << 53; + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_REGION2; + mm->task_size = mm->context.asce_limit; spin_unlock_bh(&mm->page_table_lock); - if (table) - crst_table_free(mm, table); - if (mm->context.asce_limit < limit) - goto repeat; - if (flush) - on_each_cpu(__crst_table_upgrade, mm, 0); + + on_each_cpu(__crst_table_upgrade, mm, 0); return 0; } -void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) +void crst_table_downgrade(struct mm_struct *mm) { pgd_t *pgd; + /* downgrade should only happen from 3 to 2 levels (compat only) */ + BUG_ON(mm->context.asce_limit != (1UL << 42)); + if (current->active_mm == mm) { clear_user_asce(); __tlb_flush_mm(mm); } - while (mm->context.asce_limit > limit) { - pgd = mm->pgd; - switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) { - case _REGION_ENTRY_TYPE_R2: - mm->context.asce_limit = 1UL << 42; - mm->context.asce_bits = _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | - _ASCE_TYPE_REGION3; - break; - case _REGION_ENTRY_TYPE_R3: - mm->context.asce_limit = 1UL << 31; - mm->context.asce_bits = _ASCE_TABLE_LENGTH | - _ASCE_USER_BITS | - _ASCE_TYPE_SEGMENT; - break; - default: - BUG(); - } - mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); - mm->task_size = mm->context.asce_limit; - crst_table_free(mm, (unsigned long *) pgd); - } + + pgd = mm->pgd; + mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); + mm->context.asce_limit = 1UL << 31; + mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | + _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; + mm->task_size = mm->context.asce_limit; + crst_table_free(mm, (unsigned long *) pgd); + if (current->active_mm == mm) set_user_asce(mm); } -- cgit v1.2.3 From fe1bce9e2107ba3a8faffe572483b6974201a0e6 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Wed, 20 Apr 2016 20:09:24 -0700 Subject: futex: Acknowledge a new waiter in counter before plist Otherwise an incoming waker on the dest hash bucket can miss the waiter adding itself to the plist during the lockless check optimization (small window but still the correct way of doing this); similarly to the decrement counterpart. Suggested-by: Peter Zijlstra Signed-off-by: Davidlohr Bueso Cc: Davidlohr Bueso Cc: bigeasy@linutronix.de Cc: dvhart@infradead.org Cc: stable@kernel.org Link: http://lkml.kernel.org/r/1461208164-29150-1-git-send-email-dave@stgolabs.net Signed-off-by: Thomas Gleixner --- kernel/futex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/futex.c b/kernel/futex.c index fd204e1670c9..c20f06f38ef3 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1535,8 +1535,8 @@ void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1, if (likely(&hb1->chain != &hb2->chain)) { plist_del(&q->list, &hb1->chain); hb_waiters_dec(hb1); - plist_add(&q->list, &hb2->chain); hb_waiters_inc(hb2); + plist_add(&q->list, &hb2->chain); q->lock_ptr = &hb2->lock; } get_futex_key_refs(key2); -- cgit v1.2.3 From fba7cd681b6155e2d93e7862fcd6f970336b83c3 Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Thu, 14 Apr 2016 15:36:03 +0200 Subject: asm-generic/futex: Re-enable preemption in futex_atomic_cmpxchg_inatomic() The recent decoupling of pagefault disable and preempt disable added an explicit preempt_disable/enable() pair to the futex_atomic_cmpxchg_inatomic() implementation in asm-generic/futex.h. But it forgot to add preempt_enable() calls to the error handling code pathes, which results in a preemption count imbalance. This is observable on boot when the test for atomic_cmpxchg() is calling futex_atomic_cmpxchg_inatomic() on a NULL pointer. Add the missing preempt_enable() calls to the error handling code pathes. [ tglx: Massaged changelog ] Fixes: d9b9ff8c1889 ("sched/preempt, futex: Disable preemption in UP futex_atomic_cmpxchg_inatomic() explicitly") Signed-off-by: Romain Perier Cc: linux-arch@vger.kernel.org Cc: Thomas Petazzoni Cc: Arnd Bergmann Cc: Peter Zijlstra Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1460640963-690-1-git-send-email-romain.perier@free-electrons.com Signed-off-by: Thomas Gleixner --- include/asm-generic/futex.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/asm-generic/futex.h b/include/asm-generic/futex.h index e56272c919b5..bf2d34c9d804 100644 --- a/include/asm-generic/futex.h +++ b/include/asm-generic/futex.h @@ -108,11 +108,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 val; preempt_disable(); - if (unlikely(get_user(val, uaddr) != 0)) + if (unlikely(get_user(val, uaddr) != 0)) { + preempt_enable(); return -EFAULT; + } - if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) + if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) { + preempt_enable(); return -EFAULT; + } *uval = val; preempt_enable(); -- cgit v1.2.3 From 4589f450fb285ab85f7513b6649e51ec2a820653 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Thu, 21 Apr 2016 10:08:32 +0100 Subject: genirq: Dont allow affinity mask to be updated on IPIs The IPI domain re-purposes the IRQ affinity to signify the mask of CPUs that this IPI will deliver to. This must not be modified before the IPI is destroyed again, so set the IRQ_NO_BALANCING flag to prevent the affinity being overwritten by setup_affinity(). Without this, if an IPI is reserved for a single target CPU, then allocated using __setup_irq(), the affinity is overwritten with cpu_online_mask. When ipi_destroy() is subsequently called on a multi-cpu system, it will attempt to free cpumask_weight() IRQs that were never allocated, and crash. Fixes: d17bf24e6952 ("genirq: Add a new generic IPI reservation code to irq core") Signed-off-by: Matt Redfearn Cc: linux-mips@linux-mips.org Cc: jason@lakedaemon.net Cc: marc.zyngier@arm.com Cc: ralf@linux-mips.org Cc: Qais Yousef Cc: lisa.parratt@imgtec.com Link: http://lkml.kernel.org/r/1461229712-13057-1-git-send-email-matt.redfearn@imgtec.com Signed-off-by: Thomas Gleixner --- kernel/irq/ipi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c index c37f34b00a11..14777af8e097 100644 --- a/kernel/irq/ipi.c +++ b/kernel/irq/ipi.c @@ -94,6 +94,7 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain, data = irq_get_irq_data(virq + i); cpumask_copy(data->common->affinity, dest); data->common->ipi_offset = offset; + irq_set_status_flags(virq + i, IRQ_NO_BALANCING); } return virq; -- cgit v1.2.3 From 2144fff7df8e76654fa72b0a9d2324ce2e0c8a5c Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 21 Apr 2016 13:52:38 +0200 Subject: drm/etnaviv: don't move linear memory window on 3D cores without MC2.0 On cores with MC1.0 the memory window offset is not properly respected by all engines in the core, leading to different views of the memory if the offset in non-zero. This causes relocs for those engines to be wrong and might lead to other subtile problems. Rather than trying to work around this, just disable the linear memory window offset for those cores. Suggested-by: Russell King Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 09198d0b5814..306dde18a94a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -572,6 +572,24 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) goto fail; } + /* + * Set the GPU linear window to be at the end of the DMA window, where + * the CMA area is likely to reside. This ensures that we are able to + * map the command buffers while having the linear window overlap as + * much RAM as possible, so we can optimize mappings for other buffers. + * + * For 3D cores only do this if MC2.0 is present, as with MC1.0 it leads + * to different views of the memory on the individual engines. + */ + if (!(gpu->identity.features & chipFeatures_PIPE_3D) || + (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) { + u32 dma_mask = (u32)dma_get_required_mask(gpu->dev); + if (dma_mask < PHYS_OFFSET + SZ_2G) + gpu->memory_base = PHYS_OFFSET; + else + gpu->memory_base = dma_mask - SZ_2G + 1; + } + ret = etnaviv_hw_reset(gpu); if (ret) goto fail; @@ -1566,7 +1584,6 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct etnaviv_gpu *gpu; - u32 dma_mask; int err = 0; gpu = devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL); @@ -1576,18 +1593,6 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) gpu->dev = &pdev->dev; mutex_init(&gpu->lock); - /* - * Set the GPU linear window to be at the end of the DMA window, where - * the CMA area is likely to reside. This ensures that we are able to - * map the command buffers while having the linear window overlap as - * much RAM as possible, so we can optimize mappings for other buffers. - */ - dma_mask = (u32)dma_get_required_mask(dev); - if (dma_mask < PHYS_OFFSET + SZ_2G) - gpu->memory_base = PHYS_OFFSET; - else - gpu->memory_base = dma_mask - SZ_2G + 1; - /* Map registers: */ gpu->mmio = etnaviv_ioremap(pdev, NULL, dev_name(gpu->dev)); if (IS_ERR(gpu->mmio)) -- cgit v1.2.3 From d4f6e272f2600bc1295d195a52a9e8bb81656bc7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 14 Apr 2016 12:33:37 +0300 Subject: firmware: qemu_fw_cfg.c: potential unintialized variable It acpi_acquire_global_lock() return AE_NOT_CONFIGURED then "glk" isn't initialized, which, if you got very unlucky, could cause a bug. Signed-off-by: Dan Carpenter Signed-off-by: Michael S. Tsirkin --- drivers/firmware/qemu_fw_cfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 815c4a5cae54..1b95475b6aef 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -77,7 +77,7 @@ static inline u16 fw_cfg_sel_endianness(u16 key) static inline void fw_cfg_read_blob(u16 key, void *buf, loff_t pos, size_t count) { - u32 glk; + u32 glk = -1U; acpi_status status; /* If we have ACPI, ensure mutual exclusion against any potential -- cgit v1.2.3 From cbcc72e037b8a3eb1fad3c1ae22021df21c97a51 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Thu, 21 Apr 2016 10:24:34 +0100 Subject: drivers/perf: arm-pmu: fix RCU usage on pmu resume from low-power Commit da4e4f18afe0 ("drivers/perf: arm_pmu: implement CPU_PM notifier") added code in the arm perf infrastructure that allows the kernel to save/restore perf counters whenever the CPU enters a low-power state. The kernel saves/restores the counters for each active event through the armpmu_{stop/start} ARM pmu API, so that the low-power state enter/exit cycle is emulated through pmu start/stop operations for each event in use. However, calling armpmu_start() for each active event on power up executes code that requires RCU locking (perf_event_update_userpage()) to be functional, so, given that the core may call the CPU_PM notifiers while running the idle thread in an quiescent RCU state this is not allowed as detected through the following splat when kernel is run with CONFIG_PROVE_LOCKING enabled: [ 49.293286] [ 49.294761] =============================== [ 49.298895] [ INFO: suspicious RCU usage. ] [ 49.303031] 4.6.0-rc3+ #421 Not tainted [ 49.306821] ------------------------------- [ 49.310956] include/linux/rcupdate.h:872 rcu_read_lock() used illegally while idle! [ 49.318530] [ 49.318530] other info that might help us debug this: [ 49.318530] [ 49.326451] [ 49.326451] RCU used illegally from idle CPU! [ 49.326451] rcu_scheduler_active = 1, debug_locks = 0 [ 49.337209] RCU used illegally from extended quiescent state! [ 49.342892] 2 locks held by swapper/2/0: [ 49.346768] #0: (cpu_pm_notifier_lock){......}, at: [] cpu_pm_exit+0x18/0x80 [ 49.355492] #1: (rcu_read_lock){......}, at: [] perf_event_update_userpage+0x0/0x260 This patch wraps the armpmu_start() call (that indirectly calls perf_event_update_userpage()) on CPU_PM notifier power state exit (or failed entry) within the RCU_NONIDLE() macro so that the RCU subsystem is made aware the calling cpu is not idle from an RCU perspective for the armpmu_start() call duration, therefore fixing the issue. Fixes: da4e4f18afe0 ("drivers/perf: arm_pmu: implement CPU_PM notifier") Signed-off-by: Lorenzo Pieralisi Reported-by: James Morse Suggested-by: Kevin Hilman Cc: Ashwin Chaugule Cc: Kevin Hilman Cc: Sudeep Holla Cc: Daniel Lezcano Cc: Mathieu Poirier Acked-by: Mark Rutland Acked-by: Paul E. McKenney Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- drivers/perf/arm_pmu.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 32346b5a8a11..f70090897fdf 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -737,8 +737,19 @@ static void cpu_pm_pmu_setup(struct arm_pmu *armpmu, unsigned long cmd) break; case CPU_PM_EXIT: case CPU_PM_ENTER_FAILED: - /* Restore and enable the counter */ - armpmu_start(event, PERF_EF_RELOAD); + /* + * Restore and enable the counter. + * armpmu_start() indirectly calls + * + * perf_event_update_userpage() + * + * that requires RCU read locking to be functional, + * wrap the call within RCU_NONIDLE to make the + * RCU subsystem aware this cpu is not idle from + * an RCU perspective for the armpmu_start() call + * duration. + */ + RCU_NONIDLE(armpmu_start(event, PERF_EF_RELOAD)); break; default: break; -- cgit v1.2.3 From 5f634956cc550768ebd75cf26fdba01044bc600e Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 20 Apr 2016 14:53:32 +0100 Subject: iommu/arm-smmu: Fix stream-match conflict with IOMMU_DOMAIN_DMA Commit cbf8277ef456 ("iommu/arm-smmu: Treat IOMMU_DOMAIN_DMA as bypass for now") ignores requests to attach a device to the default domain since, without IOMMU-basked DMA ops available everywhere, the default domain will just lead to unexpected transaction faults being reported. Unfortunately, the way this was implemented on SMMUv2 causes a regression with VFIO PCI device passthrough under KVM on AMD Seattle. On this system, the host controller device is associated with both a pci_dev *and* a platform_device, and can therefore end up with duplicate SMR entries, resulting in a stream-match conflict at runtime. This patch amends the original fix so that attaching to IOMMU_DOMAIN_DMA is rejected even before configuring the SMRs. This restores the old behaviour for now, but we'll need to look at handing host controllers specially when we come to supporting the default domain fully. Reported-by: Eric Auger Tested-by: Eric Auger Tested-by: Yang Shi Signed-off-by: Will Deacon Signed-off-by: Joerg Roedel --- drivers/iommu/arm-smmu.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 2409e3bd3df2..5158febd889d 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1089,18 +1089,20 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, struct arm_smmu_device *smmu = smmu_domain->smmu; void __iomem *gr0_base = ARM_SMMU_GR0(smmu); - /* Devices in an IOMMU group may already be configured */ - ret = arm_smmu_master_configure_smrs(smmu, cfg); - if (ret) - return ret == -EEXIST ? 0 : ret; - /* * FIXME: This won't be needed once we have IOMMU-backed DMA ops - * for all devices behind the SMMU. + * for all devices behind the SMMU. Note that we need to take + * care configuring SMRs for devices both a platform_device and + * and a PCI device (i.e. a PCI host controller) */ if (smmu_domain->domain.type == IOMMU_DOMAIN_DMA) return 0; + /* Devices in an IOMMU group may already be configured */ + ret = arm_smmu_master_configure_smrs(smmu, cfg); + if (ret) + return ret == -EEXIST ? 0 : ret; + for (i = 0; i < cfg->num_streamids; ++i) { u32 idx, s2cr; -- cgit v1.2.3 From 9800699c645952da6a7399194d3e762b84cde3cd Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Wed, 20 Apr 2016 14:53:33 +0100 Subject: iommu/arm-smmu: Don't allocate resources for bypass domains Until we get fully plumbed into of_iommu_configure, our default IOMMU_DOMAIN_DMA domains just bypass translation. Since we achieve that by leaving the stream table entries set to bypass instead of pointing at a translation context, the context bank we allocate for the domain is completely wasted. Context banks are typically a rather limited resource, so don't hog ones we don't need. Reported-by: Eric Auger Tested-by: Eric Auger Signed-off-by: Robin Murphy Signed-off-by: Will Deacon Signed-off-by: Joerg Roedel --- drivers/iommu/arm-smmu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 5158febd889d..7c39ac4b9c53 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -826,6 +826,12 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, if (smmu_domain->smmu) goto out_unlock; + /* We're bypassing these SIDs, so don't allocate an actual context */ + if (domain->type == IOMMU_DOMAIN_DMA) { + smmu_domain->smmu = smmu; + goto out_unlock; + } + /* * Mapping the requested stage onto what we support is surprisingly * complicated, mainly because the spec allows S1+S2 SMMUs without @@ -948,7 +954,7 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) void __iomem *cb_base; int irq; - if (!smmu) + if (!smmu || domain->type == IOMMU_DOMAIN_DMA) return; /* -- cgit v1.2.3 From 67f3754b51f22b18c4820fb84062f658c30e8644 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Apr 2016 17:37:54 +0200 Subject: ALSA: pcxhr: Fix missing mutex unlock The commit [9bef72bdb26e: ALSA: pcxhr: Use nonatomic PCM ops] converted to non-atomic PCM ops, but shamelessly with an unbalanced mutex locking, which leads to the hangup easily. Fix it. Fixes: 9bef72bdb26e ('ALSA: pcxhr: Use nonatomic PCM ops') Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=116441 Cc: # 3.18+ Signed-off-by: Takashi Iwai --- sound/pci/pcxhr/pcxhr_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index c5194f5b150a..d7e71f309299 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -1341,5 +1341,6 @@ irqreturn_t pcxhr_threaded_irq(int irq, void *dev_id) } pcxhr_msg_thread(mgr); + mutex_unlock(&mgr->lock); return IRQ_HANDLED; } -- cgit v1.2.3 From 3194ed497939c6448005542e3ca4fa2386968fa0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Apr 2016 17:49:11 +0200 Subject: ALSA: hda - Fix possible race on regmap bypass flip HD-audio driver uses regmap cache bypass feature for reading a raw value without the cache. But this is racy since both the cached and the uncached reads may occur concurrently. The former is done via the normal control API access while the latter comes from the proc file read. Even though the regmap itself has the protection against the concurrent accesses, the flag set/reset is done without the protection, so it may lead to inconsistent state of bypass flag that doesn't match with the current read and occasionally result in a kernel WARNING like: WARNING: CPU: 3 PID: 2731 at drivers/base/regmap/regcache.c:499 regcache_cache_only+0x78/0x93 One way to work around such a problem is to wrap with a mutex. But in this case, the solution is simpler: for the uncached read, we just skip the regmap and directly calls its accessor. The verb execution there is protected by itself, so basically it's safe to call individually. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=116171 Signed-off-by: Takashi Iwai --- include/sound/hda_regmap.h | 2 ++ sound/hda/hdac_device.c | 10 ++++------ sound/hda/hdac_regmap.c | 40 ++++++++++++++++++++++++++++------------ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/include/sound/hda_regmap.h b/include/sound/hda_regmap.h index 2767c55a641e..ca64f0f50b45 100644 --- a/include/sound/hda_regmap.h +++ b/include/sound/hda_regmap.h @@ -17,6 +17,8 @@ int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec, unsigned int verb); int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg, unsigned int *val); +int snd_hdac_regmap_read_raw_uncached(struct hdac_device *codec, + unsigned int reg, unsigned int *val); int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg, unsigned int val); int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg, diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c index d1a4d6973330..03c9872c31cf 100644 --- a/sound/hda/hdac_device.c +++ b/sound/hda/hdac_device.c @@ -299,13 +299,11 @@ EXPORT_SYMBOL_GPL(_snd_hdac_read_parm); int snd_hdac_read_parm_uncached(struct hdac_device *codec, hda_nid_t nid, int parm) { - int val; + unsigned int cmd, val; - if (codec->regmap) - regcache_cache_bypass(codec->regmap, true); - val = snd_hdac_read_parm(codec, nid, parm); - if (codec->regmap) - regcache_cache_bypass(codec->regmap, false); + cmd = snd_hdac_regmap_encode_verb(nid, AC_VERB_PARAMETERS) | parm; + if (snd_hdac_regmap_read_raw_uncached(codec, cmd, &val) < 0) + return -1; return val; } EXPORT_SYMBOL_GPL(snd_hdac_read_parm_uncached); diff --git a/sound/hda/hdac_regmap.c b/sound/hda/hdac_regmap.c index bdbcd6b75ff6..87041ddd29cb 100644 --- a/sound/hda/hdac_regmap.c +++ b/sound/hda/hdac_regmap.c @@ -453,14 +453,30 @@ int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg, EXPORT_SYMBOL_GPL(snd_hdac_regmap_write_raw); static int reg_raw_read(struct hdac_device *codec, unsigned int reg, - unsigned int *val) + unsigned int *val, bool uncached) { - if (!codec->regmap) + if (uncached || !codec->regmap) return hda_reg_read(codec, reg, val); else return regmap_read(codec->regmap, reg, val); } +static int __snd_hdac_regmap_read_raw(struct hdac_device *codec, + unsigned int reg, unsigned int *val, + bool uncached) +{ + int err; + + err = reg_raw_read(codec, reg, val, uncached); + if (err == -EAGAIN) { + err = snd_hdac_power_up_pm(codec); + if (!err) + err = reg_raw_read(codec, reg, val, uncached); + snd_hdac_power_down_pm(codec); + } + return err; +} + /** * snd_hdac_regmap_read_raw - read a pseudo register with power mgmt * @codec: the codec object @@ -472,19 +488,19 @@ static int reg_raw_read(struct hdac_device *codec, unsigned int reg, int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg, unsigned int *val) { - int err; - - err = reg_raw_read(codec, reg, val); - if (err == -EAGAIN) { - err = snd_hdac_power_up_pm(codec); - if (!err) - err = reg_raw_read(codec, reg, val); - snd_hdac_power_down_pm(codec); - } - return err; + return __snd_hdac_regmap_read_raw(codec, reg, val, false); } EXPORT_SYMBOL_GPL(snd_hdac_regmap_read_raw); +/* Works like snd_hdac_regmap_read_raw(), but this doesn't read from the + * cache but always via hda verbs. + */ +int snd_hdac_regmap_read_raw_uncached(struct hdac_device *codec, + unsigned int reg, unsigned int *val) +{ + return __snd_hdac_regmap_read_raw(codec, reg, val, true); +} + /** * snd_hdac_regmap_update_raw - update a pseudo register with power mgmt * @codec: the codec object -- cgit v1.2.3 From 882416c1e4d1c9d4c7b50e0f5c3fa9ef043cd710 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 18 Apr 2016 18:57:26 +0100 Subject: arm64: Fix EL1/EL2 early init inconsistencies with VHE When using the Virtualisation Host Extensions, EL1 is not used in the host and requires no separate configuration. In addition, with VHE enabled, non-hyp-specific EL2 configuration that does not need to be done early will be done anyway in __cpu_setup via the _EL1 system register aliases. In particular, the layout and definition of CPTR_EL2 are changed by enabling VHE so that they resemble CPACR_EL1, so existing code to initialise CPTR_EL2 becomes architecturally wrong in this case. This patch simply skips the affected initialisation code in the non-VHE case. Signed-off-by: Dave Martin Reviewed-by: Marc Zyngier Signed-off-by: Catalin Marinas --- arch/arm64/kernel/head.S | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 80a709aa211a..85da0f599cd6 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -588,6 +588,15 @@ set_hcr: msr vpidr_el2, x0 msr vmpidr_el2, x1 + /* + * When VHE is not in use, early init of EL2 and EL1 needs to be + * done here. + * When VHE _is_ in use, EL1 will not be used in the host and + * requires no configuration, and all non-hyp-specific EL2 setup + * will be done via the _EL1 system register aliases in __cpu_setup. + */ + cbnz x2, 1f + /* sctlr_el1 */ mov x0, #0x0800 // Set/clear RES{1,0} bits CPU_BE( movk x0, #0x33d0, lsl #16 ) // Set EE and E0E on BE systems @@ -597,6 +606,7 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems /* Coprocessor traps. */ mov x0, #0x33ff msr cptr_el2, x0 // Disable copro. traps to EL2 +1: #ifdef CONFIG_COMPAT msr hstr_el2, xzr // Disable CP15 traps to EL2 -- cgit v1.2.3 From 49e261a8a21e0960a3f7ff187a453ba1c1149053 Mon Sep 17 00:00:00 2001 From: Joe Stringer Date: Mon, 18 Apr 2016 14:51:47 -0700 Subject: openvswitch: Orphan skbs before IPv6 defrag This is the IPv6 counterpart to commit 8282f27449bf ("inet: frag: Always orphan skbs inside ip_defrag()"). Prior to commit 029f7f3b8701 ("netfilter: ipv6: nf_defrag: avoid/free clone operations"), ipv6 fragments sent to nf_ct_frag6_gather() would be cloned (implicitly orphaning) prior to queueing for reassembly. As such, when the IPv6 message is eventually reassembled, the skb->sk for all fragments would be NULL. After that commit was introduced, rather than cloning, the original skbs were queued directly without orphaning. The end result is that all frags except for the first and last may have a socket attached. This commit explicitly orphans such skbs during nf_ct_frag6_gather() to prevent BUG_ON(skb->sk) during a later call to ip6_fragment(). kernel BUG at net/ipv6/ip6_output.c:631! [...] Call Trace: [] ? __lock_acquire+0x927/0x20a0 [] ? do_output.isra.28+0x1b0/0x1b0 [openvswitch] [] ? __lock_is_held+0x52/0x70 [] ovs_fragment+0x1f7/0x280 [openvswitch] [] ? mark_held_locks+0x75/0xa0 [] ? _raw_spin_unlock_irqrestore+0x36/0x50 [] ? dst_discard_out+0x20/0x20 [] ? dst_ifdown+0x80/0x80 [] do_output.isra.28+0xf3/0x1b0 [openvswitch] [] do_execute_actions+0x709/0x12c0 [openvswitch] [] ? ovs_flow_stats_update+0x74/0x1e0 [openvswitch] [] ? ovs_flow_stats_update+0xa1/0x1e0 [openvswitch] [] ? _raw_spin_unlock+0x27/0x40 [] ovs_execute_actions+0x45/0x120 [openvswitch] [] ovs_dp_process_packet+0x85/0x150 [openvswitch] [] ? _raw_spin_unlock+0x27/0x40 [] ovs_execute_actions+0xc4/0x120 [openvswitch] [] ovs_dp_process_packet+0x85/0x150 [openvswitch] [] ? key_extract+0x442/0xc10 [openvswitch] [] ovs_vport_receive+0x5d/0xb0 [openvswitch] [] ? __lock_acquire+0x927/0x20a0 [] ? __lock_acquire+0x927/0x20a0 [] ? __lock_acquire+0x927/0x20a0 [] ? _raw_spin_unlock_irqrestore+0x36/0x50 [] internal_dev_xmit+0x6d/0x150 [openvswitch] [] ? internal_dev_xmit+0x5/0x150 [openvswitch] [] dev_hard_start_xmit+0x2df/0x660 [] ? validate_xmit_skb.isra.105.part.106+0x1a/0x2b0 [] __dev_queue_xmit+0x8f5/0x950 [] ? __dev_queue_xmit+0x50/0x950 [] ? mark_held_locks+0x75/0xa0 [] dev_queue_xmit+0x10/0x20 [] neigh_resolve_output+0x178/0x220 [] ? ip6_finish_output2+0x219/0x7b0 [] ip6_finish_output2+0x219/0x7b0 [] ? ip6_finish_output2+0x65/0x7b0 [] ? ip_idents_reserve+0x6b/0x80 [] ? ip6_fragment+0x93f/0xc50 [] ip6_fragment+0xba1/0xc50 [] ? ip6_flush_pending_frames+0x40/0x40 [] ip6_finish_output+0xcb/0x1d0 [] ip6_output+0x5f/0x1a0 [] ? ip6_fragment+0xc50/0xc50 [] ip6_local_out+0x3d/0x80 [] ip6_send_skb+0x2f/0xc0 [] ip6_push_pending_frames+0x4d/0x50 [] icmpv6_push_pending_frames+0xac/0xe0 [] icmpv6_echo_reply+0x42e/0x500 [] icmpv6_rcv+0x4cf/0x580 [] ip6_input_finish+0x1a7/0x690 [] ? ip6_input_finish+0x5/0x690 [] ip6_input+0x30/0xa0 [] ? ip6_rcv_finish+0x1a0/0x1a0 [] ip6_rcv_finish+0x4e/0x1a0 [] ipv6_rcv+0x45f/0x7c0 [] ? ipv6_rcv+0x36/0x7c0 [] ? ip6_make_skb+0x1c0/0x1c0 [] __netif_receive_skb_core+0x229/0xb80 [] ? mark_held_locks+0x75/0xa0 [] ? process_backlog+0x6f/0x230 [] __netif_receive_skb+0x16/0x70 [] process_backlog+0x78/0x230 [] ? process_backlog+0xdd/0x230 [] net_rx_action+0x203/0x480 [] ? mark_held_locks+0x75/0xa0 [] __do_softirq+0xde/0x49f [] ? ip6_finish_output2+0x228/0x7b0 [] do_softirq_own_stack+0x1c/0x30 [] do_softirq.part.18+0x3b/0x40 [] __local_bh_enable_ip+0xb6/0xc0 [] ip6_finish_output2+0x251/0x7b0 [] ? ip6_fragment+0xba1/0xc50 [] ? ip_idents_reserve+0x6b/0x80 [] ? ip6_fragment+0x93f/0xc50 [] ip6_fragment+0xba1/0xc50 [] ? ip6_flush_pending_frames+0x40/0x40 [] ip6_finish_output+0xcb/0x1d0 [] ip6_output+0x5f/0x1a0 [] ? ip6_fragment+0xc50/0xc50 [] ip6_local_out+0x3d/0x80 [] ip6_send_skb+0x2f/0xc0 [] ip6_push_pending_frames+0x4d/0x50 [] rawv6_sendmsg+0xa28/0xe30 [] ? inet_sendmsg+0xc7/0x1d0 [] inet_sendmsg+0x106/0x1d0 [] ? inet_sendmsg+0x5/0x1d0 [] sock_sendmsg+0x38/0x50 [] SYSC_sendto+0xf6/0x170 [] ? trace_hardirqs_on_thunk+0x1b/0x1d [] SyS_sendto+0xe/0x10 [] entry_SYSCALL_64_fastpath+0x18/0xa8 Code: 06 48 83 3f 00 75 26 48 8b 87 d8 00 00 00 2b 87 d0 00 00 00 48 39 d0 72 14 8b 87 e4 00 00 00 83 f8 01 75 09 48 83 7f 18 00 74 9a <0f> 0b 41 8b 86 cc 00 00 00 49 8# RIP [] ip6_fragment+0x73a/0xc50 RSP Fixes: 029f7f3b8701 ("netfilter: ipv6: nf_defrag: avoid/free clone operations") Reported-by: Daniele Di Proietto Signed-off-by: Joe Stringer Signed-off-by: David S. Miller --- net/openvswitch/conntrack.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index 1b9d286756be..b5fea1101faa 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -367,6 +367,7 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key, } else if (key->eth.type == htons(ETH_P_IPV6)) { enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone; + skb_orphan(skb); memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm)); err = nf_ct_frag6_gather(net, skb, user); if (err) -- cgit v1.2.3 From 479f85c36688f5c855ad463b71902ef5992628b7 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Mon, 18 Apr 2016 15:39:53 -0700 Subject: tcp: Fix SOF_TIMESTAMPING_TX_ACK when handling dup acks Assuming SOF_TIMESTAMPING_TX_ACK is on. When dup acks are received, it could incorrectly think that a skb has already been acked and queue a SCM_TSTAMP_ACK cmsg to the sk->sk_error_queue. In tcp_ack_tstamp(), it checks 'between(shinfo->tskey, prior_snd_una, tcp_sk(sk)->snd_una - 1)'. If prior_snd_una == tcp_sk(sk)->snd_una like the following packetdrill script, between() returns true but the tskey is actually not acked. e.g. try between(3, 2, 1). The fix is to replace between() with one before() and one !before(). By doing this, the -1 offset on the tcp_sk(sk)->snd_una can also be removed. A packetdrill script is used to reproduce the dup ack scenario. Due to the lacking cmsg support in packetdrill (may be I cannot find it), a BPF prog is used to kprobe to sock_queue_err_skb() and print out the value of serr->ee.ee_data. Both the packetdrill and the bcc BPF script is attached at the end of this commit message. BPF Output Before Fix: ~~~~~~ <...>-2056 [001] d.s. 433.927987: : ee_data:1459 #incorrect packetdrill-2056 [001] d.s. 433.929563: : ee_data:1459 #incorrect packetdrill-2056 [001] d.s. 433.930765: : ee_data:1459 #incorrect packetdrill-2056 [001] d.s. 434.028177: : ee_data:1459 packetdrill-2056 [001] d.s. 434.029686: : ee_data:14599 BPF Output After Fix: ~~~~~~ <...>-2049 [000] d.s. 113.517039: : ee_data:1459 <...>-2049 [000] d.s. 113.517253: : ee_data:14599 BCC BPF Script: ~~~~~~ #!/usr/bin/env python from __future__ import print_function from bcc import BPF bpf_text = """ #include #include #include #include #ifdef memset #undef memset #endif int trace_err_skb(struct pt_regs *ctx) { struct sk_buff *skb = (struct sk_buff *)ctx->si; struct sock *sk = (struct sock *)ctx->di; struct sock_exterr_skb *serr; u32 ee_data = 0; if (!sk || !skb) return 0; serr = SKB_EXT_ERR(skb); bpf_probe_read(&ee_data, sizeof(ee_data), &serr->ee.ee_data); bpf_trace_printk("ee_data:%u\\n", ee_data); return 0; }; """ b = BPF(text=bpf_text) b.attach_kprobe(event="sock_queue_err_skb", fn_name="trace_err_skb") print("Attached to kprobe") b.trace_print() Packetdrill Script: ~~~~~~ +0 `sysctl -q -w net.ipv4.tcp_min_tso_segs=10` +0 `sysctl -q -w net.ipv4.tcp_no_metrics_save=1` +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0 bind(3, ..., ...) = 0 +0 listen(3, 1) = 0 0.100 < S 0:0(0) win 32792 0.100 > S. 0:0(0) ack 1 0.200 < . 1:1(0) ack 1 win 257 0.200 accept(3, ..., ...) = 4 +0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0 +0 setsockopt(4, SOL_SOCKET, 37, [2688], 4) = 0 0.200 write(4, ..., 1460) = 1460 0.200 write(4, ..., 13140) = 13140 0.200 > P. 1:1461(1460) ack 1 0.200 > . 1461:8761(7300) ack 1 0.200 > P. 8761:14601(5840) ack 1 0.300 < . 1:1(0) ack 1 win 257 0.300 < . 1:1(0) ack 1 win 257 0.300 < . 1:1(0) ack 1 win 257 0.300 > P. 1:1461(1460) ack 1 0.400 < . 1:1(0) ack 14601 win 257 0.400 close(4) = 0 0.400 > F. 14601:14601(0) ack 1 0.500 < F. 1:1(0) ack 14602 win 257 0.500 > . 14602:14602(0) ack 2 Signed-off-by: Martin KaFai Lau Cc: Eric Dumazet Cc: Neal Cardwell Cc: Soheil Hassas Yeganeh Cc: Willem de Bruijn Cc: Yuchung Cheng Acked-by: Soheil Hassas Yeganeh Tested-by: Soheil Hassas Yeganeh Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e6e65f79ade8..0edb07185c25 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3098,7 +3098,8 @@ static void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb, shinfo = skb_shinfo(skb); if ((shinfo->tx_flags & SKBTX_ACK_TSTAMP) && - between(shinfo->tskey, prior_snd_una, tcp_sk(sk)->snd_una - 1)) + !before(shinfo->tskey, prior_snd_una) && + before(shinfo->tskey, tcp_sk(sk)->snd_una)) __skb_tstamp_tx(skb, NULL, sk, SCM_TSTAMP_ACK); } -- cgit v1.2.3 From 3fa88c51c73a67e7eeda1fcafd809f9185790b31 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Tue, 19 Apr 2016 21:09:49 +0300 Subject: drivers: net: cpsw: fix wrong regs access in cpsw_ndo_open The cpsw_ndo_open() could try to access CPSW registers before calling pm_runtime_get_sync(). This will trigger L3 error: WARNING: CPU: 0 PID: 21 at drivers/bus/omap_l3_noc.c:147 l3_interrupt_handler+0x220/0x34c() 44000000.ocp:L3 Custom Error: MASTER M2 (64-bit) TARGET L4_FAST (Idle): Data Access in Supervisor mode during Functional access and CPSW will stop functioning. Hence, fix it by moving pm_runtime_get_sync() before the first access to CPSW registers in cpsw_ndo_open(). Signed-off-by: Grygorii Strashko Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 42fdfd4d9d4f..bbb77cd8ad67 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -1251,12 +1251,12 @@ static int cpsw_ndo_open(struct net_device *ndev) int i, ret; u32 reg; + pm_runtime_get_sync(&priv->pdev->dev); + if (!cpsw_common_res_usage_state(priv)) cpsw_intr_disable(priv); netif_carrier_off(ndev); - pm_runtime_get_sync(&priv->pdev->dev); - reg = priv->version; dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n", -- cgit v1.2.3 From 082ac2d51d9f19ec1c29bdaaaf7fb49889e4fade Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Tue, 19 Apr 2016 22:39:28 -0700 Subject: tcp: Merge tx_flags and tskey in tcp_collapse_retrans If two skbs are merged/collapsed during retransmission, the current logic does not merge the tx_flags and tskey. The end result is the SCM_TSTAMP_ACK timestamp could be missing for a packet. The patch: 1. Merge the tx_flags 2. Overwrite the prev_skb's tskey with the next_skb's tskey BPF Output Before: ~~~~~~ BPF Output After: ~~~~~~ packetdrill-2092 [001] d.s. 453.998486: : ee_data:1459 Packetdrill Script: ~~~~~~ +0 `sysctl -q -w net.ipv4.tcp_min_tso_segs=10` +0 `sysctl -q -w net.ipv4.tcp_no_metrics_save=1` +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0 bind(3, ..., ...) = 0 +0 listen(3, 1) = 0 0.100 < S 0:0(0) win 32792 0.100 > S. 0:0(0) ack 1 0.200 < . 1:1(0) ack 1 win 257 0.200 accept(3, ..., ...) = 4 +0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0 0.200 write(4, ..., 730) = 730 +0 setsockopt(4, SOL_SOCKET, 37, [2688], 4) = 0 0.200 write(4, ..., 730) = 730 +0 setsockopt(4, SOL_SOCKET, 37, [2176], 4) = 0 0.200 write(4, ..., 11680) = 11680 +0 setsockopt(4, SOL_SOCKET, 37, [2688], 4) = 0 0.200 > P. 1:731(730) ack 1 0.200 > P. 731:1461(730) ack 1 0.200 > . 1461:8761(7300) ack 1 0.200 > P. 8761:13141(4380) ack 1 0.300 < . 1:1(0) ack 1 win 257 0.300 < . 1:1(0) ack 1 win 257 0.300 < . 1:1(0) ack 1 win 257 0.300 > P. 1:1461(1460) ack 1 0.400 < . 1:1(0) ack 13141 win 257 0.400 close(4) = 0 0.400 > F. 13141:13141(0) ack 1 0.500 < F. 1:1(0) ack 13142 win 257 0.500 > . 13142:13142(0) ack 2 Signed-off-by: Martin KaFai Lau Cc: Eric Dumazet Cc: Neal Cardwell Cc: Soheil Hassas Yeganeh Cc: Willem de Bruijn Cc: Yuchung Cheng Acked-by: Soheil Hassas Yeganeh Tested-by: Soheil Hassas Yeganeh Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 7d2dc015cd19..5bc3c3062672 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2441,6 +2441,20 @@ u32 __tcp_select_window(struct sock *sk) return window; } +static void tcp_skb_collapse_tstamp(struct sk_buff *skb, + const struct sk_buff *next_skb) +{ + const struct skb_shared_info *next_shinfo = skb_shinfo(next_skb); + u8 tsflags = next_shinfo->tx_flags & SKBTX_ANY_TSTAMP; + + if (unlikely(tsflags)) { + struct skb_shared_info *shinfo = skb_shinfo(skb); + + shinfo->tx_flags |= tsflags; + shinfo->tskey = next_shinfo->tskey; + } +} + /* Collapses two adjacent SKB's during retransmission. */ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb) { @@ -2484,6 +2498,8 @@ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb) tcp_adjust_pcount(sk, next_skb, tcp_skb_pcount(next_skb)); + tcp_skb_collapse_tstamp(skb, next_skb); + sk_wmem_free_skb(sk, next_skb); } -- cgit v1.2.3 From cfea5a688eb37bcd1081255df9f9f777f4e61999 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Tue, 19 Apr 2016 22:39:29 -0700 Subject: tcp: Merge tx_flags and tskey in tcp_shifted_skb After receiving sacks, tcp_shifted_skb() will collapse skbs if possible. tx_flags and tskey also have to be merged. This patch reuses the tcp_skb_collapse_tstamp() to handle them. BPF Output Before: ~~~~~ BPF Output After: ~~~~~ <...>-2024 [007] d.s. 88.644374: : ee_data:14599 Packetdrill Script: ~~~~~ +0 `sysctl -q -w net.ipv4.tcp_min_tso_segs=10` +0 `sysctl -q -w net.ipv4.tcp_no_metrics_save=1` +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0 bind(3, ..., ...) = 0 +0 listen(3, 1) = 0 0.100 < S 0:0(0) win 32792 0.100 > S. 0:0(0) ack 1 0.200 < . 1:1(0) ack 1 win 257 0.200 accept(3, ..., ...) = 4 +0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0 0.200 write(4, ..., 1460) = 1460 +0 setsockopt(4, SOL_SOCKET, 37, [2688], 4) = 0 0.200 write(4, ..., 13140) = 13140 0.200 > P. 1:1461(1460) ack 1 0.200 > . 1461:8761(7300) ack 1 0.200 > P. 8761:14601(5840) ack 1 0.300 < . 1:1(0) ack 1 win 257 0.300 > P. 1:1461(1460) ack 1 0.400 < . 1:1(0) ack 14601 win 257 0.400 close(4) = 0 0.400 > F. 14601:14601(0) ack 1 0.500 < F. 1:1(0) ack 14602 win 257 0.500 > . 14602:14602(0) ack 2 Signed-off-by: Martin KaFai Lau Cc: Eric Dumazet Cc: Neal Cardwell Cc: Soheil Hassas Yeganeh Cc: Willem de Bruijn Cc: Yuchung Cheng Acked-by: Soheil Hassas Yeganeh Tested-by: Soheil Hassas Yeganeh Signed-off-by: David S. Miller --- include/net/tcp.h | 2 ++ net/ipv4/tcp_input.c | 1 + net/ipv4/tcp_output.c | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index b91370f61be6..6db10228113f 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -552,6 +552,8 @@ void tcp_send_ack(struct sock *sk); void tcp_send_delayed_ack(struct sock *sk); void tcp_send_loss_probe(struct sock *sk); bool tcp_schedule_loss_probe(struct sock *sk); +void tcp_skb_collapse_tstamp(struct sk_buff *skb, + const struct sk_buff *next_skb); /* tcp_input.c */ void tcp_resume_early_retransmit(struct sock *sk); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 0edb07185c25..c124c3c12f7c 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1309,6 +1309,7 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, if (skb == tcp_highest_sack(sk)) tcp_advance_highest_sack(sk, skb); + tcp_skb_collapse_tstamp(prev, skb); tcp_unlink_write_queue(skb, sk); sk_wmem_free_skb(sk, skb); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5bc3c3062672..441ae9da3a23 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2441,8 +2441,8 @@ u32 __tcp_select_window(struct sock *sk) return window; } -static void tcp_skb_collapse_tstamp(struct sk_buff *skb, - const struct sk_buff *next_skb) +void tcp_skb_collapse_tstamp(struct sk_buff *skb, + const struct sk_buff *next_skb) { const struct skb_shared_info *next_shinfo = skb_shinfo(next_skb); u8 tsflags = next_shinfo->tx_flags & SKBTX_ANY_TSTAMP; -- cgit v1.2.3 From f86af2dfded628034d05a2548e50001f34549403 Mon Sep 17 00:00:00 2001 From: Manish Chopra Date: Wed, 20 Apr 2016 03:03:27 -0400 Subject: qede: Fix various memory allocation error flows for fastpath This patch handles memory allocation failures for fastpath gracefully in the driver. Signed-off-by: Manish Chopra Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qede/qede_main.c | 140 ++++++++++++++++----------- 1 file changed, 85 insertions(+), 55 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index 518af329502d..5cf1eb2e1776 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -750,6 +750,12 @@ static bool qede_has_tx_work(struct qede_fastpath *fp) return false; } +static inline void qede_rx_bd_ring_consume(struct qede_rx_queue *rxq) +{ + qed_chain_consume(&rxq->rx_bd_ring); + rxq->sw_rx_cons++; +} + /* This function reuses the buffer(from an offset) from * consumer index to producer index in the bd ring */ @@ -773,6 +779,21 @@ static inline void qede_reuse_page(struct qede_dev *edev, curr_cons->data = NULL; } +/* In case of allocation failures reuse buffers + * from consumer index to produce buffers for firmware + */ +static void qede_recycle_rx_bd_ring(struct qede_rx_queue *rxq, + struct qede_dev *edev, u8 count) +{ + struct sw_rx_data *curr_cons; + + for (; count > 0; count--) { + curr_cons = &rxq->sw_rx_ring[rxq->sw_rx_cons & NUM_RX_BDS_MAX]; + qede_reuse_page(edev, rxq, curr_cons); + qede_rx_bd_ring_consume(rxq); + } +} + static inline int qede_realloc_rx_buffer(struct qede_dev *edev, struct qede_rx_queue *rxq, struct sw_rx_data *curr_cons) @@ -781,8 +802,14 @@ static inline int qede_realloc_rx_buffer(struct qede_dev *edev, curr_cons->page_offset += rxq->rx_buf_seg_size; if (curr_cons->page_offset == PAGE_SIZE) { - if (unlikely(qede_alloc_rx_buffer(edev, rxq))) + if (unlikely(qede_alloc_rx_buffer(edev, rxq))) { + /* Since we failed to allocate new buffer + * current buffer can be used again. + */ + curr_cons->page_offset -= rxq->rx_buf_seg_size; + return -ENOMEM; + } dma_unmap_page(&edev->pdev->dev, curr_cons->mapping, PAGE_SIZE, DMA_FROM_DEVICE); @@ -901,7 +928,10 @@ static int qede_fill_frag_skb(struct qede_dev *edev, len_on_bd); if (unlikely(qede_realloc_rx_buffer(edev, rxq, current_bd))) { - tpa_info->agg_state = QEDE_AGG_STATE_ERROR; + /* Incr page ref count to reuse on allocation failure + * so that it doesn't get freed while freeing SKB. + */ + atomic_inc(¤t_bd->data->_count); goto out; } @@ -915,6 +945,8 @@ static int qede_fill_frag_skb(struct qede_dev *edev, return 0; out: + tpa_info->agg_state = QEDE_AGG_STATE_ERROR; + qede_recycle_rx_bd_ring(rxq, edev, 1); return -ENOMEM; } @@ -966,8 +998,9 @@ static void qede_tpa_start(struct qede_dev *edev, tpa_info->skb = netdev_alloc_skb(edev->ndev, le16_to_cpu(cqe->len_on_first_bd)); if (unlikely(!tpa_info->skb)) { + DP_NOTICE(edev, "Failed to allocate SKB for gro\n"); tpa_info->agg_state = QEDE_AGG_STATE_ERROR; - return; + goto cons_buf; } skb_put(tpa_info->skb, le16_to_cpu(cqe->len_on_first_bd)); @@ -990,6 +1023,7 @@ static void qede_tpa_start(struct qede_dev *edev, /* This is needed in order to enable forwarding support */ qede_set_gro_params(edev, tpa_info->skb, cqe); +cons_buf: /* We still need to handle bd_len_list to consume buffers */ if (likely(cqe->ext_bd_len_list[0])) qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index, le16_to_cpu(cqe->ext_bd_len_list[0])); @@ -1244,17 +1278,17 @@ static int qede_rx_int(struct qede_fastpath *fp, int budget) "CQE in CONS = %u has error, flags = %x, dropping incoming packet\n", sw_comp_cons, parse_flag); rxq->rx_hw_errors++; - qede_reuse_page(edev, rxq, sw_rx_data); - goto next_rx; + qede_recycle_rx_bd_ring(rxq, edev, fp_cqe->bd_num); + goto next_cqe; } skb = netdev_alloc_skb(edev->ndev, QEDE_RX_HDR_SIZE); if (unlikely(!skb)) { DP_NOTICE(edev, "Build_skb failed, dropping incoming packet\n"); - qede_reuse_page(edev, rxq, sw_rx_data); + qede_recycle_rx_bd_ring(rxq, edev, fp_cqe->bd_num); rxq->rx_alloc_errors++; - goto next_rx; + goto next_cqe; } /* Copy data into SKB */ @@ -1288,11 +1322,22 @@ static int qede_rx_int(struct qede_fastpath *fp, int budget) if (unlikely(qede_realloc_rx_buffer(edev, rxq, sw_rx_data))) { DP_ERR(edev, "Failed to allocate rx buffer\n"); + /* Incr page ref count to reuse on allocation + * failure so that it doesn't get freed while + * freeing SKB. + */ + + atomic_inc(&sw_rx_data->data->_count); rxq->rx_alloc_errors++; + qede_recycle_rx_bd_ring(rxq, edev, + fp_cqe->bd_num); + dev_kfree_skb_any(skb); goto next_cqe; } } + qede_rx_bd_ring_consume(rxq); + if (fp_cqe->bd_num != 1) { u16 pkt_len = le16_to_cpu(fp_cqe->pkt_len); u8 num_frags; @@ -1303,18 +1348,27 @@ static int qede_rx_int(struct qede_fastpath *fp, int budget) num_frags--) { u16 cur_size = pkt_len > rxq->rx_buf_size ? rxq->rx_buf_size : pkt_len; + if (unlikely(!cur_size)) { + DP_ERR(edev, + "Still got %d BDs for mapping jumbo, but length became 0\n", + num_frags); + qede_recycle_rx_bd_ring(rxq, edev, + num_frags); + dev_kfree_skb_any(skb); + goto next_cqe; + } - WARN_ONCE(!cur_size, - "Still got %d BDs for mapping jumbo, but length became 0\n", - num_frags); - - if (unlikely(qede_alloc_rx_buffer(edev, rxq))) + if (unlikely(qede_alloc_rx_buffer(edev, rxq))) { + qede_recycle_rx_bd_ring(rxq, edev, + num_frags); + dev_kfree_skb_any(skb); goto next_cqe; + } - rxq->sw_rx_cons++; sw_rx_index = rxq->sw_rx_cons & NUM_RX_BDS_MAX; sw_rx_data = &rxq->sw_rx_ring[sw_rx_index]; - qed_chain_consume(&rxq->rx_bd_ring); + qede_rx_bd_ring_consume(rxq); + dma_unmap_page(&edev->pdev->dev, sw_rx_data->mapping, PAGE_SIZE, DMA_FROM_DEVICE); @@ -1330,7 +1384,7 @@ static int qede_rx_int(struct qede_fastpath *fp, int budget) pkt_len -= cur_size; } - if (pkt_len) + if (unlikely(pkt_len)) DP_ERR(edev, "Mapped all BDs of jumbo, but still have %d bytes\n", pkt_len); @@ -1349,10 +1403,6 @@ static int qede_rx_int(struct qede_fastpath *fp, int budget) skb_record_rx_queue(skb, fp->rss_id); qede_skb_receive(edev, fp, skb, le16_to_cpu(fp_cqe->vlan_tag)); - - qed_chain_consume(&rxq->rx_bd_ring); -next_rx: - rxq->sw_rx_cons++; next_rx_only: rx_pkt++; @@ -2257,7 +2307,7 @@ static void qede_free_sge_mem(struct qede_dev *edev, struct qede_agg_info *tpa_info = &rxq->tpa_info[i]; struct sw_rx_data *replace_buf = &tpa_info->replace_buf; - if (replace_buf) { + if (replace_buf->data) { dma_unmap_page(&edev->pdev->dev, dma_unmap_addr(replace_buf, mapping), PAGE_SIZE, DMA_FROM_DEVICE); @@ -2377,7 +2427,7 @@ err: static int qede_alloc_mem_rxq(struct qede_dev *edev, struct qede_rx_queue *rxq) { - int i, rc, size, num_allocated; + int i, rc, size; rxq->num_rx_buffers = edev->q_num_rx_buffers; @@ -2394,6 +2444,7 @@ static int qede_alloc_mem_rxq(struct qede_dev *edev, rxq->sw_rx_ring = kzalloc(size, GFP_KERNEL); if (!rxq->sw_rx_ring) { DP_ERR(edev, "Rx buffers ring allocation failed\n"); + rc = -ENOMEM; goto err; } @@ -2421,26 +2472,16 @@ static int qede_alloc_mem_rxq(struct qede_dev *edev, /* Allocate buffers for the Rx ring */ for (i = 0; i < rxq->num_rx_buffers; i++) { rc = qede_alloc_rx_buffer(edev, rxq); - if (rc) - break; - } - num_allocated = i; - if (!num_allocated) { - DP_ERR(edev, "Rx buffers allocation failed\n"); - goto err; - } else if (num_allocated < rxq->num_rx_buffers) { - DP_NOTICE(edev, - "Allocated less buffers than desired (%d allocated)\n", - num_allocated); + if (rc) { + DP_ERR(edev, + "Rx buffers allocation failed at index %d\n", i); + goto err; + } } - qede_alloc_sge_mem(edev, rxq); - - return 0; - + rc = qede_alloc_sge_mem(edev, rxq); err: - qede_free_mem_rxq(edev, rxq); - return -ENOMEM; + return rc; } static void qede_free_mem_txq(struct qede_dev *edev, @@ -2523,10 +2564,8 @@ static int qede_alloc_mem_fp(struct qede_dev *edev, } return 0; - err: - qede_free_mem_fp(edev, fp); - return -ENOMEM; + return rc; } static void qede_free_mem_load(struct qede_dev *edev) @@ -2549,22 +2588,13 @@ static int qede_alloc_mem_load(struct qede_dev *edev) struct qede_fastpath *fp = &edev->fp_array[rss_id]; rc = qede_alloc_mem_fp(edev, fp); - if (rc) - break; - } - - if (rss_id != QEDE_RSS_CNT(edev)) { - /* Failed allocating memory for all the queues */ - if (!rss_id) { + if (rc) { DP_ERR(edev, - "Failed to allocate memory for the leading queue\n"); - rc = -ENOMEM; - } else { - DP_NOTICE(edev, - "Failed to allocate memory for all of RSS queues\n Desired: %d queues, allocated: %d queues\n", - QEDE_RSS_CNT(edev), rss_id); + "Failed to allocate memory for fastpath - rss id = %d\n", + rss_id); + qede_free_mem_load(edev); + return rc; } - edev->num_rss = rss_id; } return 0; -- cgit v1.2.3 From aad94c0408780c9f2e168f91ded861dd3877f7d9 Mon Sep 17 00:00:00 2001 From: Manish Chopra Date: Wed, 20 Apr 2016 03:03:28 -0400 Subject: qede: Fix setting Skb network header Skb's network header needs to be set before extracting IPv4/IPv6 headers from it. Signed-off-by: Manish Chopra Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qede/qede_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index 5cf1eb2e1776..bf0fb99874c6 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -1041,7 +1041,6 @@ static void qede_gro_ip_csum(struct sk_buff *skb) const struct iphdr *iph = ip_hdr(skb); struct tcphdr *th; - skb_set_network_header(skb, 0); skb_set_transport_header(skb, sizeof(struct iphdr)); th = tcp_hdr(skb); @@ -1056,7 +1055,6 @@ static void qede_gro_ipv6_csum(struct sk_buff *skb) struct ipv6hdr *iph = ipv6_hdr(skb); struct tcphdr *th; - skb_set_network_header(skb, 0); skb_set_transport_header(skb, sizeof(struct ipv6hdr)); th = tcp_hdr(skb); @@ -1073,6 +1071,8 @@ static void qede_gro_receive(struct qede_dev *edev, { #ifdef CONFIG_INET if (skb_shinfo(skb)->gso_size) { + skb_set_network_header(skb, 0); + switch (skb->protocol) { case htons(ETH_P_IP): qede_gro_ip_csum(skb); -- cgit v1.2.3 From ee2fa8e6b317ef756a3dfc2dae35891c025e32c9 Mon Sep 17 00:00:00 2001 From: Manish Chopra Date: Wed, 20 Apr 2016 03:03:29 -0400 Subject: qede: Fix single MTU sized packet from firmware GRO flow In firmware assisted GRO flow there could be a single MTU sized segment arriving due to firmware aggregation timeout/last segment in an aggregation flow, which is not expected to be an actual gro packet. So If a skb has zero frags from the GRO flow then simply push it in the stack as non gso skb. Signed-off-by: Manish Chopra Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qede/qede_main.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index bf0fb99874c6..7869465435fa 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -1069,6 +1069,17 @@ static void qede_gro_receive(struct qede_dev *edev, struct sk_buff *skb, u16 vlan_tag) { + /* FW can send a single MTU sized packet from gro flow + * due to aggregation timeout/last segment etc. which + * is not expected to be a gro packet. If a skb has zero + * frags then simply push it in the stack as non gso skb. + */ + if (unlikely(!skb->data_len)) { + skb_shinfo(skb)->gso_type = 0; + skb_shinfo(skb)->gso_size = 0; + goto send_skb; + } + #ifdef CONFIG_INET if (skb_shinfo(skb)->gso_size) { skb_set_network_header(skb, 0); @@ -1087,6 +1098,8 @@ static void qede_gro_receive(struct qede_dev *edev, } } #endif + +send_skb: skb_record_rx_queue(skb, fp->rss_id); qede_skb_receive(edev, fp, skb, vlan_tag); } -- cgit v1.2.3 From 99164f9e62a391b5f4b7923b624d182b5d2859e0 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 20 Apr 2016 10:56:13 +0200 Subject: net: ethernet: davinci_emac: Fix Unbalanced pm_runtime_enable In order to avoid an Unbalanced pm_runtime_enable in the DaVinci emac driver when the device is removed and re-probed, and a pm_runtime_disable() call in davinci_emac_remove(). Actually, using unbind/bind on a TI DM8168 SoC gives : $ echo 4a120000.ethernet > /sys/bus/platform/drivers/davinci_emac/unbind net eth1: DaVinci EMAC: davinci_emac_remove() $ echo 4a120000.ethernet > /sys/bus/platform/drivers/davinci_emac/bind davinci_emac 4a120000.ethernet: Unbalanced pm_runtime_enable Cc: Brian Hutchinson Fixes: 3ba97381343b ("net: ethernet: davinci_emac: add pm_runtime support") Signed-off-by: Neil Armstrong Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_emac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 5d9abedd6b75..e9fe3fb6d109 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -2101,6 +2101,7 @@ static int davinci_emac_remove(struct platform_device *pdev) cpdma_ctlr_destroy(priv->dma); unregister_netdev(ndev); + pm_runtime_disable(&pdev->dev); free_netdev(ndev); return 0; -- cgit v1.2.3 From 210990b05a1247886539078e857cd038881bb2d6 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 20 Apr 2016 10:56:45 +0200 Subject: net: ethernet: davinci_emac: Fix platform_data overwrite When the DaVinci emac driver is removed and re-probed, the actual pdev->dev.platform_data is populated with an unwanted valid pointer saved by the previous davinci_emac_of_get_pdata() call, causing a kernel crash when calling priv->int_disable() in emac_int_disable(). Unable to handle kernel paging request at virtual address c8622a80 ... [] (emac_int_disable) from [] (emac_dev_open+0x290/0x5f8) [] (emac_dev_open) from [] (__dev_open+0xb8/0x120) [] (__dev_open) from [] (__dev_change_flags+0x88/0x14c) [] (__dev_change_flags) from [] (dev_change_flags+0x18/0x48) [] (dev_change_flags) from [] (devinet_ioctl+0x6b4/0x7ac) [] (devinet_ioctl) from [] (sock_ioctl+0x1d8/0x2c0) [] (sock_ioctl) from [] (do_vfs_ioctl+0x41c/0x600) [] (do_vfs_ioctl) from [] (SyS_ioctl+0x6c/0x7c) [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x1c) Fixes: 42f59967a091 ("net: ethernet: davinci_emac: add OF support") Cc: Brian Hutchinson Signed-off-by: Neil Armstrong Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_emac.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index e9fe3fb6d109..58d58f002559 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1878,8 +1878,6 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv) pdata->hw_ram_addr = auxdata->hw_ram_addr; } - pdev->dev.platform_data = pdata; - return pdata; } -- cgit v1.2.3 From a1459c1c9ebcd72f3d488fd10673e64b2bfcbd27 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 20 Apr 2016 12:54:05 +0100 Subject: net: phy: spi_ks8895: Don't leak references to SPI devices The ks8895 driver is using spi_dev_get() apparently just to take a copy of the SPI device used to instantiate it but never calls spi_dev_put() to free it. Since the device is guaranteed to exist between probe() and remove() there should be no need for the driver to take an extra reference to it so fix the leak by just using a straight assignment. Signed-off-by: Mark Brown Signed-off-by: David S. Miller --- drivers/net/phy/spi_ks8995.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c index b5d50d458728..93ffedfa2994 100644 --- a/drivers/net/phy/spi_ks8995.c +++ b/drivers/net/phy/spi_ks8995.c @@ -441,7 +441,7 @@ static int ks8995_probe(struct spi_device *spi) return -ENOMEM; mutex_init(&ks->lock); - ks->spi = spi_dev_get(spi); + ks->spi = spi; ks->chip = &ks8995_chip[variant]; if (ks->spi->dev.of_node) { -- cgit v1.2.3 From c12833acff62cff83a8b728253e7ebbc1264d75e Mon Sep 17 00:00:00 2001 From: Daniel Jurgens Date: Wed, 20 Apr 2016 16:01:15 +0300 Subject: net/mlx4_core: Implement pci_resume callback Move resume related activities to a new pci_resume function instead of performing them in mlx4_pci_slot_reset. This change is needed to avoid a hotplug during EEH recovery due to commit f2da4ccf8bd4 ("powerpc/eeh: More relaxed hotplug criterion"). Fixes: 2ba5fbd62b25 ('net/mlx4_core: Handle AER flow properly') Signed-off-by: Daniel Jurgens Signed-off-by: Yishai Hadas Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/main.c | 39 +++++++++++++++++++------------ 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 358f7230da58..5d45aa34f6a5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -4050,45 +4050,53 @@ static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev) { struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); struct mlx4_dev *dev = persist->dev; - struct mlx4_priv *priv = mlx4_priv(dev); - int ret; - int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0}; - int total_vfs; + int err; mlx4_err(dev, "mlx4_pci_slot_reset was called\n"); - ret = pci_enable_device(pdev); - if (ret) { - mlx4_err(dev, "Can not re-enable device, ret=%d\n", ret); + err = pci_enable_device(pdev); + if (err) { + mlx4_err(dev, "Can not re-enable device, err=%d\n", err); return PCI_ERS_RESULT_DISCONNECT; } pci_set_master(pdev); pci_restore_state(pdev); pci_save_state(pdev); + return PCI_ERS_RESULT_RECOVERED; +} + +static void mlx4_pci_resume(struct pci_dev *pdev) +{ + struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); + struct mlx4_dev *dev = persist->dev; + struct mlx4_priv *priv = mlx4_priv(dev); + int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0}; + int total_vfs; + int err; + mlx4_err(dev, "%s was called\n", __func__); total_vfs = dev->persist->num_vfs; memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs)); mutex_lock(&persist->interface_state_mutex); if (!(persist->interface_state & MLX4_INTERFACE_STATE_UP)) { - ret = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, nvfs, + err = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, nvfs, priv, 1); - if (ret) { - mlx4_err(dev, "%s: mlx4_load_one failed, ret=%d\n", - __func__, ret); + if (err) { + mlx4_err(dev, "%s: mlx4_load_one failed, err=%d\n", + __func__, err); goto end; } - ret = restore_current_port_types(dev, dev->persist-> + err = restore_current_port_types(dev, dev->persist-> curr_port_type, dev->persist-> curr_port_poss_type); - if (ret) - mlx4_err(dev, "could not restore original port types (%d)\n", ret); + if (err) + mlx4_err(dev, "could not restore original port types (%d)\n", err); } end: mutex_unlock(&persist->interface_state_mutex); - return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; } static void mlx4_shutdown(struct pci_dev *pdev) @@ -4105,6 +4113,7 @@ static void mlx4_shutdown(struct pci_dev *pdev) static const struct pci_error_handlers mlx4_err_handler = { .error_detected = mlx4_pci_err_detected, .slot_reset = mlx4_pci_slot_reset, + .resume = mlx4_pci_resume, }; static struct pci_driver mlx4_driver = { -- cgit v1.2.3 From 4bfd2e6e53435a214888fd35e230157a38ffc6a0 Mon Sep 17 00:00:00 2001 From: Daniel Jurgens Date: Wed, 20 Apr 2016 16:01:16 +0300 Subject: net/mlx4_core: Avoid repeated calls to pci enable/disable Maintain the PCI status and provide wrappers for enabling and disabling the PCI device. Performing the actions more than once without doing its opposite results in warning logs. This occurred when EEH hotplugged the device causing a warning for disabling an already disabled device. Fixes: 2ba5fbd62b25 ('net/mlx4_core: Handle AER flow properly') Signed-off-by: Daniel Jurgens Signed-off-by: Yishai Hadas Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/main.c | 39 +++++++++++++++++++++++++++---- include/linux/mlx4/device.h | 7 ++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 5d45aa34f6a5..12c77a70abdb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -3172,6 +3172,34 @@ static int mlx4_check_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap return 0; } +static int mlx4_pci_enable_device(struct mlx4_dev *dev) +{ + struct pci_dev *pdev = dev->persist->pdev; + int err = 0; + + mutex_lock(&dev->persist->pci_status_mutex); + if (dev->persist->pci_status == MLX4_PCI_STATUS_DISABLED) { + err = pci_enable_device(pdev); + if (!err) + dev->persist->pci_status = MLX4_PCI_STATUS_ENABLED; + } + mutex_unlock(&dev->persist->pci_status_mutex); + + return err; +} + +static void mlx4_pci_disable_device(struct mlx4_dev *dev) +{ + struct pci_dev *pdev = dev->persist->pdev; + + mutex_lock(&dev->persist->pci_status_mutex); + if (dev->persist->pci_status == MLX4_PCI_STATUS_ENABLED) { + pci_disable_device(pdev); + dev->persist->pci_status = MLX4_PCI_STATUS_DISABLED; + } + mutex_unlock(&dev->persist->pci_status_mutex); +} + static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, int total_vfs, int *nvfs, struct mlx4_priv *priv, int reset_flow) @@ -3582,7 +3610,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data, pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev)); - err = pci_enable_device(pdev); + err = mlx4_pci_enable_device(&priv->dev); if (err) { dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n"); return err; @@ -3715,7 +3743,7 @@ err_release_regions: pci_release_regions(pdev); err_disable_pdev: - pci_disable_device(pdev); + mlx4_pci_disable_device(&priv->dev); pci_set_drvdata(pdev, NULL); return err; } @@ -3775,6 +3803,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) priv->pci_dev_data = id->driver_data; mutex_init(&dev->persist->device_state_mutex); mutex_init(&dev->persist->interface_state_mutex); + mutex_init(&dev->persist->pci_status_mutex); ret = devlink_register(devlink, &pdev->dev); if (ret) @@ -3923,7 +3952,7 @@ static void mlx4_remove_one(struct pci_dev *pdev) } pci_release_regions(pdev); - pci_disable_device(pdev); + mlx4_pci_disable_device(dev); devlink_unregister(devlink); kfree(dev->persist); devlink_free(devlink); @@ -4042,7 +4071,7 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev, if (state == pci_channel_io_perm_failure) return PCI_ERS_RESULT_DISCONNECT; - pci_disable_device(pdev); + mlx4_pci_disable_device(persist->dev); return PCI_ERS_RESULT_NEED_RESET; } @@ -4053,7 +4082,7 @@ static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev) int err; mlx4_err(dev, "mlx4_pci_slot_reset was called\n"); - err = pci_enable_device(pdev); + err = mlx4_pci_enable_device(dev); if (err) { mlx4_err(dev, "Can not re-enable device, err=%d\n", err); return PCI_ERS_RESULT_DISCONNECT; diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 8541a913f6a3..d1f904c8b2cb 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -828,6 +828,11 @@ struct mlx4_vf_dev { u8 n_ports; }; +enum mlx4_pci_status { + MLX4_PCI_STATUS_DISABLED, + MLX4_PCI_STATUS_ENABLED, +}; + struct mlx4_dev_persistent { struct pci_dev *pdev; struct mlx4_dev *dev; @@ -841,6 +846,8 @@ struct mlx4_dev_persistent { u8 state; struct mutex interface_state_mutex; /* protect SW state */ u8 interface_state; + struct mutex pci_status_mutex; /* sync pci state */ + enum mlx4_pci_status pci_status; }; struct mlx4_dev { -- cgit v1.2.3 From 2a500090a4ea2ccd713f3c782a2fb27681bd6e67 Mon Sep 17 00:00:00 2001 From: Eugenia Emantayev Date: Wed, 20 Apr 2016 16:01:17 +0300 Subject: net/mlx4_core: Don't allow to VF change global pause settings Currently changing global pause settings is done via SET_PORT command with input modifier GENERAL. This command is allowed for each VF since MTU setting is done via the same command. Change the above to the following scheme: before passing the request to the FW, the PF will check whether it was issued by a slave. If yes, don't change global pause and warn, otherwise change to the requested value and store for further reference. Signed-off-by: Eugenia Emantayev Signed-off-by: Saeed Mahameed Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 2 ++ drivers/net/ethernet/mellanox/mlx4/port.c | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index ef9683101ead..c9d7fc5159f2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -586,6 +586,8 @@ struct mlx4_mfunc_master_ctx { struct mlx4_master_qp0_state qp0_state[MLX4_MAX_PORTS + 1]; int init_port_ref[MLX4_MAX_PORTS + 1]; u16 max_mtu[MLX4_MAX_PORTS + 1]; + u8 pptx; + u8 pprx; int disable_mcast_ref[MLX4_MAX_PORTS + 1]; struct mlx4_resource_tracker res_tracker; struct workqueue_struct *comm_wq; diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 211c65087997..087b23b320cb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c @@ -1317,6 +1317,19 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, } gen_context->mtu = cpu_to_be16(master->max_mtu[port]); + /* Slave cannot change Global Pause configuration */ + if (slave != mlx4_master_func_num(dev) && + ((gen_context->pptx != master->pptx) || + (gen_context->pprx != master->pprx))) { + gen_context->pptx = master->pptx; + gen_context->pprx = master->pprx; + mlx4_warn(dev, + "denying Global Pause change for slave:%d\n", + slave); + } else { + master->pptx = gen_context->pptx; + master->pprx = gen_context->pprx; + } break; case MLX4_SET_PORT_GID_TABLE: /* change to MULTIPLE entries: number of guest's gids -- cgit v1.2.3 From d21ed3a311a1031dddc78e9270d1aa9adc8f8a93 Mon Sep 17 00:00:00 2001 From: Eran Ben Elisha Date: Wed, 20 Apr 2016 16:01:18 +0300 Subject: net/mlx4_en: Split SW RX dropped counter per RX ring Count SW packet drops per RX ring instead of a global counter. This will allow monitoring the number of rx drops per ring. In addition, SW rx_dropped counter was overwritten by HW rx_dropped counter, sum both of them instead to show the accurate value. Fixes: a3333b35da16 ('net/mlx4_en: Moderate ethtool callback to [...] ') Signed-off-by: Eran Ben Elisha Reported-by: Brenden Blanco Signed-off-by: Saeed Mahameed Signed-off-by: Or Gerlitz Reported-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 5 ++++- drivers/net/ethernet/mellanox/mlx4/en_port.c | 5 ++++- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 2 +- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index f69584a9b47f..c761194bb323 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -337,7 +337,7 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset) case ETH_SS_STATS: return bitmap_iterator_count(&it) + (priv->tx_ring_num * 2) + - (priv->rx_ring_num * 2); + (priv->rx_ring_num * 3); case ETH_SS_TEST: return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2; @@ -404,6 +404,7 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, for (i = 0; i < priv->rx_ring_num; i++) { data[index++] = priv->rx_ring[i]->packets; data[index++] = priv->rx_ring[i]->bytes; + data[index++] = priv->rx_ring[i]->dropped; } spin_unlock_bh(&priv->stats_lock); @@ -477,6 +478,8 @@ static void mlx4_en_get_strings(struct net_device *dev, "rx%d_packets", i); sprintf(data + (index++) * ETH_GSTRING_LEN, "rx%d_bytes", i); + sprintf(data + (index++) * ETH_GSTRING_LEN, + "rx%d_dropped", i); } break; case ETH_SS_PRIV_FLAGS: diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c index 3904b5fc0b7c..20b6c2e678b8 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_port.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c @@ -158,6 +158,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) u64 in_mod = reset << 8 | port; int err; int i, counter_index; + unsigned long sw_rx_dropped = 0; mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); if (IS_ERR(mailbox)) @@ -180,6 +181,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) for (i = 0; i < priv->rx_ring_num; i++) { stats->rx_packets += priv->rx_ring[i]->packets; stats->rx_bytes += priv->rx_ring[i]->bytes; + sw_rx_dropped += priv->rx_ring[i]->dropped; priv->port_stats.rx_chksum_good += priv->rx_ring[i]->csum_ok; priv->port_stats.rx_chksum_none += priv->rx_ring[i]->csum_none; priv->port_stats.rx_chksum_complete += priv->rx_ring[i]->csum_complete; @@ -236,7 +238,8 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) &mlx4_en_stats->MCAST_prio_1, NUM_PRIORITIES); stats->collisions = 0; - stats->rx_dropped = be32_to_cpu(mlx4_en_stats->RDROP); + stats->rx_dropped = be32_to_cpu(mlx4_en_stats->RDROP) + + sw_rx_dropped; stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength); stats->rx_over_errors = 0; stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 7d25bc9c1b22..b723e3bcab39 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -943,7 +943,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud /* GRO not possible, complete processing here */ skb = mlx4_en_rx_skb(priv, rx_desc, frags, length); if (!skb) { - priv->stats.rx_dropped++; + ring->dropped++; goto next; } diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index d12ab6a73344..63b1aeae2c03 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -323,6 +323,7 @@ struct mlx4_en_rx_ring { unsigned long csum_ok; unsigned long csum_none; unsigned long csum_complete; + unsigned long dropped; int hwtstamp_rx_filter; cpumask_var_t affinity_mask; }; -- cgit v1.2.3 From 91951f980e521d8f7e92283735b99fb9f4b05d93 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 21 Apr 2016 11:31:54 +0100 Subject: irqchip/mips-gic: Don't overrun pcpu_masks array Commit 2a0787051182 ("irqchip/mips-gic: Use gic_vpes instead of NR_CPUS") & commit 78930f09b940 ("irqchip/mips-gic: Clear percpu_masks correctly when mapping") both introduce code which accesses gic_vpes entries in the pcpu_masks array. However, this array has length NR_CPUS. If NR_CPUS is less than gic_vpes (ie. the kernel supports use of less CPUs than are present in the system) then we overrun the array, clobber some other data & generally die pretty promptly. Most notably this affects uniprocessor kernels running on any multicore or multithreaded Malta with a GIC (ie. the vast majority of real Malta boards). Fix this by only accessing up to min(gic_vpes, NR_CPUS) entries in the pcpu_masks array, preventing the array overrun. Fixes: 2a0787051182 ("irqchip/mips-gic: Use gic_vpes instead of NR_CPUS") Fixes: 78930f09b940 ("irqchip/mips-gic: Clear percpu_masks correctly when mapping") Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: Jason Cooper Cc: Marc Zyngier Cc: Ralf Baechle Link: http://lkml.kernel.org/r/1461234714-9975-1-git-send-email-paul.burton@imgtec.com Signed-off-by: Thomas Gleixner --- drivers/irqchip/irq-mips-gic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 94a30da0cfac..4dffccf532a2 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -467,7 +467,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, gic_map_to_vpe(irq, mips_cm_vp_id(cpumask_first(&tmp))); /* Update the pcpu_masks */ - for (i = 0; i < gic_vpes; i++) + for (i = 0; i < min(gic_vpes, NR_CPUS); i++) clear_bit(irq, pcpu_masks[i].pcpu_mask); set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask); @@ -707,7 +707,7 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, spin_lock_irqsave(&gic_lock, flags); gic_map_to_pin(intr, gic_cpu_pin); gic_map_to_vpe(intr, vpe); - for (i = 0; i < gic_vpes; i++) + for (i = 0; i < min(gic_vpes, NR_CPUS); i++) clear_bit(intr, pcpu_masks[i].pcpu_mask); set_bit(intr, pcpu_masks[vpe].pcpu_mask); spin_unlock_irqrestore(&gic_lock, flags); -- cgit v1.2.3 From f43bfaeddc79effbf3d0fcb53ca477cca66f3db8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 20 Apr 2016 23:23:08 +0100 Subject: atl2: Disable unimplemented scatter/gather feature atl2 includes NETIF_F_SG in hw_features even though it has no support for non-linear skbs. This bug was originally harmless since the driver does not claim to implement checksum offload and that used to be a requirement for SG. Now that SG and checksum offload are independent features, if you explicitly enable SG *and* use one of the rare protocols that can use SG without checkusm offload, this potentially leaks sensitive information (before you notice that it just isn't working). Therefore this obscure bug has been designated CVE-2016-2117. Reported-by: Justin Yackoski Signed-off-by: Ben Hutchings Fixes: ec5f06156423 ("net: Kill link between CSUM and SG features.") Signed-off-by: David S. Miller --- drivers/net/ethernet/atheros/atlx/atl2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c index 8f76f4558a88..2ff465848b65 100644 --- a/drivers/net/ethernet/atheros/atlx/atl2.c +++ b/drivers/net/ethernet/atheros/atlx/atl2.c @@ -1412,7 +1412,7 @@ static int atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = -EIO; - netdev->hw_features = NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_RX; + netdev->hw_features = NETIF_F_HW_VLAN_CTAG_RX; netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX); /* Init PHY as early as possible due to power saving issue */ -- cgit v1.2.3 From f0d437809d23999cb25207cfbe80c61e5703fdc1 Mon Sep 17 00:00:00 2001 From: Shrikrishna Khare Date: Wed, 20 Apr 2016 18:12:29 -0700 Subject: Driver: Vmxnet3: set CHECKSUM_UNNECESSARY for IPv6 packets For IPv6, if the device indicates that the checksum is correct, set CHECKSUM_UNNECESSARY. Reported-by: Subbarao Narahari Signed-off-by: Shrikrishna Khare Signed-off-by: Jin Heo Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 12 ++++++++---- drivers/net/vmxnet3/vmxnet3_int.h | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index b2348f67b00a..db8022ae415b 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1152,12 +1152,16 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter, union Vmxnet3_GenericDesc *gdesc) { if (!gdesc->rcd.cnc && adapter->netdev->features & NETIF_F_RXCSUM) { - /* typical case: TCP/UDP over IP and both csums are correct */ - if ((le32_to_cpu(gdesc->dword[3]) & VMXNET3_RCD_CSUM_OK) == - VMXNET3_RCD_CSUM_OK) { + if (gdesc->rcd.v4 && + (le32_to_cpu(gdesc->dword[3]) & + VMXNET3_RCD_CSUM_OK) == VMXNET3_RCD_CSUM_OK) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp)); + BUG_ON(gdesc->rcd.frg); + } else if (gdesc->rcd.v6 && (le32_to_cpu(gdesc->dword[3]) & + (1 << VMXNET3_RCD_TUC_SHIFT))) { skb->ip_summed = CHECKSUM_UNNECESSARY; BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp)); - BUG_ON(!(gdesc->rcd.v4 || gdesc->rcd.v6)); BUG_ON(gdesc->rcd.frg); } else { if (gdesc->rcd.csum) { diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 729c344e6774..c4825392d64b 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -69,10 +69,10 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.4.6.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.4.7.0-k" /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01040600 +#define VMXNET3_DRIVER_VERSION_NUM 0x01040700 #if defined(CONFIG_PCI_MSI) /* RSS only makes sense if MSI-X is supported. */ -- cgit v1.2.3 From b4f70527f052b0c00be4d7cac562baa75b212df5 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 21 Apr 2016 11:49:15 +1000 Subject: openvswitch: use flow protocol when recalculating ipv6 checksums When using masked actions the ipv6_proto field of an action to set IPv6 fields may be zero rather than the prevailing protocol which will result in skipping checksum recalculation. This patch resolves the problem by relying on the protocol in the flow key rather than that in the set field action. Fixes: 83d2b9ba1abc ("net: openvswitch: Support masked set actions.") Cc: Jarno Rajahalme Signed-off-by: Simon Horman Signed-off-by: David S. Miller --- net/openvswitch/actions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index e9dd47b2a85b..879185fe183f 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -461,7 +461,7 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key, mask_ipv6_addr(saddr, key->ipv6_src, mask->ipv6_src, masked); if (unlikely(memcmp(saddr, masked, sizeof(masked)))) { - set_ipv6_addr(skb, key->ipv6_proto, saddr, masked, + set_ipv6_addr(skb, flow_key->ip.proto, saddr, masked, true); memcpy(&flow_key->ipv6.addr.src, masked, sizeof(flow_key->ipv6.addr.src)); @@ -483,7 +483,7 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key, NULL, &flags) != NEXTHDR_ROUTING); - set_ipv6_addr(skb, key->ipv6_proto, daddr, masked, + set_ipv6_addr(skb, flow_key->ip.proto, daddr, masked, recalc_csum); memcpy(&flow_key->ipv6.addr.dst, masked, sizeof(flow_key->ipv6.addr.dst)); -- cgit v1.2.3 From a95f94bc98754bad32cb7f36c867d71f3f2be729 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 30 Mar 2016 13:42:47 +0200 Subject: sparc/defconfigs: Remove CONFIG_IPV6_PRIVACY Option is long gone, see 5d9efa7ee99e ("ipv6: Remove privacy config option.") Signed-off-by: Borislav Petkov Cc: sparclinux@vger.kernel.org Signed-off-by: David S. Miller --- arch/sparc/configs/sparc32_defconfig | 1 - arch/sparc/configs/sparc64_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/sparc/configs/sparc32_defconfig b/arch/sparc/configs/sparc32_defconfig index fb23fd6b186a..c74d3701ad68 100644 --- a/arch/sparc/configs/sparc32_defconfig +++ b/arch/sparc/configs/sparc32_defconfig @@ -24,7 +24,6 @@ CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y # CONFIG_INET_LRO is not set -CONFIG_IPV6_PRIVACY=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index 04920ab8e292..3583d676a916 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig @@ -48,7 +48,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y -CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y CONFIG_IPV6_OPTIMISTIC_DAD=y -- cgit v1.2.3 From 9a78d4fc28904785ffe4c2d361e25b251b479704 Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Mon, 11 Apr 2016 17:57:05 -0700 Subject: sparc/pci: Refactor dev_archdata initialization into pci_init_dev_archdata The function pcibios_add_device() added by commit d0c31e020057 ("sparc/PCI: Fix for panic while enabling SR-IOV") initializes the dev_archdata by doing a memcpy from the PF. This has the problem that it erroneously copies the OF device without explicitly refcounting it. As David Miller pointed out: "Generally speaking we don't really support hot-plug for OF probed devices, but if we did all of the device tree pointers have to be refcounted properly." To fix this error, and also avoid code duplication, this patch creates a new helper function, pci_init_dev_archdata(), that initializes the fields in dev_archdata, and can be invoked by callers after they have taken the needed refcounts Signed-off-by: Sowmini Varadhan Tested-by: Babu Moger Reviewed-by: Khalid Aziz Signed-off-by: David S. Miller --- arch/sparc/kernel/pci.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 9f9614df9e1e..c2b202d763a1 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -245,6 +245,18 @@ static void pci_parse_of_addrs(struct platform_device *op, } } +static void pci_init_dev_archdata(struct dev_archdata *sd, void *iommu, + void *stc, void *host_controller, + struct platform_device *op, + int numa_node) +{ + sd->iommu = iommu; + sd->stc = stc; + sd->host_controller = host_controller; + sd->op = op; + sd->numa_node = numa_node; +} + static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, struct device_node *node, struct pci_bus *bus, int devfn) @@ -259,13 +271,10 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, if (!dev) return NULL; + op = of_find_device_by_node(node); sd = &dev->dev.archdata; - sd->iommu = pbm->iommu; - sd->stc = &pbm->stc; - sd->host_controller = pbm; - sd->op = op = of_find_device_by_node(node); - sd->numa_node = pbm->numa_node; - + pci_init_dev_archdata(sd, pbm->iommu, &pbm->stc, pbm, op, + pbm->numa_node); sd = &op->dev.archdata; sd->iommu = pbm->iommu; sd->stc = &pbm->stc; @@ -1003,9 +1012,13 @@ int pcibios_add_device(struct pci_dev *dev) * Copy dev_archdata from PF to VF */ if (dev->is_virtfn) { + struct dev_archdata *psd; + pdev = dev->physfn; - memcpy(&dev->dev.archdata, &pdev->dev.archdata, - sizeof(struct dev_archdata)); + psd = &pdev->dev.archdata; + pci_init_dev_archdata(&dev->dev.archdata, psd->iommu, + psd->stc, psd->host_controller, NULL, + psd->numa_node); } return 0; } -- cgit v1.2.3 From 36128d204b81c099b5779771127a5546eac549c9 Mon Sep 17 00:00:00 2001 From: Adrian Glaubitz Date: Thu, 14 Apr 2016 20:14:41 +0200 Subject: sparc: Implement and wire up modalias_show for vio. Signed-off-by: John Paul Adrian Glaubitz Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/vio.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index cb5789c9f961..d7055609a41c 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -105,9 +105,18 @@ static ssize_t type_show(struct device *dev, return sprintf(buf, "%s\n", vdev->type); } +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + const struct vio_dev *vdev = to_vio_dev(dev); + + return sprintf(buf, "vio:T%sS%s\n", vdev->type, vdev->compat); +} + static struct device_attribute vio_dev_attrs[] = { __ATTR_RO(devspec), __ATTR_RO(type), + __ATTR_RO(modalias), __ATTR_NULL }; -- cgit v1.2.3 From 5bde2c9be701c4583f0a9243bd46590ec401bfba Mon Sep 17 00:00:00 2001 From: Adrian Glaubitz Date: Thu, 14 Apr 2016 20:14:42 +0200 Subject: sparc: Implement and wire up vio_hotplug for vio. Signed-off-by: John Paul Adrian Glaubitz Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/vio.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index d7055609a41c..f6bb857254fc 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -45,6 +45,14 @@ static const struct vio_device_id *vio_match_device( return NULL; } +static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env) +{ + const struct vio_dev *vio_dev = to_vio_dev(dev); + + add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, vio_dev->compat); + return 0; +} + static int vio_bus_match(struct device *dev, struct device_driver *drv) { struct vio_dev *vio_dev = to_vio_dev(dev); @@ -123,6 +131,7 @@ static struct device_attribute vio_dev_attrs[] = { static struct bus_type vio_bus_type = { .name = "vio", .dev_attrs = vio_dev_attrs, + .uevent = vio_hotplug, .match = vio_bus_match, .probe = vio_device_probe, .remove = vio_device_remove, -- cgit v1.2.3 From c5b8b5beee1e2aadef0409dba555b7085d57910d Mon Sep 17 00:00:00 2001 From: Khalid Aziz Date: Tue, 19 Apr 2016 11:12:54 -0600 Subject: sparc64: recognize and support Sonoma CPU type Add code to recognize SPARC-Sonoma cpu correctly and update cpu hardware caps and cpu distribution map. SPARC-Sonoma is based upon SPARC-M7 core along with additional PCI functions added on and is reported by firmware as "SPARC-SN". Signed-off-by: Khalid Aziz Acked-by: Allen Pais Signed-off-by: David S. Miller --- arch/sparc/include/asm/spitfire.h | 1 + arch/sparc/kernel/cpu.c | 6 ++++++ arch/sparc/kernel/cpumap.c | 1 + arch/sparc/kernel/head_64.S | 8 ++++++++ arch/sparc/kernel/setup_64.c | 7 ++++++- arch/sparc/mm/init_64.c | 3 +++ 6 files changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/sparc/include/asm/spitfire.h b/arch/sparc/include/asm/spitfire.h index 56f933816144..1d8321c827a8 100644 --- a/arch/sparc/include/asm/spitfire.h +++ b/arch/sparc/include/asm/spitfire.h @@ -48,6 +48,7 @@ #define SUN4V_CHIP_SPARC_M6 0x06 #define SUN4V_CHIP_SPARC_M7 0x07 #define SUN4V_CHIP_SPARC64X 0x8a +#define SUN4V_CHIP_SPARC_SN 0x8b #define SUN4V_CHIP_UNKNOWN 0xff #ifndef __ASSEMBLY__ diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index dfad8b1aea9f..493e023a468a 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -506,6 +506,12 @@ static void __init sun4v_cpu_probe(void) sparc_pmu_type = "sparc-m7"; break; + case SUN4V_CHIP_SPARC_SN: + sparc_cpu_type = "SPARC-SN"; + sparc_fpu_type = "SPARC-SN integrated FPU"; + sparc_pmu_type = "sparc-sn"; + break; + case SUN4V_CHIP_SPARC64X: sparc_cpu_type = "SPARC64-X"; sparc_fpu_type = "SPARC64-X integrated FPU"; diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index e69ec0e3f155..45c820e1cba5 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c @@ -328,6 +328,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index) case SUN4V_CHIP_NIAGARA5: case SUN4V_CHIP_SPARC_M6: case SUN4V_CHIP_SPARC_M7: + case SUN4V_CHIP_SPARC_SN: case SUN4V_CHIP_SPARC64X: rover_inc_table = niagara_iterate_method; break; diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index cd1f592cd347..5b4f5c363674 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -414,6 +414,8 @@ sun4v_chip_type: cmp %g2, 'T' be,pt %xcc, 70f cmp %g2, 'M' + be,pt %xcc, 70f + cmp %g2, 'S' bne,pn %xcc, 49f nop @@ -433,6 +435,9 @@ sun4v_chip_type: cmp %g2, '7' be,pt %xcc, 5f mov SUN4V_CHIP_SPARC_M7, %g4 + cmp %g2, 'N' + be,pt %xcc, 5f + mov SUN4V_CHIP_SPARC_SN, %g4 ba,pt %xcc, 49f nop @@ -595,6 +600,9 @@ niagara_tlb_fixup: be,pt %xcc, niagara4_patch nop cmp %g1, SUN4V_CHIP_SPARC_M7 + be,pt %xcc, niagara4_patch + nop + cmp %g1, SUN4V_CHIP_SPARC_SN be,pt %xcc, niagara4_patch nop diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 26db95b54ee9..599f1207eed2 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -285,7 +285,8 @@ static void __init sun4v_patch(void) sun4v_patch_2insn_range(&__sun4v_2insn_patch, &__sun4v_2insn_patch_end); - if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7) + if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || + sun4v_chip_type == SUN4V_CHIP_SPARC_SN) sun_m7_patch_2insn_range(&__sun_m7_2insn_patch, &__sun_m7_2insn_patch_end); @@ -524,6 +525,7 @@ static void __init init_sparc64_elf_hwcap(void) sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || sun4v_chip_type == SUN4V_CHIP_SPARC64X) cap |= HWCAP_SPARC_BLKINIT; if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || @@ -532,6 +534,7 @@ static void __init init_sparc64_elf_hwcap(void) sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || sun4v_chip_type == SUN4V_CHIP_SPARC64X) cap |= HWCAP_SPARC_N2; } @@ -561,6 +564,7 @@ static void __init init_sparc64_elf_hwcap(void) sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || sun4v_chip_type == SUN4V_CHIP_SPARC64X) cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | AV_SPARC_ASI_BLK_INIT | @@ -570,6 +574,7 @@ static void __init init_sparc64_elf_hwcap(void) sun4v_chip_type == SUN4V_CHIP_NIAGARA5 || sun4v_chip_type == SUN4V_CHIP_SPARC_M6 || sun4v_chip_type == SUN4V_CHIP_SPARC_M7 || + sun4v_chip_type == SUN4V_CHIP_SPARC_SN || sun4v_chip_type == SUN4V_CHIP_SPARC64X) cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | AV_SPARC_FMAF); diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 1cfe6aab7a11..09e838801e39 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1769,6 +1769,7 @@ static void __init setup_page_offset(void) max_phys_bits = 47; break; case SUN4V_CHIP_SPARC_M7: + case SUN4V_CHIP_SPARC_SN: default: /* M7 and later support 52-bit virtual addresses. */ sparc64_va_hole_top = 0xfff8000000000000UL; @@ -1986,6 +1987,7 @@ static void __init sun4v_linear_pte_xor_finalize(void) */ switch (sun4v_chip_type) { case SUN4V_CHIP_SPARC_M7: + case SUN4V_CHIP_SPARC_SN: pagecv_flag = 0x00; break; default: @@ -2138,6 +2140,7 @@ void __init paging_init(void) */ switch (sun4v_chip_type) { case SUN4V_CHIP_SPARC_M7: + case SUN4V_CHIP_SPARC_SN: page_cache4v_flag = _PAGE_CP_4V; break; default: -- cgit v1.2.3 From 9a3dce62cc5640d7ea17733a2bd1b57665c232b0 Mon Sep 17 00:00:00 2001 From: Zhuang Yuyao Date: Mon, 18 Apr 2016 09:21:42 +0900 Subject: rtc: ds1307: ds3231 temperature s16 overflow while retrieving temperature from ds3231, the result may be overflow since s16 is too small for a multiplication with 250. ie. if temp_buf[0] == 0x2d, the result (s16 temp) will be negative. Signed-off-by: Akinobu Mita Tested-by: Michael Tatarinov Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index b2156ee5bae1..ee3cae2f212e 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -863,7 +863,7 @@ out: * A user-initiated temperature conversion is not started by this function, * so the temperature is updated once every 64 seconds. */ -static int ds3231_hwmon_read_temp(struct device *dev, s16 *mC) +static int ds3231_hwmon_read_temp(struct device *dev, s32 *mC) { struct ds1307 *ds1307 = dev_get_drvdata(dev); u8 temp_buf[2]; @@ -892,7 +892,7 @@ static ssize_t ds3231_hwmon_show_temp(struct device *dev, struct device_attribute *attr, char *buf) { int ret; - s16 temp; + s32 temp; ret = ds3231_hwmon_read_temp(dev, &temp); if (ret) -- cgit v1.2.3 From 38a7a73e8ed0fa9e8cd99bb62463afbdcd23429b Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 19 Apr 2016 11:23:54 -0500 Subject: rtc: ds1307: Use irq when available for wakeup-source device With commit 8bc2a40730ec ("rtc: ds1307: add support for the DT property 'wakeup-source'") we lost the ability for rtc irq functionality for devices that are actually hooked on a real IRQ line and have capability to wakeup as well. This is not an expected behavior. So, instead of just not requesting IRQ, skip the IRQ requirement only if interrupts are not defined for the device. Fixes: 8bc2a40730ec ("rtc: ds1307: add support for the DT property 'wakeup-source'") Reported-by: Tony Lindgren Cc: Michael Lange Cc: Alexandre Belloni Signed-off-by: Nishanth Menon Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index ee3cae2f212e..ecb7dbae9be9 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1531,7 +1531,7 @@ read_rtc: return PTR_ERR(ds1307->rtc); } - if (ds1307_can_wakeup_device) { + if (ds1307_can_wakeup_device && ds1307->client->irq <= 0) { /* Disable request for an IRQ */ want_irq = false; dev_info(&client->dev, "'wakeup-source' is set, request for an IRQ is disabled!\n"); -- cgit v1.2.3 From 38bdcfc1fc734a91fd982fe32290f3f70612bf33 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Apr 2016 09:09:41 +1000 Subject: drm/nouveau/kms: fix setting of default values for dithering properties Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index ae96ebc490fb..e81aefe5ffa7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1276,18 +1276,18 @@ nouveau_connector_create(struct drm_device *dev, int index) break; default: if (disp->dithering_mode) { + nv_connector->dithering_mode = DITHERING_MODE_AUTO; drm_object_attach_property(&connector->base, disp->dithering_mode, nv_connector-> dithering_mode); - nv_connector->dithering_mode = DITHERING_MODE_AUTO; } if (disp->dithering_depth) { + nv_connector->dithering_depth = DITHERING_DEPTH_AUTO; drm_object_attach_property(&connector->base, disp->dithering_depth, nv_connector-> dithering_depth); - nv_connector->dithering_depth = DITHERING_DEPTH_AUTO; } break; } -- cgit v1.2.3 From deba0a2af9592b2022a0bce7b085a318b53ce1db Mon Sep 17 00:00:00 2001 From: "cpaul@redhat.com" Date: Mon, 4 Apr 2016 19:58:47 -0400 Subject: drm/dp/mst: Validate port in drm_dp_payload_send_msg() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the joys of things running concurrently, there's always a chance that the port we get passed in drm_dp_payload_send_msg() isn't actually valid anymore. Because of this, we need to make sure we validate the reference to the port before we use it otherwise we risk running into various race conditions. For instance, on the Dell MST monitor I have here for testing, hotplugging it enough times causes us to kernel panic: [drm:intel_mst_enable_dp] 1 [drm:drm_dp_update_payload_part2] payload 0 1 [drm:intel_get_hpd_pins] hotplug event received, stat 0x00200000, dig 0x10101011, pins 0x00000020 [drm:intel_hpd_irq_handler] digital hpd port B - short [drm:intel_dp_hpd_pulse] got hpd irq on port B - short [drm:intel_dp_check_mst_status] got esi 00 10 00 [drm:drm_dp_update_payload_part2] payload 1 1 general protection fault: 0000 [#1] SMP … Call Trace: [] drm_dp_update_payload_part2+0xc2/0x130 [drm_kms_helper] [] intel_mst_enable_dp+0xf8/0x180 [i915] [] haswell_crtc_enable+0x3ed/0x8c0 [i915] [] intel_atomic_commit+0x5ad/0x1590 [i915] [] ? drm_atomic_set_crtc_for_connector+0x57/0xe0 [drm] [] drm_atomic_commit+0x37/0x60 [drm] [] drm_atomic_helper_set_config+0x7a/0xb0 [drm_kms_helper] [] drm_mode_set_config_internal+0x62/0x100 [drm] [] drm_mode_setcrtc+0x3cd/0x4e0 [drm] [] drm_ioctl+0x143/0x510 [drm] [] ? drm_mode_setplane+0x1b0/0x1b0 [drm] [] ? hrtimer_start_range_ns+0x1b7/0x3a0 [] do_vfs_ioctl+0x92/0x570 [] ? __sys_recvmsg+0x42/0x80 [] SyS_ioctl+0x79/0x90 [] entry_SYSCALL_64_fastpath+0x1a/0xa4 RIP [] drm_dp_payload_send_msg+0x146/0x1f0 [drm_kms_helper] Which occurs because of the hotplug event shown in the log, which ends up causing DRM's dp helpers to drop the port we're updating the payload on and panic. CC: stable@vger.kernel.org Signed-off-by: Lyude Reviewed-by: David Airlie Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_dp_mst_topology.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 27fbd79d0daf..e17fbdaf874b 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1672,13 +1672,19 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr, u8 sinks[DRM_DP_MAX_SDP_STREAMS]; int i; + port = drm_dp_get_validated_port_ref(mgr, port); + if (!port) + return -EINVAL; + port_num = port->port_num; mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent); if (!mstb) { mstb = drm_dp_get_last_connected_port_and_mstb(mgr, port->parent, &port_num); - if (!mstb) + if (!mstb) { + drm_dp_put_port(port); return -EINVAL; + } } txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); @@ -1707,6 +1713,7 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr, kfree(txmsg); fail_put: drm_dp_put_mst_branch_device(mstb); + drm_dp_put_port(port); return ret; } -- cgit v1.2.3 From 3ea25f858fd5aeee888059952bbb8e910541eebb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 18 Apr 2016 18:09:57 -0400 Subject: drm/amdgpu: use defines for CRTCs and AMFT blocks Prerequiste for the next patch which ups the limits. Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 8d432e6901af..e4da6daf128e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -309,8 +309,8 @@ struct amdgpu_mode_info { struct atom_context *atom_context; struct card_info *atom_card_info; bool mode_config_initialized; - struct amdgpu_crtc *crtcs[6]; - struct amdgpu_afmt *afmt[7]; + struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS]; + struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS]; /* DVI-I properties */ struct drm_property *coherent_mode_property; /* DAC enable load detect */ -- cgit v1.2.3 From 83c5cda2ccf40a7a7e4bb674321509b346e23d5a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 18 Apr 2016 18:25:34 -0400 Subject: drm/amdgpu: bump the afmt limit for CZ, ST, Polaris Fixes array overflow on these chips. Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index e4da6daf128e..81bd964d3dfc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -53,7 +53,7 @@ struct amdgpu_hpd; #define AMDGPU_MAX_HPD_PINS 6 #define AMDGPU_MAX_CRTCS 6 -#define AMDGPU_MAX_AFMT_BLOCKS 7 +#define AMDGPU_MAX_AFMT_BLOCKS 9 enum amdgpu_rmx_type { RMX_OFF, -- cgit v1.2.3 From b5dcec693f87cb8475f2291c0075b2422addd3d6 Mon Sep 17 00:00:00 2001 From: Jérôme Glisse Date: Tue, 19 Apr 2016 09:07:50 -0400 Subject: drm/radeon: forbid mapping of userptr bo through radeon device file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allowing userptr bo which are basicly a list of page from some vma (so either anonymous page or file backed page) would lead to serious corruption of kernel structures and counters (because we overwrite the page->mapping field when mapping buffer). This will already block if the buffer was populated before anyone does try to mmap it because then TTM_PAGE_FLAG_SG would be set in in the ttm_tt flags. But that flag is check before ttm_tt_populate in the ttm vm fault handler. So to be safe just add a check to verify_access() callback. Reviewed-by: Christian König Signed-off-by: Jérôme Glisse Cc: Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_ttm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 7dddfdce85e6..90f739478a1b 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -235,6 +235,8 @@ static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp) { struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); + if (radeon_ttm_tt_has_userptr(bo->ttm)) + return -EPERM; return drm_vma_node_verify_access(&rbo->gem_base.vma_node, filp); } -- cgit v1.2.3 From 054892ed6a1645e265bc35641c2a96433a051453 Mon Sep 17 00:00:00 2001 From: Jérôme Glisse Date: Tue, 19 Apr 2016 09:07:51 -0400 Subject: drm/amdgpu: forbid mapping of userptr bo through radeon device file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allowing userptr bo which are basicly a list of page from some vma (so either anonymous page or file backed page) would lead to serious corruption of kernel structures and counters (because we overwrite the page->mapping field when mapping buffer). This will already block if the buffer was populated before anyone does try to mmap it because then TTM_PAGE_FLAG_SG would be set in in the ttm_tt flags. But that flag is check before ttm_tt_populate in the ttm vm fault handler. So to be safe just add a check to verify_access() callback. Reviewed-by: Christian König Signed-off-by: Jérôme Glisse Cc: Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 6f3369de232f..11af4492b4be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -223,6 +223,8 @@ static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) { struct amdgpu_bo *rbo = container_of(bo, struct amdgpu_bo, tbo); + if (amdgpu_ttm_tt_get_usermm(bo->ttm)) + return -EPERM; return drm_vma_node_verify_access(&rbo->gem_base.vma_node, filp); } -- cgit v1.2.3 From 562e2689baebaa2ac25b7ec934385480ed1cb7d6 Mon Sep 17 00:00:00 2001 From: Sonny Jiang Date: Mon, 18 Apr 2016 16:05:04 -0400 Subject: amdgpu/uvd: add uvd fw version for amdgpu Was previously always hardcoded to 0. Signed-off-by: Sonny Jiang Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index b77489dec6e8..1bcbade479dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1591,6 +1591,7 @@ struct amdgpu_uvd { struct amdgpu_bo *vcpu_bo; void *cpu_addr; uint64_t gpu_addr; + unsigned fw_version; void *saved_bo; atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index aef70db16832..b04337de65d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -303,7 +303,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file fw_info.feature = adev->vce.fb_version; break; case AMDGPU_INFO_FW_UVD: - fw_info.ver = 0; + fw_info.ver = adev->uvd.fw_version; fw_info.feature = 0; break; case AMDGPU_INFO_FW_GMC: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 8d035b65d967..871018c634e0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -158,6 +158,9 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n", version_major, version_minor, family_id); + adev->uvd.fw_version = ((version_major << 24) | (version_minor << 16) | + (family_id << 8)); + bo_size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8) + AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE; r = amdgpu_bo_create(adev, bo_size, PAGE_SIZE, true, -- cgit v1.2.3 From 28dca90533750c7e31e8641c3df426bad9c12941 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Apr 2016 10:05:21 +1000 Subject: drm/nouveau/gr/gf100: select a stream master to fixup tfb offset queries Signed-off-by: Ben Skeggs Cc: stable@vger.kernel.org --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index c56a886229f1..b2de290da16f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1832,6 +1832,8 @@ gf100_gr_init(struct gf100_gr *gr) gf100_gr_mmio(gr, gr->func->mmio); + nvkm_mask(device, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001); + memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); for (i = 0, gpc = -1; i < gr->tpc_total; i++) { do { -- cgit v1.2.3 From 221004c66a58949a0f25c937a6789c0839feb530 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 19 Apr 2016 19:19:11 +0800 Subject: drm: Loongson-3 doesn't fully support wc memory Signed-off-by: Huacai Chen Cc: stable@vger.kernel.org Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- include/drm/drm_cache.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/drm/drm_cache.h b/include/drm/drm_cache.h index 461a0558bca4..cebecff536a3 100644 --- a/include/drm/drm_cache.h +++ b/include/drm/drm_cache.h @@ -39,6 +39,8 @@ static inline bool drm_arch_can_wc_memory(void) { #if defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE) return false; +#elif defined(CONFIG_MIPS) && defined(CONFIG_CPU_LOONGSON3) + return false; #else return true; #endif -- cgit v1.2.3 From c2bb9e32e2315971a8535fee77335c04a739d71d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 20 Apr 2016 11:32:35 -0400 Subject: objtool: Fix Makefile to properly see if libelf is supported When doing a make allmodconfig, I hit the following compile error: In file included from builtin-check.c:32:0: elf.h:22:18: fatal error: gelf.h: No such file or directory compilation terminated. ... Digging into it, it appears that the $(shell ..) command in the Makefile does not give the proper result when it fails to find -lelf, and continues to compile objtool. Instead, use the "try-run" makefile macro to perform the test. This gives a proper result for both cases. Signed-off-by: Steven Rostedt Acked-by: Josh Poimboeuf Cc: Andrew Morton Cc: Andy Lutomirski Cc: Arnaldo Carvalho de Melo Cc: Bernd Petrovitsch Cc: Borislav Petkov Cc: Chris J Arges Cc: Jiri Slaby Cc: Linus Torvalds Cc: Michal Marek Cc: Namhyung Kim Cc: Pedro Alves Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: live-patching@vger.kernel.org Fixes: 442f04c34a1a4 ("objtool: Add tool to perform compile-time stack metadata validation") Link: http://lkml.kernel.org/r/20160420153234.GA24032@home.goodmis.org Signed-off-by: Ingo Molnar --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1d0aef03eae7..70ca38ef9f4b 100644 --- a/Makefile +++ b/Makefile @@ -1008,7 +1008,8 @@ prepare0: archprepare FORCE prepare: prepare0 prepare-objtool ifdef CONFIG_STACK_VALIDATION - has_libelf := $(shell echo "int main() {}" | $(HOSTCC) -xc -o /dev/null -lelf - &> /dev/null && echo 1 || echo 0) + has_libelf := $(call try-run,\ + echo "int main() {}" | $(HOSTCC) -xc -o /dev/null -lelf -,1,0) ifeq ($(has_libelf),1) objtool_target := tools/objtool FORCE else -- cgit v1.2.3 From 16eeed7e5558a3dcf30f75526a896b2632f299f9 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Tue, 19 Apr 2016 15:43:02 +0200 Subject: clocksource/drivers/tango-xtal: Fix boot hang due to incorrect test Commit 0881841f7e78 introduced a regression by inverting a test check after calling clocksource_mmio_init(). That results on the system to hang at boot time. Fix it by inverting the test again. Fixes: 0881841f7e78 ("Replace code by clocksource_mmio_init") Reported-by: Marc Gonzalez Signed-off-by: Daniel Lezcano --- drivers/clocksource/tango_xtal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/tango_xtal.c b/drivers/clocksource/tango_xtal.c index 2bcecafdeaea..c407c47a3232 100644 --- a/drivers/clocksource/tango_xtal.c +++ b/drivers/clocksource/tango_xtal.c @@ -42,7 +42,7 @@ static void __init tango_clocksource_init(struct device_node *np) ret = clocksource_mmio_init(xtal_in_cnt, "tango-xtal", xtal_freq, 350, 32, clocksource_mmio_readl_up); - if (!ret) { + if (ret) { pr_err("%s: registration failed\n", np->full_name); return; } -- cgit v1.2.3 From 3b9d6da67e11ca8f78fde887918983523a36b0fa Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 8 Apr 2016 14:40:15 +0200 Subject: cpu/hotplug: Fix rollback during error-out in __cpu_disable() The recent introduction of the hotplug thread which invokes the callbacks on the plugged cpu, cased the following regression: If takedown_cpu() fails, then we run into several issues: 1) The rollback of the target cpu states is not invoked. That leaves the smp threads and the hotplug thread in disabled state. 2) notify_online() is executed due to a missing skip_onerr flag. That causes that both CPU_DOWN_FAILED and CPU_ONLINE notifications are invoked which confuses quite some notifiers. 3) The CPU_DOWN_FAILED notification is not invoked on the target CPU. That's not an issue per se, but it is inconsistent and in consequence blocks the patches which rely on these states being invoked on the target CPU and not on the controlling cpu. It also does not preserve the strict call order on rollback which is problematic for the ongoing state machine conversion as well. To fix this we add a rollback flag to the remote callback machinery and invoke the rollback including the CPU_DOWN_FAILED notification on the remote cpu. Further mark the notify online state with 'skip_onerr' so we don't get a double invokation. This workaround will go away once we moved the unplug invocation to the target cpu itself. [ tglx: Massaged changelog and moved the CPU_DOWN_FAILED notifiaction to the target cpu ] Fixes: 4cb28ced23c4 ("cpu/hotplug: Create hotplug threads") Reported-by: Heiko Carstens Signed-off-by: Sebastian Andrzej Siewior Cc: linux-s390@vger.kernel.org Cc: rt@linutronix.de Cc: Martin Schwidefsky Cc: Anna-Maria Gleixner Link: http://lkml.kernel.org/r/20160408124015.GA21960@linutronix.de Signed-off-by: Thomas Gleixner --- kernel/cpu.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/kernel/cpu.c b/kernel/cpu.c index 6ea42e8da861..3e3f6e49eabb 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -36,6 +36,7 @@ * @target: The target state * @thread: Pointer to the hotplug thread * @should_run: Thread should execute + * @rollback: Perform a rollback * @cb_stat: The state for a single callback (install/uninstall) * @cb: Single callback function (install/uninstall) * @result: Result of the operation @@ -47,6 +48,7 @@ struct cpuhp_cpu_state { #ifdef CONFIG_SMP struct task_struct *thread; bool should_run; + bool rollback; enum cpuhp_state cb_state; int (*cb)(unsigned int cpu); int result; @@ -301,6 +303,11 @@ static int cpu_notify(unsigned long val, unsigned int cpu) return __cpu_notify(val, cpu, -1, NULL); } +static void cpu_notify_nofail(unsigned long val, unsigned int cpu) +{ + BUG_ON(cpu_notify(val, cpu)); +} + /* Notifier wrappers for transitioning to state machine */ static int notify_prepare(unsigned int cpu) { @@ -477,6 +484,16 @@ static void cpuhp_thread_fun(unsigned int cpu) } else { ret = cpuhp_invoke_callback(cpu, st->cb_state, st->cb); } + } else if (st->rollback) { + BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE); + + undo_cpu_down(cpu, st, cpuhp_ap_states); + /* + * This is a momentary workaround to keep the notifier users + * happy. Will go away once we got rid of the notifiers. + */ + cpu_notify_nofail(CPU_DOWN_FAILED, cpu); + st->rollback = false; } else { /* Cannot happen .... */ BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE); @@ -636,11 +653,6 @@ static inline void check_for_tasks(int dead_cpu) read_unlock(&tasklist_lock); } -static void cpu_notify_nofail(unsigned long val, unsigned int cpu) -{ - BUG_ON(cpu_notify(val, cpu)); -} - static int notify_down_prepare(unsigned int cpu) { int err, nr_calls = 0; @@ -721,9 +733,10 @@ static int takedown_cpu(unsigned int cpu) */ err = stop_machine(take_cpu_down, NULL, cpumask_of(cpu)); if (err) { - /* CPU didn't die: tell everyone. Can't complain. */ - cpu_notify_nofail(CPU_DOWN_FAILED, cpu); + /* CPU refused to die */ irq_unlock_sparse(); + /* Unpark the hotplug thread so we can rollback there */ + kthread_unpark(per_cpu_ptr(&cpuhp_state, cpu)->thread); return err; } BUG_ON(cpu_online(cpu)); @@ -832,6 +845,11 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, * to do the further cleanups. */ ret = cpuhp_down_callbacks(cpu, st, cpuhp_bp_states, target); + if (ret && st->state > CPUHP_TEARDOWN_CPU && st->state < prev_state) { + st->target = prev_state; + st->rollback = true; + cpuhp_kick_ap_work(cpu); + } hasdied = prev_state != st->state && st->state == CPUHP_OFFLINE; out: @@ -1249,6 +1267,7 @@ static struct cpuhp_step cpuhp_ap_states[] = { .name = "notify:online", .startup = notify_online, .teardown = notify_down_prepare, + .skip_onerr = true, }, #endif /* -- cgit v1.2.3 From 78b0634d2851d30ec5d289aefbae23b141de67f0 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Fri, 22 Apr 2016 09:35:04 +0200 Subject: x86/doc: Correct limits in Documentation/x86/x86_64/mm.txt Correct the size of the module mapping space and the maximum available physical memory size of current processors. Signed-off-by: Juergen Gross Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: corbet@lwn.net Cc: linux-doc@vger.kernel.org Link: http://lkml.kernel.org/r/1461310504-15977-1-git-send-email-jgross@suse.com Signed-off-by: Ingo Molnar --- Documentation/x86/x86_64/mm.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt index c518dce7da4d..5aa738346062 100644 --- a/Documentation/x86/x86_64/mm.txt +++ b/Documentation/x86/x86_64/mm.txt @@ -19,7 +19,7 @@ ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks ffffffef00000000 - ffffffff00000000 (=64 GB) EFI region mapping space ... unused hole ... ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0 -ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space +ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole @@ -31,8 +31,8 @@ vmalloc space is lazily synchronized into the different PML4 pages of the processes using the page fault handler, with init_level4_pgt as reference. -Current X86-64 implementations only support 40 bits of address space, -but we support up to 46 bits. This expands into MBZ space in the page tables. +Current X86-64 implementations support up to 46 bits of address space (64 TB), +which is our current limit. This expands into MBZ space in the page tables. We map EFI runtime services in the 'efi_pgd' PGD in a 64Gb large virtual memory window (this size is arbitrary, it can be raised later if needed). -- cgit v1.2.3 From 103f6112f253017d7062cd74d17f4a514ed4485c Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 21 Apr 2016 00:27:04 -0600 Subject: x86/mm/xen: Suppress hugetlbfs in PV guests Huge pages are not normally available to PV guests. Not suppressing hugetlbfs use results in an endless loop of page faults when user mode code tries to access a hugetlbfs mapped area (since the hypervisor denies such PTEs to be created, but error indications can't be propagated out of xen_set_pte_at(), just like for various of its siblings), and - once killed in an oops like this: kernel BUG at .../fs/hugetlbfs/inode.c:428! invalid opcode: 0000 [#1] SMP ... RIP: e030:[] [] remove_inode_hugepages+0x25b/0x320 ... Call Trace: [] hugetlbfs_evict_inode+0x15/0x40 [] evict+0xbd/0x1b0 [] __dentry_kill+0x19a/0x1f0 [] dput+0x1fe/0x220 [] __fput+0x155/0x200 [] task_work_run+0x60/0xa0 [] do_exit+0x160/0x400 [] do_group_exit+0x3b/0xa0 [] get_signal+0x1ed/0x470 [] do_signal+0x14/0x110 [] prepare_exit_to_usermode+0xe9/0xf0 [] retint_user+0x8/0x13 This is CVE-2016-3961 / XSA-174. Reported-by: Vitaly Kuznetsov Signed-off-by: Jan Beulich Cc: Andrew Morton Cc: Andy Lutomirski Cc: Boris Ostrovsky Cc: Borislav Petkov Cc: Brian Gerst Cc: David Vrabel Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Juergen Gross Cc: Linus Torvalds Cc: Luis R. Rodriguez Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Toshi Kani Cc: stable@vger.kernel.org Cc: xen-devel Link: http://lkml.kernel.org/r/57188ED802000078000E431C@prv-mh.provo.novell.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/hugetlb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h index f8a29d2c97b0..e6a8613fbfb0 100644 --- a/arch/x86/include/asm/hugetlb.h +++ b/arch/x86/include/asm/hugetlb.h @@ -4,6 +4,7 @@ #include #include +#define hugepages_supported() cpu_has_pse static inline int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, -- cgit v1.2.3 From ff15e95c82768d589957dbb17d7eb7dba7904659 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 14 Apr 2016 10:21:52 -0700 Subject: x86 EDAC, sb_edac.c: Repair damage introduced when "fixing" channel address In commit: eb1af3b71f9d ("Fix computation of channel address") I switched the "sck_way" variable from holding the log2 value read from the h/w to instead be the actual number. Unfortunately it is needed in log2 form when used to shift the address. Tested-by: Patrick Geary Signed-off-by: Tony Luck Acked-by: Mauro Carvalho Chehab Cc: Aristeu Rozanski Cc: Borislav Petkov Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-edac@vger.kernel.org Cc: stable@vger.kernel.org Fixes: eb1af3b71f9d ("Fix computation of channel address") Signed-off-by: Ingo Molnar --- drivers/edac/sb_edac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 93f0d4120289..f4666b0aeba6 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -2118,7 +2118,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci, } ch_way = TAD_CH(reg) + 1; - sck_way = 1 << TAD_SOCK(reg); + sck_way = TAD_SOCK(reg); if (ch_way == 3) idx = addr >> 6; @@ -2157,7 +2157,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci, switch(ch_way) { case 2: case 4: - sck_xch = 1 << sck_way * (ch_way >> 1); + sck_xch = (1 << sck_way) * (ch_way >> 1); break; default: sprintf(msg, "Invalid mirror set. Can't decode addr"); @@ -2193,7 +2193,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci, ch_addr = addr - offset; ch_addr >>= (6 + shiftup); - ch_addr /= ch_way * sck_way; + ch_addr /= sck_xch; ch_addr <<= (6 + shiftup); ch_addr |= addr & ((1 << (6 + shiftup)) - 1); -- cgit v1.2.3 From ea5dfb5fae81939f777ca569d8cfb599252da2e8 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 14 Apr 2016 10:22:02 -0700 Subject: x86 EDAC, sb_edac.c: Take account of channel hashing when needed Haswell and Broadwell can be configured to hash the channel interleave function using bits [27:12] of the physical address. On those processor models we must check to see if hashing is enabled (bit21 of the HASWELL_HASYSDEFEATURE2 register) and act accordingly. Based on a patch by patrickg Tested-by: Patrick Geary Signed-off-by: Tony Luck Acked-by: Mauro Carvalho Chehab Cc: Aristeu Rozanski Cc: Borislav Petkov Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-edac@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Ingo Molnar --- drivers/edac/sb_edac.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index f4666b0aeba6..468447aff8eb 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -362,6 +362,7 @@ struct sbridge_pvt { /* Memory type detection */ bool is_mirrored, is_lockstep, is_close_pg; + bool is_chan_hash; /* Fifo double buffers */ struct mce mce_entry[MCE_LOG_LEN]; @@ -1060,6 +1061,20 @@ static inline u8 sad_pkg_ha(u8 pkg) return (pkg >> 2) & 0x1; } +static int haswell_chan_hash(int idx, u64 addr) +{ + int i; + + /* + * XOR even bits from 12:26 to bit0 of idx, + * odd bits from 13:27 to bit1 + */ + for (i = 12; i < 28; i += 2) + idx ^= (addr >> i) & 3; + + return idx; +} + /**************************************************************************** Memory check routines ****************************************************************************/ @@ -1616,6 +1631,10 @@ static int get_dimm_config(struct mem_ctl_info *mci) KNL_MAX_CHANNELS : NUM_CHANNELS; u64 knl_mc_sizes[KNL_MAX_CHANNELS]; + if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL) { + pci_read_config_dword(pvt->pci_ha0, HASWELL_HASYSDEFEATURE2, ®); + pvt->is_chan_hash = GET_BITFIELD(reg, 21, 21); + } if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL || pvt->info.type == KNIGHTS_LANDING) pci_read_config_dword(pvt->pci_sad1, SAD_TARGET, ®); @@ -2122,8 +2141,11 @@ static int get_memory_error_data(struct mem_ctl_info *mci, if (ch_way == 3) idx = addr >> 6; - else + else { idx = (addr >> (6 + sck_way + shiftup)) & 0x3; + if (pvt->is_chan_hash) + idx = haswell_chan_hash(idx, addr); + } idx = idx % ch_way; /* -- cgit v1.2.3 From d9676fa152c83b82137af950b1d4f629045d90c9 Mon Sep 17 00:00:00 2001 From: Evgeny Voevodin Date: Wed, 23 Mar 2016 12:26:52 +0300 Subject: ARCv2: Enable LOCKDEP - The asm helpers for calling into irq tracer were missing - Add calls to above helpers in low level assembly entry code for ARCv2 - irq_save() uses CLRI to disable interrupts and returns the prev interrupt state (in STATUS32) in a specific encoding (and not the raw value of STATUS32). This is usable with SETI in irq_restore(). However save_flags() reads the raw value of STATUS32 which doesn't pair with irq_save/restore() and thus needs fixing. Signed-off-by: Evgeny Voevodin [vgupta: updated changelog and also added some comments] Signed-off-by: Vineet Gupta --- arch/arc/include/asm/irqflags-arcv2.h | 36 ++++++++++++++++++++++++++++++++++- arch/arc/kernel/entry-arcv2.S | 10 +++++++++- arch/arc/kernel/entry-compact.S | 3 +++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/arch/arc/include/asm/irqflags-arcv2.h b/arch/arc/include/asm/irqflags-arcv2.h index 37c2f751eebf..d1ec7f6b31e0 100644 --- a/arch/arc/include/asm/irqflags-arcv2.h +++ b/arch/arc/include/asm/irqflags-arcv2.h @@ -18,6 +18,12 @@ #define STATUS_AD_MASK (1< Date: Wed, 13 Apr 2016 13:59:14 +1000 Subject: i2c: cpm: Fix build break due to incompatible pointer types Since commit ea8daa7b9784 ("kbuild: Add option to turn incompatible pointer check into error"), assignments from an incompatible pointer types have become a hard error, eg: drivers/i2c/busses/i2c-cpm.c:545:91: error: passing argument 3 of 'dma_alloc_coherent' from incompatible pointer type Fix the build break by converting txdma & rxdma to dma_addr_t. Signed-off-by: Michael Ellerman Signed-off-by: Wolfram Sang Cc: stable@kernel.org Fixes: ea8daa7b9784 --- drivers/i2c/busses/i2c-cpm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 714bdc837769..b167ab25310a 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -116,8 +116,8 @@ struct cpm_i2c { cbd_t __iomem *rbase; u_char *txbuf[CPM_MAXBD]; u_char *rxbuf[CPM_MAXBD]; - u32 txdma[CPM_MAXBD]; - u32 rxdma[CPM_MAXBD]; + dma_addr_t txdma[CPM_MAXBD]; + dma_addr_t rxdma[CPM_MAXBD]; }; static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id) -- cgit v1.2.3 From 10ff4c5239a137abfc896ec73ef3d15a0f86a16a Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 16 Apr 2016 21:14:52 -0400 Subject: i2c: exynos5: Fix possible ABBA deadlock by keeping I2C clock prepared The exynos5 I2C controller driver always prepares and enables a clock before using it and then disables unprepares it when the clock is not used anymore. But this can cause a possible ABBA deadlock in some scenarios since a driver that uses regmap to access its I2C registers, will first grab the regmap lock and then the I2C xfer function will grab the prepare lock when preparing the I2C clock. But since the clock driver also uses regmap for I2C accesses, preparing a clock will first grab the prepare lock and then the regmap lock when using the regmap API. An example of this happens on the Exynos5422 Odroid XU4 board where a s2mps11 PMIC is used and both the s2mps11 regulators and clk drivers share the same I2C regmap. The possible deadlock is reported by the kernel lockdep: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(sec_core:428:(regmap)->lock); lock(prepare_lock); lock(sec_core:428:(regmap)->lock); lock(prepare_lock); *** DEADLOCK *** Fix it by leaving the code prepared on probe and use {en,dis}able in the I2C transfer function. This patch is similar to commit 34e81ad5f0b6 ("i2c: s3c2410: fix ABBA deadlock by keeping clock prepared") that fixes the same bug in other driver for an I2C controller found in Samsung SoCs. Reported-by: Anand Moon Signed-off-by: Javier Martinez Canillas Reviewed-by: Anand Moon Reviewed-by: Krzysztof Kozlowski Signed-off-by: Wolfram Sang Cc: stable@kernel.org --- drivers/i2c/busses/i2c-exynos5.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c index b29c7500461a..f54ece8fce78 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -671,7 +671,9 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, return -EIO; } - clk_prepare_enable(i2c->clk); + ret = clk_enable(i2c->clk); + if (ret) + return ret; for (i = 0; i < num; i++, msgs++) { stop = (i == num - 1); @@ -695,7 +697,7 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, } out: - clk_disable_unprepare(i2c->clk); + clk_disable(i2c->clk); return ret; } @@ -747,7 +749,9 @@ static int exynos5_i2c_probe(struct platform_device *pdev) return -ENOENT; } - clk_prepare_enable(i2c->clk); + ret = clk_prepare_enable(i2c->clk); + if (ret) + return ret; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); i2c->regs = devm_ioremap_resource(&pdev->dev, mem); @@ -799,6 +803,10 @@ static int exynos5_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2c); + clk_disable(i2c->clk); + + return 0; + err_clk: clk_disable_unprepare(i2c->clk); return ret; @@ -810,6 +818,8 @@ static int exynos5_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&i2c->adap); + clk_unprepare(i2c->clk); + return 0; } @@ -821,6 +831,8 @@ static int exynos5_i2c_suspend_noirq(struct device *dev) i2c->suspended = 1; + clk_unprepare(i2c->clk); + return 0; } @@ -830,7 +842,9 @@ static int exynos5_i2c_resume_noirq(struct device *dev) struct exynos5_i2c *i2c = platform_get_drvdata(pdev); int ret = 0; - clk_prepare_enable(i2c->clk); + ret = clk_prepare_enable(i2c->clk); + if (ret) + return ret; ret = exynos5_hsi2c_clock_setup(i2c); if (ret) { @@ -839,7 +853,7 @@ static int exynos5_i2c_resume_noirq(struct device *dev) } exynos5_i2c_init(i2c); - clk_disable_unprepare(i2c->clk); + clk_disable(i2c->clk); i2c->suspended = 0; return 0; -- cgit v1.2.3 From 630ba0cc7a6dbafbdee43795617c872b35cde1b4 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 21 Apr 2016 18:21:11 +0200 Subject: efi: Fix out-of-bounds read in variable_matches() The variable_matches() function can currently read "var_name[len]", for example when: - var_name[0] == 'a', - len == 1 - match_name points to the NUL-terminated string "ab". This function is supposed to accept "var_name" inputs that are not NUL-terminated (hence the "len" parameter"). Document the function, and access "var_name[*match]" only if "*match" is smaller than "len". Reported-by: Chris Wilson Signed-off-by: Laszlo Ersek Cc: Peter Jones Cc: Matthew Garrett Cc: Jason Andryuk Cc: Jani Nikula Cc: # v3.10+ Link: http://thread.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/86906 Signed-off-by: Matt Fleming --- drivers/firmware/efi/vars.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index 0ac594c0a234..34b741940494 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c @@ -202,29 +202,44 @@ static const struct variable_validate variable_validate[] = { { NULL_GUID, "", NULL }, }; +/* + * Check if @var_name matches the pattern given in @match_name. + * + * @var_name: an array of @len non-NUL characters. + * @match_name: a NUL-terminated pattern string, optionally ending in "*". A + * final "*" character matches any trailing characters @var_name, + * including the case when there are none left in @var_name. + * @match: on output, the number of non-wildcard characters in @match_name + * that @var_name matches, regardless of the return value. + * @return: whether @var_name fully matches @match_name. + */ static bool variable_matches(const char *var_name, size_t len, const char *match_name, int *match) { for (*match = 0; ; (*match)++) { char c = match_name[*match]; - char u = var_name[*match]; - /* Wildcard in the matching name means we've matched */ - if (c == '*') + switch (c) { + case '*': + /* Wildcard in @match_name means we've matched. */ return true; - /* Case sensitive match */ - if (!c && *match == len) - return true; + case '\0': + /* @match_name has ended. Has @var_name too? */ + return (*match == len); - if (c != u) + default: + /* + * We've reached a non-wildcard char in @match_name. + * Continue only if there's an identical character in + * @var_name. + */ + if (*match < len && c == var_name[*match]) + continue; return false; - - if (!c) - return true; + } } - return true; } bool -- cgit v1.2.3 From f4e7de63ab273b6a5e35c82eb4fc6363c855ddd4 Mon Sep 17 00:00:00 2001 From: Doug Ledford Date: Fri, 22 Apr 2016 20:14:58 -0400 Subject: IB/core: Fix oops in ib_cache_gid_set_default_gid When we fail to find the default gid index, we can't continue processing in this routine or else we will pass a negative index to later routines resulting in invalid memory access attempts and a kernel oops. Fixes: 03db3a2d81e6 (IB/core: Add RoCE GID table management) Signed-off-by: Doug Ledford --- drivers/infiniband/core/cache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index cb00d59da456..c2e257d97eff 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -691,7 +691,8 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, NULL); /* Coudn't find default GID location */ - WARN_ON(ix < 0); + if (WARN_ON(ix < 0)) + goto release; zattr_type.gid_type = gid_type; -- cgit v1.2.3 From 707e59ba494372a90d245f18b0c78982caa88e48 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Fri, 22 Apr 2016 13:05:31 +0100 Subject: xen/qspinlock: Don't kick CPU if IRQ is not initialized The following commit: 1fb3a8b2cfb2 ("xen/spinlock: Fix locking path engaging too soon under PVHVM.") ... moved the initalization of the kicker interrupt until after native_cpu_up() is called. However, when using qspinlocks, a CPU may try to kick another CPU that is spinning (because it has not yet initialized its kicker interrupt), resulting in the following crash during boot: kernel BUG at /build/linux-Ay7j_C/linux-4.4.0/drivers/xen/events/events_base.c:1210! invalid opcode: 0000 [#1] SMP ... RIP: 0010:[] [] xen_send_IPI_one+0x59/0x60 ... Call Trace: [] xen_qlock_kick+0xe/0x10 [] __pv_queued_spin_unlock+0xb2/0xf0 [] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x20 [] ? check_tsc_warp+0x76/0x150 [] check_tsc_sync_source+0x96/0x160 [] native_cpu_up+0x3d8/0x9f0 [] xen_hvm_cpu_up+0x35/0x80 [] _cpu_up+0x13c/0x180 [] cpu_up+0x7a/0xa0 [] smp_init+0x7f/0x81 [] kernel_init_freeable+0xef/0x212 [] ? rest_init+0x80/0x80 [] kernel_init+0xe/0xe0 [] ret_from_fork+0x3f/0x70 [] ? rest_init+0x80/0x80 To fix this, only send the kick if the target CPU's interrupt has been initialized. This check isn't racy, because the target is waiting for the spinlock, so it won't have initialized the interrupt in the meantime. Signed-off-by: Ross Lagerwall Reviewed-by: Boris Ostrovsky Cc: David Vrabel Cc: Juergen Gross Cc: Konrad Rzeszutek Wilk Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Cc: xen-devel@lists.xenproject.org Signed-off-by: Ingo Molnar --- arch/x86/xen/spinlock.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 9e2ba5c6e1dd..f42e78de1e10 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -27,6 +27,12 @@ static bool xen_pvspin = true; static void xen_qlock_kick(int cpu) { + int irq = per_cpu(lock_kicker_irq, cpu); + + /* Don't kick if the target's kicker interrupt is not initialized. */ + if (irq == -1) + return; + xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR); } -- cgit v1.2.3 From b89c173788c3a8ed571652c203bf59a0e9d700aa Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 15 Apr 2016 13:25:33 -0700 Subject: perf/x86/intel: Add model number for Skylake Server to perf Everything the same as base Skylake, just a new model number. Signed-off-by: Andi Kleen Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: http://lkml.kernel.org/r/1460751933-2264-1-git-send-email-andi@firstfloor.org Signed-off-by: Ingo Molnar --- arch/x86/events/intel/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 68fa55b4d42e..aff79884e17d 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3639,6 +3639,7 @@ __init int intel_pmu_init(void) case 78: /* 14nm Skylake Mobile */ case 94: /* 14nm Skylake Desktop */ + case 85: /* 14nm Skylake Server */ x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); -- cgit v1.2.3 From e1089602a3bf3efd13d0ffc575f3e22213f009da Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Sun, 17 Apr 2016 08:43:29 -0700 Subject: perf/x86/intel/rapl: Add missing Haswell model Added one missing Haswell model. Signed-off-by: Srinivas Pandruvada Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: bp@alien8.de Cc: hpa@zytor.com Link: http://lkml.kernel.org/r/1460907809-11897-1-git-send-email-srinivas.pandruvada@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/events/intel/rapl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index 70c93f9b03ac..1705c9d75e44 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c @@ -718,6 +718,7 @@ static int __init rapl_pmu_init(void) break; case 60: /* Haswell */ case 69: /* Haswell-Celeron */ + case 70: /* Haswell GT3e */ case 61: /* Broadwell */ case 71: /* Broadwell-H */ rapl_cntr_mask = RAPL_IDX_HSW; -- cgit v1.2.3 From b303e7c15d53cd8ef6b349b702e07eee3f102792 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 4 Apr 2016 09:57:40 +0200 Subject: perf/core: Make sysctl_perf_cpu_time_max_percent conform to documentation Markus reported that 0 should also disable the throttling we per Documentation/sysctl/kernel.txt. Reported-by: Markus Trippelsdorf Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Fixes: 91a612eea9a3 ("perf/core: Fix dynamic interrupt throttle") Signed-off-by: Ingo Molnar --- kernel/events/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 52bedc5a5aaa..2c78b6f47339 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -412,7 +412,8 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, if (ret || !write) return ret; - if (sysctl_perf_cpu_time_max_percent == 100) { + if (sysctl_perf_cpu_time_max_percent == 100 || + sysctl_perf_cpu_time_max_percent == 0) { printk(KERN_WARNING "perf: Dynamic interrupt throttling disabled, can hang your system!\n"); WRITE_ONCE(perf_sample_allowed_ns, 0); -- cgit v1.2.3 From c24697566298df04cac9913e0601501b5ee2b3f5 Mon Sep 17 00:00:00 2001 From: Boqun Feng Date: Tue, 16 Feb 2016 13:57:40 +0800 Subject: locking/lockdep: Fix ->irq_context calculation task_irq_context() returns the encoded irq_context of the task, the return value is encoded in the same as ->irq_context of held_lock. Always return 0 if !(CONFIG_TRACE_IRQFLAGS && CONFIG_PROVE_LOCKING) Signed-off-by: Boqun Feng Signed-off-by: Peter Zijlstra (Intel) Cc: Andrew Morton Cc: Josh Triplett Cc: Lai Jiangshan Cc: Linus Torvalds Cc: Mathieu Desnoyers Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Steven Rostedt Cc: Thomas Gleixner Cc: sasha.levin@oracle.com Link: http://lkml.kernel.org/r/1455602265-16490-2-git-send-email-boqun.feng@gmail.com Signed-off-by: Ingo Molnar --- kernel/locking/lockdep.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index ed9410936a22..beb06f604420 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -2932,6 +2932,11 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) return 1; } +static inline unsigned int task_irq_context(struct task_struct *task) +{ + return 2 * !!task->hardirq_context + !!task->softirq_context; +} + static int separate_irq_context(struct task_struct *curr, struct held_lock *hlock) { @@ -2940,8 +2945,6 @@ static int separate_irq_context(struct task_struct *curr, /* * Keep track of points where we cross into an interrupt context: */ - hlock->irq_context = 2*(curr->hardirq_context ? 1 : 0) + - curr->softirq_context; if (depth) { struct held_lock *prev_hlock; @@ -2973,6 +2976,11 @@ static inline int mark_irqflags(struct task_struct *curr, return 1; } +static inline unsigned int task_irq_context(struct task_struct *task) +{ + return 0; +} + static inline int separate_irq_context(struct task_struct *curr, struct held_lock *hlock) { @@ -3241,6 +3249,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, hlock->acquire_ip = ip; hlock->instance = lock; hlock->nest_lock = nest_lock; + hlock->irq_context = task_irq_context(curr); hlock->trylock = trylock; hlock->read = read; hlock->check = check; -- cgit v1.2.3 From 75dd602a5198a6e5f75534db52b6e6fbaabb33d1 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 30 Mar 2016 11:36:59 +0200 Subject: lockdep: Fix lock_chain::base size lock_chain::base is used to store an index into the chain_hlocks[] array, however that array contains more elements than can be indexed using the u16. Change the lock_chain structure to use a bitfield to encode the data it needs and add BUILD_BUG_ON() assertions to check the fields are wide enough. Also, for DEBUG_LOCKDEP, assert that we don't run out of elements of that array; as that would wreck the collision detectoring. Signed-off-by: Peter Zijlstra (Intel) Cc: Alfredo Alvarez Fernandez Cc: Andrew Morton Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Sedat Dilek Cc: Theodore Ts'o Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/20160330093659.GS3408@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar --- include/linux/lockdep.h | 8 +++++--- kernel/locking/lockdep.c | 24 +++++++++++++++++++++++- kernel/locking/lockdep_proc.c | 2 ++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index d026b190c530..d10ef06971b5 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -196,9 +196,11 @@ struct lock_list { * We record lock dependency chains, so that we can cache them: */ struct lock_chain { - u8 irq_context; - u8 depth; - u16 base; + /* see BUILD_BUG_ON()s in lookup_chain_cache() */ + unsigned int irq_context : 2, + depth : 6, + base : 24; + /* 4 byte hole */ struct hlist_node entry; u64 chain_key; }; diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index beb06f604420..78c1c0ee6dc1 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -2176,15 +2176,37 @@ cache_hit: chain->irq_context = hlock->irq_context; i = get_first_held_lock(curr, hlock); chain->depth = curr->lockdep_depth + 1 - i; + + BUILD_BUG_ON((1UL << 24) <= ARRAY_SIZE(chain_hlocks)); + BUILD_BUG_ON((1UL << 6) <= ARRAY_SIZE(curr->held_locks)); + BUILD_BUG_ON((1UL << 8*sizeof(chain_hlocks[0])) <= ARRAY_SIZE(lock_classes)); + if (likely(nr_chain_hlocks + chain->depth <= MAX_LOCKDEP_CHAIN_HLOCKS)) { chain->base = nr_chain_hlocks; - nr_chain_hlocks += chain->depth; for (j = 0; j < chain->depth - 1; j++, i++) { int lock_id = curr->held_locks[i].class_idx - 1; chain_hlocks[chain->base + j] = lock_id; } chain_hlocks[chain->base + j] = class - lock_classes; } + + if (nr_chain_hlocks < MAX_LOCKDEP_CHAIN_HLOCKS) + nr_chain_hlocks += chain->depth; + +#ifdef CONFIG_DEBUG_LOCKDEP + /* + * Important for check_no_collision(). + */ + if (unlikely(nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS)) { + if (debug_locks_off_graph_unlock()) + return 0; + + print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!"); + dump_stack(); + return 0; + } +#endif + hlist_add_head_rcu(&chain->entry, hash_head); debug_atomic_inc(chain_lookup_misses); inc_chains(); diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c index dbb61a302548..a0f61effad25 100644 --- a/kernel/locking/lockdep_proc.c +++ b/kernel/locking/lockdep_proc.c @@ -141,6 +141,8 @@ static int lc_show(struct seq_file *m, void *v) int i; if (v == SEQ_START_TOKEN) { + if (nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS) + seq_printf(m, "(buggered) "); seq_printf(m, "all lock chains:\n"); return 0; } -- cgit v1.2.3 From 56896ef5b990a3822da45f92e548c4c8ac301bb4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 15 Apr 2016 19:30:46 +0900 Subject: arm64: dts: uniphier: fix I2C nodes of PH1-LD20 The I2C hardware blocks on this SoC are connected as follows: I2C0: external connection I2C1: external connection I2C2: internal connection I2C3: external connection I2C4: external connection I2C5: internal connection I2C6: no connection (not accessible) Delete pinctrl from Ch2, add pinctrl to Ch4, and remove the Ch6 node. Signed-off-by: Masahiro Yamada Signed-off-by: Arnd Bergmann --- .../boot/dts/socionext/uniphier-ph1-ld20-ref.dts | 1 - arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi | 20 +++++--------------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts index 727ae5f8c4e7..b0ed44313a5b 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts @@ -70,7 +70,6 @@ i2c3 = &i2c3; i2c4 = &i2c4; i2c5 = &i2c5; - i2c6 = &i2c6; }; }; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi index e682a3f52791..651c9d9d2d54 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi @@ -201,15 +201,12 @@ i2c2: i2c@58782000 { compatible = "socionext,uniphier-fi2c"; - status = "disabled"; reg = <0x58782000 0x80>; #address-cells = <1>; #size-cells = <0>; interrupts = <0 43 4>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c2>; clocks = <&i2c_clk>; - clock-frequency = <100000>; + clock-frequency = <400000>; }; i2c3: i2c@58783000 { @@ -227,12 +224,15 @@ i2c4: i2c@58784000 { compatible = "socionext,uniphier-fi2c"; + status = "disabled"; reg = <0x58784000 0x80>; #address-cells = <1>; #size-cells = <0>; interrupts = <0 45 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; clocks = <&i2c_clk>; - clock-frequency = <400000>; + clock-frequency = <100000>; }; i2c5: i2c@58785000 { @@ -245,16 +245,6 @@ clock-frequency = <400000>; }; - i2c6: i2c@58786000 { - compatible = "socionext,uniphier-fi2c"; - reg = <0x58786000 0x80>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 26 4>; - clocks = <&i2c_clk>; - clock-frequency = <400000>; - }; - system_bus: system-bus@58c00000 { compatible = "socionext,uniphier-system-bus"; status = "disabled"; -- cgit v1.2.3 From 987aedb5d6f6e10c5203c6d0aab9a60ec22c7e93 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 11 Apr 2016 10:17:46 +0100 Subject: generic syscalls: wire up preadv2 and pwritev2 syscalls These new syscalls are implemented as generic code, so enable them for architectures like arm64 which use the generic syscall table. Signed-off-by: Andre Przywara Signed-off-by: Arnd Bergmann --- include/uapi/asm-generic/unistd.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 2622b33fb2ec..6e0f5f01734c 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -717,9 +717,13 @@ __SYSCALL(__NR_membarrier, sys_membarrier) __SYSCALL(__NR_mlock2, sys_mlock2) #define __NR_copy_file_range 285 __SYSCALL(__NR_copy_file_range, sys_copy_file_range) +#define __NR_preadv2 286 +__SYSCALL(__NR_preadv2, sys_preadv2) +#define __NR_pwritev2 287 +__SYSCALL(__NR_pwritev2, sys_pwritev2) #undef __NR_syscalls -#define __NR_syscalls 286 +#define __NR_syscalls 288 /* * All syscalls below here should go away really, -- cgit v1.2.3 From c78296665c3d81f040117432ab9e1cb125521b0c Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Fri, 26 Feb 2016 17:56:13 +0100 Subject: batman-adv: Check skb size before using encapsulated ETH+VLAN header The encapsulated ethernet and VLAN header may be outside the received ethernet frame. Thus the skb buffer size has to be checked before it can be parsed to find out if it encapsulates another batman-adv packet. Fixes: 420193573f11 ("batman-adv: softif bridge loop avoidance") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/soft-interface.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 0710379491bf..8a136b6a1ff0 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -408,11 +408,17 @@ void batadv_interface_rx(struct net_device *soft_iface, */ nf_reset(skb); + if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) + goto dropped; + vid = batadv_get_vid(skb, 0); ethhdr = eth_hdr(skb); switch (ntohs(ethhdr->h_proto)) { case ETH_P_8021Q: + if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) + goto dropped; + vhdr = (struct vlan_ethhdr *)skb->data; if (vhdr->h_vlan_encapsulated_proto != ethertype) @@ -424,8 +430,6 @@ void batadv_interface_rx(struct net_device *soft_iface, } /* skb->dev & skb->pkt_type are set here */ - if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) - goto dropped; skb->protocol = eth_type_trans(skb, soft_iface); /* should not be necessary anymore as we use skb_pull_rcsum() -- cgit v1.2.3 From e48474ed8a217b7f80f2a42bc05352406a06cb67 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Fri, 11 Mar 2016 16:01:09 +0100 Subject: batman-adv: init neigh node last seen field Signed-off-by: Marek Lindner [sven@narfation.org: fix conflicts with current version] Signed-off-by: Sven Eckelmann Signed-off-by: Antonio Quartulli --- net/batman-adv/originator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index e4cbb0753e37..d52f67a0c057 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -663,6 +663,7 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, ether_addr_copy(neigh_node->addr, neigh_addr); neigh_node->if_incoming = hard_iface; neigh_node->orig_node = orig_node; + neigh_node->last_seen = jiffies; /* extra reference for return */ kref_init(&neigh_node->refcount); -- cgit v1.2.3 From f2d23861b818d08bcd15cc1612ae94aa33b3931c Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 19 Mar 2016 13:55:21 +0100 Subject: batman-adv: Deactivate TO_BE_ACTIVATED hardif on shutdown The shutdown of an batman-adv interface can happen with one of its slave interfaces still being in the BATADV_IF_TO_BE_ACTIVATED state. A possible reason for it is that the routing algorithm BATMAN_V was selected and batadv_schedule_bat_ogm was not yet called for this interface. This slave interface still has to be set to BATADV_IF_INACTIVE or the batman-adv interface will never reduce its usage counter and thus never gets shutdown. This problem can be simulated via: $ modprobe dummy $ modprobe batman-adv routing_algo=BATMAN_V $ ip link add bat0 type batadv $ ip link set dummy0 master bat0 $ ip link set dummy0 up $ ip link del bat0 unregister_netdevice: waiting for bat0 to become free. Usage count = 3 Reported-by: Matthias Schiffer Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/hard-interface.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index b22b2775a0a5..c61d5b0b24d2 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -572,8 +572,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batadv_hard_iface *primary_if = NULL; - if (hard_iface->if_status == BATADV_IF_ACTIVE) - batadv_hardif_deactivate_interface(hard_iface); + batadv_hardif_deactivate_interface(hard_iface); if (hard_iface->if_status != BATADV_IF_INACTIVE) goto out; -- cgit v1.2.3 From d1a65f1741bfd9c69f9e4e2ad447a89b6810427d Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 20 Mar 2016 12:27:53 +0100 Subject: batman-adv: Reduce refcnt of removed router when updating route _batadv_update_route rcu_derefences orig_ifinfo->router outside of a spinlock protected region to print some information messages to the debug log. But this pointer is not checked again when the new pointer is assigned in the spinlock protected region. Thus is can happen that the value of orig_ifinfo->router changed in the meantime and thus the reference counter of the wrong router gets reduced after the spinlock protected region. Just rcu_dereferencing the value of orig_ifinfo->router inside the spinlock protected region (which also set the new pointer) is enough to get the correct old router object. Fixes: e1a5382f978b ("batman-adv: Make orig_node->router an rcu protected pointer") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/routing.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 4dd646a52f1a..b781bf753250 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -105,6 +105,15 @@ static void _batadv_update_route(struct batadv_priv *bat_priv, neigh_node = NULL; spin_lock_bh(&orig_node->neigh_list_lock); + /* curr_router used earlier may not be the current orig_ifinfo->router + * anymore because it was dereferenced outside of the neigh_list_lock + * protected region. After the new best neighbor has replace the current + * best neighbor the reference counter needs to decrease. Consequently, + * the code needs to ensure the curr_router variable contains a pointer + * to the replaced best neighbor. + */ + curr_router = rcu_dereference_protected(orig_ifinfo->router, true); + rcu_assign_pointer(orig_ifinfo->router, neigh_node); spin_unlock_bh(&orig_node->neigh_list_lock); batadv_orig_ifinfo_put(orig_ifinfo); -- cgit v1.2.3 From c4fdb6cff2aa0ae740c5f19b6f745cbbe786d42f Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Fri, 11 Mar 2016 14:04:49 +0100 Subject: batman-adv: Fix broadcast/ogm queue limit on a removed interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When removing a single interface while a broadcast or ogm packet is still pending then we will free the forward packet without releasing the queue slots again. This patch is supposed to fix this issue. Fixes: 6d5808d4ae1b ("batman-adv: Add missing hardif_free_ref in forw_packet_free") Signed-off-by: Linus Lüssing [sven@narfation.org: fix conflicts with current version] Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/send.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 3ce06e0a91b1..76417850d3fc 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -675,6 +675,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, if (pending) { hlist_del(&forw_packet->list); + if (!forw_packet->own) + atomic_inc(&bat_priv->bcast_queue_left); + batadv_forw_packet_free(forw_packet); } } @@ -702,6 +705,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, if (pending) { hlist_del(&forw_packet->list); + if (!forw_packet->own) + atomic_inc(&bat_priv->batman_queue_left); + batadv_forw_packet_free(forw_packet); } } -- cgit v1.2.3 From 1d377f4d690637a0121eac8701f84a0aa1e69a69 Mon Sep 17 00:00:00 2001 From: Mike Manning Date: Mon, 18 Apr 2016 12:13:23 +0000 Subject: USB: serial: cp210x: add ID for Link ECU The Link ECU is an aftermarket ECU computer for vehicles that provides full tuning abilities as well as datalogging and displaying capabilities via the USB to Serial adapter built into the device. Signed-off-by: Mike Manning Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index dd47823bb014..da608b4a0c30 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -141,6 +141,8 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */ { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */ { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */ + { USB_DEVICE(0x12B8, 0xEC60) }, /* Link G4 ECU */ + { USB_DEVICE(0x12B8, 0xEC62) }, /* Link G4+ ECU */ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ { USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */ -- cgit v1.2.3 From 613ac23a46e10d4d4339febdd534fafadd68e059 Mon Sep 17 00:00:00 2001 From: Jasem Mutlaq Date: Tue, 19 Apr 2016 10:38:27 +0300 Subject: USB: serial: cp210x: add Straizona Focusers device ids Adding VID:PID for Straizona Focusers to cp210x driver. Signed-off-by: Jasem Mutlaq Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index da608b4a0c30..7c9f25e9c422 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -109,6 +109,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */ { USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */ { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */ + { USB_DEVICE(0x10C4, 0x82F4) }, /* Starizona MicroTouch */ { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ @@ -118,6 +119,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */ { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ + { USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */ { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */ { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */ { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ -- cgit v1.2.3 From f75cfbaddeef943aed479b80415c3dcc63ff4247 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Thu, 21 Apr 2016 13:13:56 +0300 Subject: MAINTAINERS: net: add entry for TI Ethernet Switch drivers Add record for TI Ethernet Switch Driver CPSW/CPDMA/MDIO HW (am33/am43/am57/dr7/davinci) to ensure that related patches will go through dedicated linux-omap list. Also add Mugunthan as maintainer and myself as the reviewer. Cc: "David S. Miller" Cc: Tony Lindgren Cc: Mugunthan V N Cc: Richard Cochran Signed-off-by: Grygorii Strashko Acked-by: Mugunthan V N Acked-by: Tony Lindgren Signed-off-by: David S. Miller --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 1d5b4becab6f..849133608da7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11071,6 +11071,15 @@ S: Maintained F: drivers/clk/ti/ F: include/linux/clk/ti.h +TI ETHERNET SWITCH DRIVER (CPSW) +M: Mugunthan V N +R: Grygorii Strashko +L: linux-omap@vger.kernel.org +L: netdev@vger.kernel.org +S: Maintained +F: drivers/net/ethernet/ti/cpsw* +F: drivers/net/ethernet/ti/davinci* + TI FLASH MEDIA INTERFACE DRIVER M: Alex Dubov S: Maintained -- cgit v1.2.3 From 7ceb2afbd6aee4643056b47156baad6841db8e78 Mon Sep 17 00:00:00 2001 From: Elad Raz Date: Thu, 21 Apr 2016 12:52:43 +0200 Subject: switchdev: Adding complete operation to deferred switchdev ops When using switchdev deferred operation (SWITCHDEV_F_DEFER), the operation is executed in different context and the application doesn't have any way to get the operation real status. Adding a completion callback fixes that. This patch adds fields to switchdev_attr and switchdev_obj "complete_priv" field which is used by the "complete" callback. Application can set a complete function which will be called once the operation executed. Signed-off-by: Elad Raz Signed-off-by: Jiri Pirko Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- include/net/switchdev.h | 4 ++++ net/switchdev/switchdev.c | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/include/net/switchdev.h b/include/net/switchdev.h index d451122e8404..51d77b2ce2b2 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -54,6 +54,8 @@ struct switchdev_attr { struct net_device *orig_dev; enum switchdev_attr_id id; u32 flags; + void *complete_priv; + void (*complete)(struct net_device *dev, int err, void *priv); union { struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */ u8 stp_state; /* PORT_STP_STATE */ @@ -75,6 +77,8 @@ struct switchdev_obj { struct net_device *orig_dev; enum switchdev_obj_id id; u32 flags; + void *complete_priv; + void (*complete)(struct net_device *dev, int err, void *priv); }; /* SWITCHDEV_OBJ_ID_PORT_VLAN */ diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 2b9b98f1c2ff..b7e01d88bdc5 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -305,6 +305,8 @@ static void switchdev_port_attr_set_deferred(struct net_device *dev, if (err && err != -EOPNOTSUPP) netdev_err(dev, "failed (err=%d) to set attribute (id=%d)\n", err, attr->id); + if (attr->complete) + attr->complete(dev, err, attr->complete_priv); } static int switchdev_port_attr_set_defer(struct net_device *dev, @@ -434,6 +436,8 @@ static void switchdev_port_obj_add_deferred(struct net_device *dev, if (err && err != -EOPNOTSUPP) netdev_err(dev, "failed (err=%d) to add object (id=%d)\n", err, obj->id); + if (obj->complete) + obj->complete(dev, err, obj->complete_priv); } static int switchdev_port_obj_add_defer(struct net_device *dev, @@ -502,6 +506,8 @@ static void switchdev_port_obj_del_deferred(struct net_device *dev, if (err && err != -EOPNOTSUPP) netdev_err(dev, "failed (err=%d) to del object (id=%d)\n", err, obj->id); + if (obj->complete) + obj->complete(dev, err, obj->complete_priv); } static int switchdev_port_obj_del_defer(struct net_device *dev, -- cgit v1.2.3 From 6dd684c0feb207f30180570bad24264b922d9476 Mon Sep 17 00:00:00 2001 From: Elad Raz Date: Thu, 21 Apr 2016 12:52:44 +0200 Subject: bridge: mdb: Common function for mdb entry translation There is duplicate code that translates br_mdb_entry to br_ip let's wrap it in a common function. Signed-off-by: Elad Raz Signed-off-by: Jiri Pirko Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- net/bridge/br_mdb.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index 253bc77eda3b..b258120e1145 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c @@ -61,6 +61,19 @@ static void __mdb_entry_fill_flags(struct br_mdb_entry *e, unsigned char flags) e->flags |= MDB_FLAGS_OFFLOAD; } +static void __mdb_entry_to_br_ip(struct br_mdb_entry *entry, struct br_ip *ip) +{ + memset(ip, 0, sizeof(struct br_ip)); + ip->vid = entry->vid; + ip->proto = entry->addr.proto; + if (ip->proto == htons(ETH_P_IP)) + ip->u.ip4 = entry->addr.u.ip4; +#if IS_ENABLED(CONFIG_IPV6) + else + ip->u.ip6 = entry->addr.u.ip6; +#endif +} + static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, struct net_device *dev) { @@ -509,15 +522,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, if (!p || p->br != br || p->state == BR_STATE_DISABLED) return -EINVAL; - memset(&ip, 0, sizeof(ip)); - ip.vid = entry->vid; - ip.proto = entry->addr.proto; - if (ip.proto == htons(ETH_P_IP)) - ip.u.ip4 = entry->addr.u.ip4; -#if IS_ENABLED(CONFIG_IPV6) - else - ip.u.ip6 = entry->addr.u.ip6; -#endif + __mdb_entry_to_br_ip(entry, &ip); spin_lock_bh(&br->multicast_lock); ret = br_mdb_add_group(br, p, &ip, entry->state, pg); @@ -584,15 +589,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry) if (!netif_running(br->dev) || br->multicast_disabled) return -EINVAL; - memset(&ip, 0, sizeof(ip)); - ip.vid = entry->vid; - ip.proto = entry->addr.proto; - if (ip.proto == htons(ETH_P_IP)) - ip.u.ip4 = entry->addr.u.ip4; -#if IS_ENABLED(CONFIG_IPV6) - else - ip.u.ip6 = entry->addr.u.ip6; -#endif + __mdb_entry_to_br_ip(entry, &ip); spin_lock_bh(&br->multicast_lock); mdb = mlock_dereference(br->mdb, br); -- cgit v1.2.3 From 45ebcce56823d14d196dbdecd26783b3d5f464a6 Mon Sep 17 00:00:00 2001 From: Elad Raz Date: Thu, 21 Apr 2016 12:52:45 +0200 Subject: bridge: mdb: Marking port-group as offloaded There is a race-condition when updating the mdb offload flag without using the mulicast_lock. This reverts commit 9e8430f8d60d98 ("bridge: mdb: Passing the port-group pointer to br_mdb module"). This patch marks offloaded MDB entry as "offload" by changing the port- group flags and marks it as MDB_PG_FLAGS_OFFLOAD. When switchdev PORT_MDB succeeded and adds a multicast group, a completion callback is been invoked "br_mdb_complete". The completion function locks the multicast_lock and finds the right net_bridge_port_group and marks it as offloaded. Fixes: 9e8430f8d60d98 ("bridge: mdb: Passing the port-group pointer to br_mdb module") Reported-by: Nikolay Aleksandrov Signed-off-by: Elad Raz Signed-off-by: Jiri Pirko Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- net/bridge/br_mdb.c | 91 +++++++++++++++++++++++++++++++++-------------- net/bridge/br_multicast.c | 8 +++-- net/bridge/br_private.h | 4 +-- 3 files changed, 71 insertions(+), 32 deletions(-) diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index b258120e1145..7dbc80d01eb0 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c @@ -256,9 +256,45 @@ static inline size_t rtnl_mdb_nlmsg_size(void) + nla_total_size(sizeof(struct br_mdb_entry)); } -static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry, - int type, struct net_bridge_port_group *pg) +struct br_mdb_complete_info { + struct net_bridge_port *port; + struct br_ip ip; +}; + +static void br_mdb_complete(struct net_device *dev, int err, void *priv) { + struct br_mdb_complete_info *data = priv; + struct net_bridge_port_group __rcu **pp; + struct net_bridge_port_group *p; + struct net_bridge_mdb_htable *mdb; + struct net_bridge_mdb_entry *mp; + struct net_bridge_port *port = data->port; + struct net_bridge *br = port->br; + + if (err) + goto err; + + spin_lock_bh(&br->multicast_lock); + mdb = mlock_dereference(br->mdb, br); + mp = br_mdb_ip_get(mdb, &data->ip); + if (!mp) + goto out; + for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL; + pp = &p->next) { + if (p->port != port) + continue; + p->flags |= MDB_PG_FLAGS_OFFLOAD; + } +out: + spin_unlock_bh(&br->multicast_lock); +err: + kfree(priv); +} + +static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port *p, + struct br_mdb_entry *entry, int type) +{ + struct br_mdb_complete_info *complete_info; struct switchdev_obj_port_mdb mdb = { .obj = { .id = SWITCHDEV_OBJ_ID_PORT_MDB, @@ -281,9 +317,14 @@ static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry, mdb.obj.orig_dev = port_dev; if (port_dev && type == RTM_NEWMDB) { - err = switchdev_port_obj_add(port_dev, &mdb.obj); - if (!err && pg) - pg->flags |= MDB_PG_FLAGS_OFFLOAD; + complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC); + if (complete_info) { + complete_info->port = p; + __mdb_entry_to_br_ip(entry, &complete_info->ip); + mdb.obj.complete_priv = complete_info; + mdb.obj.complete = br_mdb_complete; + switchdev_port_obj_add(port_dev, &mdb.obj); + } } else if (port_dev && type == RTM_DELMDB) { switchdev_port_obj_del(port_dev, &mdb.obj); } @@ -304,21 +345,21 @@ errout: rtnl_set_sk_err(net, RTNLGRP_MDB, err); } -void br_mdb_notify(struct net_device *dev, struct net_bridge_port_group *pg, - int type) +void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, + struct br_ip *group, int type, u8 flags) { struct br_mdb_entry entry; memset(&entry, 0, sizeof(entry)); - entry.ifindex = pg->port->dev->ifindex; - entry.addr.proto = pg->addr.proto; - entry.addr.u.ip4 = pg->addr.u.ip4; + entry.ifindex = port->dev->ifindex; + entry.addr.proto = group->proto; + entry.addr.u.ip4 = group->u.ip4; #if IS_ENABLED(CONFIG_IPV6) - entry.addr.u.ip6 = pg->addr.u.ip6; + entry.addr.u.ip6 = group->u.ip6; #endif - entry.vid = pg->addr.vid; - __mdb_entry_fill_flags(&entry, pg->flags); - __br_mdb_notify(dev, &entry, type, pg); + entry.vid = group->vid; + __mdb_entry_fill_flags(&entry, flags); + __br_mdb_notify(dev, port, &entry, type); } static int nlmsg_populate_rtr_fill(struct sk_buff *skb, @@ -463,8 +504,7 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, } static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, - struct br_ip *group, unsigned char state, - struct net_bridge_port_group **pg) + struct br_ip *group, unsigned char state) { struct net_bridge_mdb_entry *mp; struct net_bridge_port_group *p; @@ -495,7 +535,6 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, if (unlikely(!p)) return -ENOMEM; rcu_assign_pointer(*pp, p); - *pg = p; if (state == MDB_TEMPORARY) mod_timer(&p->timer, now + br->multicast_membership_interval); @@ -503,8 +542,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, } static int __br_mdb_add(struct net *net, struct net_bridge *br, - struct br_mdb_entry *entry, - struct net_bridge_port_group **pg) + struct br_mdb_entry *entry) { struct br_ip ip; struct net_device *dev; @@ -525,7 +563,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, __mdb_entry_to_br_ip(entry, &ip); spin_lock_bh(&br->multicast_lock); - ret = br_mdb_add_group(br, p, &ip, entry->state, pg); + ret = br_mdb_add_group(br, p, &ip, entry->state); spin_unlock_bh(&br->multicast_lock); return ret; } @@ -533,7 +571,6 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); - struct net_bridge_port_group *pg; struct net_bridge_vlan_group *vg; struct net_device *dev, *pdev; struct br_mdb_entry *entry; @@ -563,15 +600,15 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) if (br_vlan_enabled(br) && vg && entry->vid == 0) { list_for_each_entry(v, &vg->vlan_list, vlist) { entry->vid = v->vid; - err = __br_mdb_add(net, br, entry, &pg); + err = __br_mdb_add(net, br, entry); if (err) break; - __br_mdb_notify(dev, entry, RTM_NEWMDB, pg); + __br_mdb_notify(dev, p, entry, RTM_NEWMDB); } } else { - err = __br_mdb_add(net, br, entry, &pg); + err = __br_mdb_add(net, br, entry); if (!err) - __br_mdb_notify(dev, entry, RTM_NEWMDB, pg); + __br_mdb_notify(dev, p, entry, RTM_NEWMDB); } return err; @@ -659,12 +696,12 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) entry->vid = v->vid; err = __br_mdb_del(br, entry); if (!err) - __br_mdb_notify(dev, entry, RTM_DELMDB, NULL); + __br_mdb_notify(dev, p, entry, RTM_DELMDB); } } else { err = __br_mdb_del(br, entry); if (!err) - __br_mdb_notify(dev, entry, RTM_DELMDB, NULL); + __br_mdb_notify(dev, p, entry, RTM_DELMDB); } return err; diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index a4c15df2b792..191ea66e4d92 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -283,7 +283,8 @@ static void br_multicast_del_pg(struct net_bridge *br, rcu_assign_pointer(*pp, p->next); hlist_del_init(&p->mglist); del_timer(&p->timer); - br_mdb_notify(br->dev, p, RTM_DELMDB); + br_mdb_notify(br->dev, p->port, &pg->addr, RTM_DELMDB, + p->flags); call_rcu_bh(&p->rcu, br_multicast_free_pg); if (!mp->ports && !mp->mglist && @@ -705,7 +706,7 @@ static int br_multicast_add_group(struct net_bridge *br, if (unlikely(!p)) goto err; rcu_assign_pointer(*pp, p); - br_mdb_notify(br->dev, p, RTM_NEWMDB); + br_mdb_notify(br->dev, port, group, RTM_NEWMDB, 0); found: mod_timer(&p->timer, now + br->multicast_membership_interval); @@ -1461,7 +1462,8 @@ br_multicast_leave_group(struct net_bridge *br, hlist_del_init(&p->mglist); del_timer(&p->timer); call_rcu_bh(&p->rcu, br_multicast_free_pg); - br_mdb_notify(br->dev, p, RTM_DELMDB); + br_mdb_notify(br->dev, port, group, RTM_DELMDB, + p->flags); if (!mp->ports && !mp->mglist && netif_running(br->dev)) diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 1b5d145dfcbf..d9da857182ef 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -560,8 +560,8 @@ br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group, unsigned char flags); void br_mdb_init(void); void br_mdb_uninit(void); -void br_mdb_notify(struct net_device *dev, struct net_bridge_port_group *pg, - int type); +void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, + struct br_ip *group, int type, u8 flags); void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, int type); -- cgit v1.2.3 From 72f2a05b8f367ee0d75584a6fbec7dbe7c144f27 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 22 Apr 2016 11:28:01 +0200 Subject: macsec: add missing NULL check after kmalloc Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Reported-by: Dan Carpenter Signed-off-by: Sabrina Dubroca Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/macsec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 84d3e5ca8817..f691030ee3df 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -1622,8 +1622,8 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info) } rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL); - if (init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), secy->key_len, - secy->icv_len)) { + if (!rx_sa || init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), + secy->key_len, secy->icv_len)) { rtnl_unlock(); return -ENOMEM; } -- cgit v1.2.3 From c10c63ea739bce3b8a6ab85c7bb472d900c9b070 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 22 Apr 2016 11:28:02 +0200 Subject: macsec: take rtnl lock before for_each_netdev Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Reported-by: Johannes Berg Signed-off-by: Sabrina Dubroca Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/macsec.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index f691030ee3df..5f3ea8026074 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -2268,8 +2268,6 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, if (!hdr) return -EMSGSIZE; - rtnl_lock(); - if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex)) goto nla_put_failure; @@ -2429,14 +2427,11 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, nla_nest_end(skb, rxsc_list); - rtnl_unlock(); - genlmsg_end(skb, hdr); return 0; nla_put_failure: - rtnl_unlock(); genlmsg_cancel(skb, hdr); return -EMSGSIZE; } @@ -2450,6 +2445,7 @@ static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) dev_idx = cb->args[0]; d = 0; + rtnl_lock(); for_each_netdev(net, dev) { struct macsec_secy *secy; @@ -2467,6 +2463,7 @@ next: } done: + rtnl_unlock(); cb->args[0] = d; return skb->len; } -- cgit v1.2.3 From 497f358aa4c0d99b75ec204407389920d5e33ec5 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 22 Apr 2016 11:28:03 +0200 Subject: macsec: don't put a NULL rxsa The "deliver:" path of macsec_handle_frame can be called with rx_sa == NULL. Check rx_sa != NULL before calling macsec_rxsa_put(). Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Signed-off-by: Sabrina Dubroca Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/macsec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 5f3ea8026074..2a2136b7d324 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -1161,7 +1161,8 @@ deliver: macsec_extra_len(macsec_skb_cb(skb)->has_sci)); macsec_reset_skb(skb, secy->netdev); - macsec_rxsa_put(rx_sa); + if (rx_sa) + macsec_rxsa_put(rx_sa); count_rx(dev, skb->len); rcu_read_unlock(); -- cgit v1.2.3 From c3b7d0bd7ac2c501d4806db71ddd383c184968e8 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 22 Apr 2016 11:28:04 +0200 Subject: macsec: fix rx_sa refcounting with decrypt callback The decrypt callback macsec_decrypt_done needs a reference on the rx_sa and releases it before returning, but macsec_handle_frame already put that reference after macsec_decrypt returned NULL. Set rx_sa to NULL when the decrypt callback runs so that macsec_handle_frame knows it must not release the reference. Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Signed-off-by: Sabrina Dubroca Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/macsec.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 2a2136b7d324..1fd2b147fda1 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -880,12 +880,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, macsec_skb_cb(skb)->valid = false; skb = skb_share_check(skb, GFP_ATOMIC); if (!skb) - return NULL; + return ERR_PTR(-ENOMEM); req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC); if (!req) { kfree_skb(skb); - return NULL; + return ERR_PTR(-ENOMEM); } hdr = (struct macsec_eth_header *)skb->data; @@ -905,7 +905,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, skb = skb_unshare(skb, GFP_ATOMIC); if (!skb) { aead_request_free(req); - return NULL; + return ERR_PTR(-ENOMEM); } } else { /* integrity only: all headers + data authenticated */ @@ -921,14 +921,14 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, dev_hold(dev); ret = crypto_aead_decrypt(req); if (ret == -EINPROGRESS) { - return NULL; + return ERR_PTR(ret); } else if (ret != 0) { /* decryption/authentication failed * 10.6 if validateFrames is disabled, deliver anyway */ if (ret != -EBADMSG) { kfree_skb(skb); - skb = NULL; + skb = ERR_PTR(ret); } } else { macsec_skb_cb(skb)->valid = true; @@ -1146,8 +1146,10 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) secy->validate_frames != MACSEC_VALIDATE_DISABLED) skb = macsec_decrypt(skb, dev, rx_sa, sci, secy); - if (!skb) { - macsec_rxsa_put(rx_sa); + if (IS_ERR(skb)) { + /* the decrypt callback needs the reference */ + if (PTR_ERR(skb) != -EINPROGRESS) + macsec_rxsa_put(rx_sa); rcu_read_unlock(); *pskb = NULL; return RX_HANDLER_CONSUMED; -- cgit v1.2.3 From 96cfc5052c5d434563873caa7707b32b9e389b16 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 22 Apr 2016 11:28:05 +0200 Subject: macsec: add consistency check to netlink dumps Use genl_dump_check_consistent in dump_secy. Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Suggested-by: Johannes Berg Signed-off-by: Sabrina Dubroca Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/macsec.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 1fd2b147fda1..41fbe556ba6d 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -2271,6 +2271,8 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, if (!hdr) return -EMSGSIZE; + genl_dump_check_consistent(cb, hdr, &macsec_fam); + if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex)) goto nla_put_failure; @@ -2439,6 +2441,8 @@ nla_put_failure: return -EMSGSIZE; } +static int macsec_generation = 1; /* protected by RTNL */ + static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); @@ -2449,6 +2453,9 @@ static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) d = 0; rtnl_lock(); + + cb->seq = macsec_generation; + for_each_netdev(net, dev) { struct macsec_secy *secy; @@ -2920,6 +2927,8 @@ static void macsec_dellink(struct net_device *dev, struct list_head *head) struct net_device *real_dev = macsec->real_dev; struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev); + macsec_generation++; + unregister_netdevice_queue(dev, head); list_del_rcu(&macsec->secys); if (list_empty(&rxd->secys)) @@ -3066,6 +3075,8 @@ static int macsec_newlink(struct net *net, struct net_device *dev, if (err < 0) goto del_dev; + macsec_generation++; + dev_hold(real_dev); return 0; -- cgit v1.2.3 From 960d5848dbf1245cc3a310109897937207411c0c Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 22 Apr 2016 11:28:06 +0200 Subject: macsec: fix memory leaks around rx_handler (un)registration We leak a struct macsec_rxh_data when we unregister the rx_handler in macsec_dellink. We also leak a struct macsec_rxh_data in register_macsec_dev if we fail to register the rx_handler. Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Signed-off-by: Sabrina Dubroca Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/macsec.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 41fbe556ba6d..826c6c9ce7fd 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -2931,8 +2931,10 @@ static void macsec_dellink(struct net_device *dev, struct list_head *head) unregister_netdevice_queue(dev, head); list_del_rcu(&macsec->secys); - if (list_empty(&rxd->secys)) + if (list_empty(&rxd->secys)) { netdev_rx_handler_unregister(real_dev); + kfree(rxd); + } macsec_del_dev(macsec); } @@ -2954,8 +2956,10 @@ static int register_macsec_dev(struct net_device *real_dev, err = netdev_rx_handler_register(real_dev, macsec_handle_frame, rxd); - if (err < 0) + if (err < 0) { + kfree(rxd); return err; + } } list_add_tail_rcu(&macsec->secys, &rxd->secys); -- cgit v1.2.3 From 38787fc209580f9b5918e93e71da7c960dbb5d8d Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 22 Apr 2016 11:28:07 +0200 Subject: macsec: fix SA leak if initialization fails Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Reported-by: Lance Richardson Signed-off-by: Sabrina Dubroca Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/macsec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 826c6c9ce7fd..b37d348b8ea0 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -1627,6 +1627,7 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info) rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL); if (!rx_sa || init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), secy->key_len, secy->icv_len)) { + kfree(rx_sa); rtnl_unlock(); return -ENOMEM; } @@ -1771,6 +1772,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info) tx_sa = kmalloc(sizeof(*tx_sa), GFP_KERNEL); if (!tx_sa || init_tx_sa(tx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), secy->key_len, secy->icv_len)) { + kfree(tx_sa); rtnl_unlock(); return -ENOMEM; } -- cgit v1.2.3 From 748164802c1bd2c52937d20782b07d8c68dd9a4f Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 22 Apr 2016 11:28:08 +0200 Subject: macsec: add missing macsec prefix in uapi I accidentally forgot some MACSEC_ prefixes in if_macsec.h. Fixes: dece8d2b78d1 ("uapi: add MACsec bits") Signed-off-by: Sabrina Dubroca Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/macsec.c | 12 +++++++----- include/uapi/linux/if_macsec.h | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index b37d348b8ea0..9f63cc7b0a73 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -2232,7 +2232,8 @@ static int nla_put_secy(struct macsec_secy *secy, struct sk_buff *skb) return 1; if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci) || - nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, DEFAULT_CIPHER_ID) || + nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, + MACSEC_DEFAULT_CIPHER_ID) || nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) || nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) || nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) || @@ -3096,7 +3097,7 @@ unregister: static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) { - u64 csid = DEFAULT_CIPHER_ID; + u64 csid = MACSEC_DEFAULT_CIPHER_ID; u8 icv_len = DEFAULT_ICV_LEN; int flag; bool es, scb, sci; @@ -3111,8 +3112,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]); switch (csid) { - case DEFAULT_CIPHER_ID: - case DEFAULT_CIPHER_ALT: + case MACSEC_DEFAULT_CIPHER_ID: + case MACSEC_DEFAULT_CIPHER_ALT: if (icv_len < MACSEC_MIN_ICV_LEN || icv_len > MACSEC_MAX_ICV_LEN) return -EINVAL; @@ -3185,7 +3186,8 @@ static int macsec_fill_info(struct sk_buff *skb, if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci) || nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) || - nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, DEFAULT_CIPHER_ID) || + nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, + MACSEC_DEFAULT_CIPHER_ID) || nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) || nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) || nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) || diff --git a/include/uapi/linux/if_macsec.h b/include/uapi/linux/if_macsec.h index 26b0d1e3e3e7..4c58d9917aa4 100644 --- a/include/uapi/linux/if_macsec.h +++ b/include/uapi/linux/if_macsec.h @@ -19,8 +19,8 @@ #define MACSEC_MAX_KEY_LEN 128 -#define DEFAULT_CIPHER_ID 0x0080020001000001ULL -#define DEFAULT_CIPHER_ALT 0x0080C20001000001ULL +#define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL +#define MACSEC_DEFAULT_CIPHER_ALT 0x0080C20001000001ULL #define MACSEC_MIN_ICV_LEN 8 #define MACSEC_MAX_ICV_LEN 32 -- cgit v1.2.3 From 4b1fb9352f351faa067a914907d58a6fe38ac048 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 22 Apr 2016 11:28:09 +0200 Subject: macsec: fix netlink attribute validation macsec_validate_attr should check IFLA_MACSEC_REPLAY_PROTECT (not IFLA_MACSEC_PROTECT) to verify that the replay protection and replay window arguments are correct. Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Signed-off-by: Sabrina Dubroca Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/macsec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 9f63cc7b0a73..c6385617bfb2 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -3147,8 +3147,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) nla_get_u8(data[IFLA_MACSEC_VALIDATION]) > MACSEC_VALIDATE_MAX) return -EINVAL; - if ((data[IFLA_MACSEC_PROTECT] && - nla_get_u8(data[IFLA_MACSEC_PROTECT])) && + if ((data[IFLA_MACSEC_REPLAY_PROTECT] && + nla_get_u8(data[IFLA_MACSEC_REPLAY_PROTECT])) && !data[IFLA_MACSEC_WINDOW]) return -EINVAL; -- cgit v1.2.3 From 3c201b5a84edd6ee2f9a8548efaa813980839b46 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 21 Apr 2016 14:11:50 +0200 Subject: net: stmmac: socfpga: Remove re-registration of reset controller Both socfpga_dwmac_parse_data() in dwmac-socfpga.c and stmmac_dvr_probe() in stmmac_main.c functions call devm_reset_control_get() to register an reset controller for the stmmac. This results in an attempt to register two reset controllers for the same non-shared reset line. The first attempt to register the reset controller works fine. The second attempt fails with warning from the reset controller core, see below. The warning is produced because the reset line is non-shared and thus it is allowed to have only up-to one reset controller associated with that reset line, not two or more. The solution has multiple parts. First, the original socfpga_dwmac_init() is tweaked to use reset controller pointer from the stmmac_priv (private data of the stmmac core) instead of the local instance, which was used before. The local re-registration of the reset controller is removed. Next, the socfpga_dwmac_init() is moved after stmmac_dvr_probe() in the probe function. This order is legal according to Altera and it makes the code much easier, since there is no need to temporarily register and unregister the reset controller ; the reset controller is already registered by the stmmac_dvr_probe(). Finally, plat_dat->exit and socfpga_dwmac_exit() is no longer necessary, since the functionality is already performed by the stmmac core. ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1 at drivers/reset/core.c:187 __of_reset_control_get+0x218/0x270 Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.6.0-rc4-next-20160419-00015-gabb2477-dirty #4 Hardware name: Altera SOCFPGA [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x94/0xa8) [] (dump_stack) from [] (__warn+0xec/0x104) [] (__warn) from [] (warn_slowpath_null+0x20/0x28) [] (warn_slowpath_null) from [] (__of_reset_control_get+0x218/0x270) [] (__of_reset_control_get) from [] (__devm_reset_control_get+0x54/0x90) [] (__devm_reset_control_get) from [] (stmmac_dvr_probe+0x1b4/0x8e8) [] (stmmac_dvr_probe) from [] (socfpga_dwmac_probe+0x1b8/0x28c) [] (socfpga_dwmac_probe) from [] (platform_drv_probe+0x4c/0xb0) [] (platform_drv_probe) from [] (driver_probe_device+0x224/0x2bc) [] (driver_probe_device) from [] (__driver_attach+0xac/0xb0) [] (__driver_attach) from [] (bus_for_each_dev+0x6c/0xa0) [] (bus_for_each_dev) from [] (bus_add_driver+0x1a4/0x21c) [] (bus_add_driver) from [] (driver_register+0x78/0xf8) [] (driver_register) from [] (do_one_initcall+0x40/0x170) [] (do_one_initcall) from [] (kernel_init_freeable+0x1dc/0x27c) [] (kernel_init_freeable) from [] (kernel_init+0x8/0x114) [] (kernel_init) from [] (ret_from_fork+0x14/0x3c) ---[ end trace 059d2fbe87608fa9 ]--- Signed-off-by: Marek Vasut Cc: Matthew Gerlach Cc: Dinh Nguyen Cc: David S. Miller Tested-by: Dinh Nguyen Signed-off-by: David S. Miller --- .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 50 +++++++--------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index 44022b1845ce..afb90d129cb6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -49,7 +49,6 @@ struct socfpga_dwmac { u32 reg_shift; struct device *dev; struct regmap *sys_mgr_base_addr; - struct reset_control *stmmac_rst; void __iomem *splitter_base; bool f2h_ptp_ref_clk; }; @@ -92,15 +91,6 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device * struct device_node *np_splitter; struct resource res_splitter; - dwmac->stmmac_rst = devm_reset_control_get(dev, - STMMAC_RESOURCE_NAME); - if (IS_ERR(dwmac->stmmac_rst)) { - dev_info(dev, "Could not get reset control!\n"); - if (PTR_ERR(dwmac->stmmac_rst) == -EPROBE_DEFER) - return -EPROBE_DEFER; - dwmac->stmmac_rst = NULL; - } - dwmac->interface = of_get_phy_mode(np); sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); @@ -194,30 +184,23 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac) return 0; } -static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv) -{ - struct socfpga_dwmac *dwmac = priv; - - /* On socfpga platform exit, assert and hold reset to the - * enet controller - the default state after a hard reset. - */ - if (dwmac->stmmac_rst) - reset_control_assert(dwmac->stmmac_rst); -} - static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) { - struct socfpga_dwmac *dwmac = priv; + struct socfpga_dwmac *dwmac = priv; struct net_device *ndev = platform_get_drvdata(pdev); struct stmmac_priv *stpriv = NULL; int ret = 0; - if (ndev) - stpriv = netdev_priv(ndev); + if (!ndev) + return -EINVAL; + + stpriv = netdev_priv(ndev); + if (!stpriv) + return -EINVAL; /* Assert reset to the enet controller before changing the phy mode */ - if (dwmac->stmmac_rst) - reset_control_assert(dwmac->stmmac_rst); + if (stpriv->stmmac_rst) + reset_control_assert(stpriv->stmmac_rst); /* Setup the phy mode in the system manager registers according to * devicetree configuration @@ -227,8 +210,8 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) /* Deassert reset for the phy configuration to be sampled by * the enet controller, and operation to start in requested mode */ - if (dwmac->stmmac_rst) - reset_control_deassert(dwmac->stmmac_rst); + if (stpriv->stmmac_rst) + reset_control_deassert(stpriv->stmmac_rst); /* Before the enet controller is suspended, the phy is suspended. * This causes the phy clock to be gated. The enet controller is @@ -245,7 +228,7 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) * control register 0, and can be modified by the phy driver * framework. */ - if (stpriv && stpriv->phydev) + if (stpriv->phydev) phy_resume(stpriv->phydev); return ret; @@ -285,14 +268,13 @@ static int socfpga_dwmac_probe(struct platform_device *pdev) plat_dat->bsp_priv = dwmac; plat_dat->init = socfpga_dwmac_init; - plat_dat->exit = socfpga_dwmac_exit; plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; - ret = socfpga_dwmac_init(pdev, plat_dat->bsp_priv); - if (ret) - return ret; + ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); + if (!ret) + ret = socfpga_dwmac_init(pdev, dwmac); - return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); + return ret; } static const struct of_device_id socfpga_dwmac_match[] = { -- cgit v1.2.3 From 45c78e0219405af1b0f31b06952dfd9bcf7ad1f6 Mon Sep 17 00:00:00 2001 From: Manish Chopra Date: Thu, 21 Apr 2016 13:25:20 -0400 Subject: qlcnic: Update version to 5.3.64 Just updating the version as many fixes got accumulated over 5.3.63 Signed-off-by: Manish Chopra Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 55007f1e6bbc..caf6ddb7ea76 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -37,8 +37,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 3 -#define _QLCNIC_LINUX_SUBVERSION 63 -#define QLCNIC_LINUX_VERSIONID "5.3.63" +#define _QLCNIC_LINUX_SUBVERSION 64 +#define QLCNIC_LINUX_VERSIONID "5.3.64" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- cgit v1.2.3 From c3f9bf628bc7edda298897d952f5e761137229c9 Mon Sep 17 00:00:00 2001 From: Maor Gottlieb Date: Fri, 22 Apr 2016 00:33:00 +0300 Subject: net/mlx5_core: Fix soft lockup in steering error flow In the error flow of adding flow rule to auto-grouped flow table, we call to tree_remove_node. tree_remove_node locks the node's parent, however the node's parent is already locked by mlx5_add_flow_rule and this causes a deadlock. After this patch, if we failed to add the flow rule, we unlock the flow table before calling to tree_remove_node. fixes: f0d22d187473 ('net/mlx5_core: Introduce flow steering autogrouped flow table') Signed-off-by: Maor Gottlieb Reported-by: Amir Vadai Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 46 +++++++++-------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 5121be4675d1..3c7e3e581835 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -1065,33 +1065,6 @@ unlock_fg: return rule; } -static struct mlx5_flow_rule *add_rule_to_auto_fg(struct mlx5_flow_table *ft, - u8 match_criteria_enable, - u32 *match_criteria, - u32 *match_value, - u8 action, - u32 flow_tag, - struct mlx5_flow_destination *dest) -{ - struct mlx5_flow_rule *rule; - struct mlx5_flow_group *g; - - g = create_autogroup(ft, match_criteria_enable, match_criteria); - if (IS_ERR(g)) - return (void *)g; - - rule = add_rule_fg(g, match_value, - action, flow_tag, dest); - if (IS_ERR(rule)) { - /* Remove assumes refcount > 0 and autogroup creates a group - * with a refcount = 0. - */ - tree_get_node(&g->node); - tree_remove_node(&g->node); - } - return rule; -} - static struct mlx5_flow_rule * _mlx5_add_flow_rule(struct mlx5_flow_table *ft, u8 match_criteria_enable, @@ -1119,8 +1092,23 @@ _mlx5_add_flow_rule(struct mlx5_flow_table *ft, goto unlock; } - rule = add_rule_to_auto_fg(ft, match_criteria_enable, match_criteria, - match_value, action, flow_tag, dest); + g = create_autogroup(ft, match_criteria_enable, match_criteria); + if (IS_ERR(g)) { + rule = (void *)g; + goto unlock; + } + + rule = add_rule_fg(g, match_value, + action, flow_tag, dest); + if (IS_ERR(rule)) { + /* Remove assumes refcount > 0 and autogroup creates a group + * with a refcount = 0. + */ + unlock_ref_node(&ft->node); + tree_get_node(&g->node); + tree_remove_node(&g->node); + return rule; + } unlock: unlock_ref_node(&ft->node); return rule; -- cgit v1.2.3 From 6e4c21894673baabdbef03c3ac2458a28246128b Mon Sep 17 00:00:00 2001 From: Rana Shahout Date: Fri, 22 Apr 2016 00:33:01 +0300 Subject: net/mlx5e: Fix MLX5E_100BASE_T define Bit 25 of eth_proto_capability in PTYS register is 1000Base-TT and not 100Base-T. Fixes: f62b8bb8f2d3 ('net/mlx5: Extend mlx5_core to support ConnectX-4 Ethernet functionality') Signed-off-by: Rana Shahout Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +- drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index 879e6276c473..e80ce94b5dcf 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -609,7 +609,7 @@ enum mlx5e_link_mode { MLX5E_100GBASE_KR4 = 22, MLX5E_100GBASE_LR4 = 23, MLX5E_100BASE_TX = 24, - MLX5E_100BASE_T = 25, + MLX5E_1000BASE_T = 25, MLX5E_10GBASE_T = 26, MLX5E_25GBASE_CR = 27, MLX5E_25GBASE_KR = 28, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 68834b715f6c..3476ab844634 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -138,10 +138,10 @@ static const struct { [MLX5E_100BASE_TX] = { .speed = 100, }, - [MLX5E_100BASE_T] = { - .supported = SUPPORTED_100baseT_Full, - .advertised = ADVERTISED_100baseT_Full, - .speed = 100, + [MLX5E_1000BASE_T] = { + .supported = SUPPORTED_1000baseT_Full, + .advertised = ADVERTISED_1000baseT_Full, + .speed = 1000, }, [MLX5E_10GBASE_T] = { .supported = SUPPORTED_10000baseT_Full, -- cgit v1.2.3 From 64dbbdfef245f67504ec403a5aebfcc7b92bd8c1 Mon Sep 17 00:00:00 2001 From: Majd Dibbiny Date: Fri, 22 Apr 2016 00:33:02 +0300 Subject: net/mlx5_core: Add ConnectX-5 to list of supported devices Add the upcoming ConnectX-5 devices (PF and VF) to the list of supported devices by the mlx5 driver. Signed-off-by: Majd Dibbiny Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 3f3b2fae4991..ddd352ae3dbd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1459,6 +1459,8 @@ static const struct pci_device_id mlx5_core_pci_table[] = { { PCI_VDEVICE(MELLANOX, 0x1014), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4 VF */ { PCI_VDEVICE(MELLANOX, 0x1015) }, /* ConnectX-4LX */ { PCI_VDEVICE(MELLANOX, 0x1016), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4LX VF */ + { PCI_VDEVICE(MELLANOX, 0x1017) }, /* ConnectX-5 */ + { PCI_VDEVICE(MELLANOX, 0x1018), MLX5_PCI_DEV_IS_VF}, /* ConnectX-5 VF */ { 0, } }; -- cgit v1.2.3 From 046339eaab26804f52f6604877f5674f70815b26 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Fri, 22 Apr 2016 00:33:03 +0300 Subject: net/mlx5e: Device's mtu field is u16 and not int For set/query MTU port firmware commands the MTU field is 16 bits, here I changed all the "int mtu" parameters of the functions wrapping those firmware commands to be u16. Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/infiniband/hw/mlx5/main.c | 4 ++-- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 4 ++-- drivers/net/ethernet/mellanox/mlx5/core/port.c | 10 +++++----- include/linux/mlx5/port.h | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 5acf346e048e..99eb1c1a3b7b 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -671,8 +671,8 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u8 port, struct mlx5_ib_dev *dev = to_mdev(ibdev); struct mlx5_core_dev *mdev = dev->mdev; struct mlx5_hca_vport_context *rep; - int max_mtu; - int oper_mtu; + u16 max_mtu; + u16 oper_mtu; int err; u8 ib_link_width_oper; u8 vl_hw_cap; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index e0adb604f461..2fbbc625f106 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -1408,7 +1408,7 @@ static int mlx5e_set_dev_port_mtu(struct net_device *netdev) { struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5_core_dev *mdev = priv->mdev; - int hw_mtu; + u16 hw_mtu; int err; err = mlx5_set_port_mtu(mdev, MLX5E_SW2HW_MTU(netdev->mtu), 1); @@ -2004,7 +2004,7 @@ static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu) struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5_core_dev *mdev = priv->mdev; bool was_opened; - int max_mtu; + u16 max_mtu; int err = 0; mlx5_query_port_max_mtu(mdev, &max_mtu, 1); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index ae378c575deb..53cc1e2c693b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c @@ -247,8 +247,8 @@ int mlx5_query_port_admin_status(struct mlx5_core_dev *dev, } EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status); -static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu, - int *max_mtu, int *oper_mtu, u8 port) +static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, u16 *admin_mtu, + u16 *max_mtu, u16 *oper_mtu, u8 port) { u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; @@ -268,7 +268,7 @@ static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu, *admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu); } -int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port) +int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port) { u32 in[MLX5_ST_SZ_DW(pmtu_reg)]; u32 out[MLX5_ST_SZ_DW(pmtu_reg)]; @@ -283,14 +283,14 @@ int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port) } EXPORT_SYMBOL_GPL(mlx5_set_port_mtu); -void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu, +void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu, u8 port) { mlx5_query_port_mtu(dev, NULL, max_mtu, NULL, port); } EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu); -void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu, +void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu, u8 port) { mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu, port); diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h index a1d145abd4eb..b30250ab7604 100644 --- a/include/linux/mlx5/port.h +++ b/include/linux/mlx5/port.h @@ -54,9 +54,9 @@ int mlx5_set_port_admin_status(struct mlx5_core_dev *dev, int mlx5_query_port_admin_status(struct mlx5_core_dev *dev, enum mlx5_port_status *status); -int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port); -void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu, u8 port); -void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu, +int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port); +void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu, u8 port); +void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu, u8 port); int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev, -- cgit v1.2.3 From d8edd2469ace550db707798180d1c84d81f93bca Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Fri, 22 Apr 2016 00:33:04 +0300 Subject: net/mlx5e: Fix minimum MTU Minimum MTU that can be set in Connectx4 device is 68. This fixes the case where a user wants to set invalid MTU, the driver will fail to satisfy this request and the interface will stay down. It is better to report an error and continue working with old mtu. Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 2fbbc625f106..93e4ef43fa9f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -1999,22 +1999,27 @@ static int mlx5e_set_features(struct net_device *netdev, return err; } +#define MXL5_HW_MIN_MTU 64 +#define MXL5E_MIN_MTU (MXL5_HW_MIN_MTU + ETH_FCS_LEN) + static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu) { struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5_core_dev *mdev = priv->mdev; bool was_opened; u16 max_mtu; + u16 min_mtu; int err = 0; mlx5_query_port_max_mtu(mdev, &max_mtu, 1); max_mtu = MLX5E_HW2SW_MTU(max_mtu); + min_mtu = MLX5E_HW2SW_MTU(MXL5E_MIN_MTU); - if (new_mtu > max_mtu) { + if (new_mtu > max_mtu || new_mtu < min_mtu) { netdev_err(netdev, - "%s: Bad MTU (%d) > (%d) Max\n", - __func__, new_mtu, max_mtu); + "%s: Bad MTU (%d), valid range is: [%d..%d]\n", + __func__, new_mtu, min_mtu, max_mtu); return -EINVAL; } -- cgit v1.2.3 From cd255efff9baadd654d6160e52d17ae7c568c9d3 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Fri, 22 Apr 2016 00:33:05 +0300 Subject: net/mlx5e: Use vport MTU rather than physical port MTU Set and report vport MTU rather than physical MTU, Driver will set both vport and physical port mtu and will rely on the query of vport mtu. SRIOV VFs have to report their MTU to their vport manager (PF), and this will allow them to work with any MTU they need without failing the request. Also for some cases where the PF is not a port owner, PF can work with MTU less than the physical port mtu if set physical port mtu didn't take effect. Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 44 ++++++++++++++++++----- drivers/net/ethernet/mellanox/mlx5/core/vport.c | 40 +++++++++++++++++++++ include/linux/mlx5/vport.h | 2 ++ 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 93e4ef43fa9f..85773f8573e5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -1404,24 +1404,50 @@ static int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5e_priv *priv) return 0; } -static int mlx5e_set_dev_port_mtu(struct net_device *netdev) +static int mlx5e_set_mtu(struct mlx5e_priv *priv, u16 mtu) { - struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5_core_dev *mdev = priv->mdev; - u16 hw_mtu; + u16 hw_mtu = MLX5E_SW2HW_MTU(mtu); int err; - err = mlx5_set_port_mtu(mdev, MLX5E_SW2HW_MTU(netdev->mtu), 1); + err = mlx5_set_port_mtu(mdev, hw_mtu, 1); if (err) return err; - mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1); + /* Update vport context MTU */ + mlx5_modify_nic_vport_mtu(mdev, hw_mtu); + return 0; +} + +static void mlx5e_query_mtu(struct mlx5e_priv *priv, u16 *mtu) +{ + struct mlx5_core_dev *mdev = priv->mdev; + u16 hw_mtu = 0; + int err; + + err = mlx5_query_nic_vport_mtu(mdev, &hw_mtu); + if (err || !hw_mtu) /* fallback to port oper mtu */ + mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1); + + *mtu = MLX5E_HW2SW_MTU(hw_mtu); +} + +static int mlx5e_set_dev_port_mtu(struct net_device *netdev) +{ + struct mlx5e_priv *priv = netdev_priv(netdev); + u16 mtu; + int err; + + err = mlx5e_set_mtu(priv, netdev->mtu); + if (err) + return err; - if (MLX5E_HW2SW_MTU(hw_mtu) != netdev->mtu) - netdev_warn(netdev, "%s: Port MTU %d is different than netdev mtu %d\n", - __func__, MLX5E_HW2SW_MTU(hw_mtu), netdev->mtu); + mlx5e_query_mtu(priv, &mtu); + if (mtu != netdev->mtu) + netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n", + __func__, mtu, netdev->mtu); - netdev->mtu = MLX5E_HW2SW_MTU(hw_mtu); + netdev->mtu = mtu; return 0; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c index bd518405859e..b69dadcfb897 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c @@ -196,6 +196,46 @@ int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev, } EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_address); +int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu) +{ + int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out); + u32 *out; + int err; + + out = mlx5_vzalloc(outlen); + if (!out) + return -ENOMEM; + + err = mlx5_query_nic_vport_context(mdev, 0, out, outlen); + if (!err) + *mtu = MLX5_GET(query_nic_vport_context_out, out, + nic_vport_context.mtu); + + kvfree(out); + return err; +} +EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mtu); + +int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu) +{ + int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in); + void *in; + int err; + + in = mlx5_vzalloc(inlen); + if (!in) + return -ENOMEM; + + MLX5_SET(modify_nic_vport_context_in, in, field_select.mtu, 1); + MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.mtu, mtu); + + err = mlx5_modify_nic_vport_context(mdev, in, inlen); + + kvfree(in); + return err; +} +EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu); + int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev, u32 vport, enum mlx5_list_type list_type, diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h index bd93e6323603..301da4a5e6bf 100644 --- a/include/linux/mlx5/vport.h +++ b/include/linux/mlx5/vport.h @@ -45,6 +45,8 @@ int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, u16 vport, u8 *addr); int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *dev, u16 vport, u8 *addr); +int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu); +int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu); int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev, u64 *system_image_guid); int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid); -- cgit v1.2.3 From 78228cbdeb0aa5c96e2a721e7e0d6953b416b5a3 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Fri, 22 Apr 2016 00:33:06 +0300 Subject: net/mlx5_core: Remove static from local variable The static is not required and breaks re-entrancy if it will be required. Fixes: 2530236303d9 ("net/mlx5_core: Flow steering tree initialization") Signed-off-by: Eli Cohen Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 3c7e3e581835..89cce97d46c6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -1276,7 +1276,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev, { struct mlx5_flow_root_namespace *root_ns = dev->priv.root_ns; int prio; - static struct fs_prio *fs_prio; + struct fs_prio *fs_prio; struct mlx5_flow_namespace *ns; if (!root_ns) -- cgit v1.2.3 From 5fc7197d3a256d9c5de3134870304b24892a4908 Mon Sep 17 00:00:00 2001 From: Majd Dibbiny Date: Fri, 22 Apr 2016 00:33:07 +0300 Subject: net/mlx5: Add pci shutdown callback This patch introduces kexec support for mlx5. When switching kernels, kexec() calls shutdown, which unloads the driver and cleans its resources. In addition, remove unregister netdev from shutdown flow. This will allow a clean shutdown, even if some netdev clients did not release their reference from this netdev. Releasing The HW resources only is enough as the kernel is shutting down Signed-off-by: Majd Dibbiny Signed-off-by: Tariq Toukan Signed-off-by: Haggai Abramovsky Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 15 +++++++++++++-- drivers/net/ethernet/mellanox/mlx5/core/main.c | 23 +++++++++++++++++++---- include/linux/mlx5/driver.h | 7 ++++--- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 85773f8573e5..67d548b70e14 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -2633,7 +2633,16 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) schedule_work(&priv->set_rx_mode_work); mlx5e_disable_async_events(priv); flush_scheduled_work(); - unregister_netdev(netdev); + if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) { + netif_device_detach(netdev); + mutex_lock(&priv->state_lock); + if (test_bit(MLX5E_STATE_OPENED, &priv->state)) + mlx5e_close_locked(netdev); + mutex_unlock(&priv->state_lock); + } else { + unregister_netdev(netdev); + } + mlx5e_tc_cleanup(priv); mlx5e_vxlan_cleanup(priv); mlx5e_destroy_flow_tables(priv); @@ -2646,7 +2655,9 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn); mlx5_core_dealloc_pd(priv->mdev, priv->pdn); mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar); - free_netdev(netdev); + + if (!test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) + free_netdev(netdev); } static void *mlx5e_get_netdev(void *vpriv) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index ddd352ae3dbd..6892746fd10d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -966,7 +966,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) int err; mutex_lock(&dev->intf_state_mutex); - if (dev->interface_state == MLX5_INTERFACE_STATE_UP) { + if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { dev_warn(&dev->pdev->dev, "%s: interface is up, NOP\n", __func__); goto out; @@ -1133,7 +1133,8 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) if (err) pr_info("failed request module on %s\n", MLX5_IB_MOD); - dev->interface_state = MLX5_INTERFACE_STATE_UP; + clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state); + set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); out: mutex_unlock(&dev->intf_state_mutex); @@ -1207,7 +1208,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) } mutex_lock(&dev->intf_state_mutex); - if (dev->interface_state == MLX5_INTERFACE_STATE_DOWN) { + if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) { dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n", __func__); goto out; @@ -1241,7 +1242,8 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv) mlx5_cmd_cleanup(dev); out: - dev->interface_state = MLX5_INTERFACE_STATE_DOWN; + clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state); + set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state); mutex_unlock(&dev->intf_state_mutex); return err; } @@ -1452,6 +1454,18 @@ static const struct pci_error_handlers mlx5_err_handler = { .resume = mlx5_pci_resume }; +static void shutdown(struct pci_dev *pdev) +{ + struct mlx5_core_dev *dev = pci_get_drvdata(pdev); + struct mlx5_priv *priv = &dev->priv; + + dev_info(&pdev->dev, "Shutdown was called\n"); + /* Notify mlx5 clients that the kernel is being shut down */ + set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state); + mlx5_unload_one(dev, priv); + mlx5_pci_disable_device(dev); +} + static const struct pci_device_id mlx5_core_pci_table[] = { { PCI_VDEVICE(MELLANOX, 0x1011) }, /* Connect-IB */ { PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF}, /* Connect-IB VF */ @@ -1471,6 +1485,7 @@ static struct pci_driver mlx5_core_driver = { .id_table = mlx5_core_pci_table, .probe = init_one, .remove = remove_one, + .shutdown = shutdown, .err_handler = &mlx5_err_handler, .sriov_configure = mlx5_core_sriov_configure, }; diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index dcd5ac8d3b14..369c837d40f5 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -519,8 +519,9 @@ enum mlx5_device_state { }; enum mlx5_interface_state { - MLX5_INTERFACE_STATE_DOWN, - MLX5_INTERFACE_STATE_UP, + MLX5_INTERFACE_STATE_DOWN = BIT(0), + MLX5_INTERFACE_STATE_UP = BIT(1), + MLX5_INTERFACE_STATE_SHUTDOWN = BIT(2), }; enum mlx5_pci_status { @@ -544,7 +545,7 @@ struct mlx5_core_dev { enum mlx5_device_state state; /* sync interface state */ struct mutex intf_state_mutex; - enum mlx5_interface_state interface_state; + unsigned long intf_state; void (*event) (struct mlx5_core_dev *dev, enum mlx5_dev_event event, unsigned long param); -- cgit v1.2.3 From 02da2d72174c61988eb4456b53f405e3ebdebce4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 24 Apr 2016 16:17:05 -0700 Subject: Linux 4.6-rc5 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 012b7dd3ed24..9496df81b9a8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc5 NAME = Blurry Fish Butt # *DOCUMENTATION* -- cgit v1.2.3 From 94862a62dfe3ba1c7601115a2dc80721c5b256f0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Apr 2016 20:57:47 +0200 Subject: Revert "cpufreq: governor: Fix negative idle_time when configured with CONFIG_HZ_PERIODIC" Revert commit 0df35026c6a5 (cpufreq: governor: Fix negative idle_time when configured with CONFIG_HZ_PERIODIC) that introduced a regression by causing the ondemand cpufreq governor to misbehave for CONFIG_TICK_CPU_ACCOUNTING unset (the frequency goes up to the max at one point and stays there indefinitely). The revert takes subsequent modifications of the code in question into account. Fixes: 0df35026c6a5 (cpufreq: governor: Fix negative idle_time when configured with CONFIG_HZ_PERIODIC) Link: https://bugzilla.kernel.org/show_bug.cgi?id=115261 Reported-and-tested-by: Timo Valtoaho Cc: 4.5+ # 4.5+ Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- drivers/cpufreq/cpufreq_governor.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 10a5cfeae8c5..5f1147fa9239 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -193,12 +193,8 @@ unsigned int dbs_update(struct cpufreq_policy *policy) wall_time = cur_wall_time - j_cdbs->prev_cpu_wall; j_cdbs->prev_cpu_wall = cur_wall_time; - if (cur_idle_time <= j_cdbs->prev_cpu_idle) { - idle_time = 0; - } else { - idle_time = cur_idle_time - j_cdbs->prev_cpu_idle; - j_cdbs->prev_cpu_idle = cur_idle_time; - } + idle_time = cur_idle_time - j_cdbs->prev_cpu_idle; + j_cdbs->prev_cpu_idle = cur_idle_time; if (ignore_nice) { u64 cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; -- cgit v1.2.3 From 391a20333b8393ef2e13014e6e59d192c5594471 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Thu, 21 Apr 2016 22:23:31 +0200 Subject: ipv4/fib: don't warn when primary address is missing if in_dev is dead After commit fbd40ea0180a ("ipv4: Don't do expensive useless work during inetdev destroy.") when deleting an interface, fib_del_ifaddr() can be executed without any primary address present on the dead interface. The above is safe, but triggers some "bug: prim == NULL" warnings. This commit avoids warning if the in_dev is dead Signed-off-by: Paolo Abeni Signed-off-by: David S. Miller --- net/ipv4/fib_frontend.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 8a9246deccfe..63566ec54794 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -904,7 +904,11 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim) if (ifa->ifa_flags & IFA_F_SECONDARY) { prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); if (!prim) { - pr_warn("%s: bug: prim == NULL\n", __func__); + /* if the device has been deleted, we don't perform + * address promotion + */ + if (!in_dev->dead) + pr_warn("%s: bug: prim == NULL\n", __func__); return; } if (iprim && iprim != prim) { -- cgit v1.2.3 From da67e68c0e4601e87612918496fd8c7d72795e50 Mon Sep 17 00:00:00 2001 From: Eric Engestrom Date: Mon, 25 Apr 2016 01:24:04 +0100 Subject: Documentation: dt: arc: fix spelling mistakes Signed-off-by: Eric Engestrom Signed-off-by: Vineet Gupta --- Documentation/devicetree/bindings/arc/archs-pct.txt | 2 +- Documentation/devicetree/bindings/arc/pct.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/arc/archs-pct.txt b/Documentation/devicetree/bindings/arc/archs-pct.txt index 1ae98b87c640..e4b9dcee6d41 100644 --- a/Documentation/devicetree/bindings/arc/archs-pct.txt +++ b/Documentation/devicetree/bindings/arc/archs-pct.txt @@ -2,7 +2,7 @@ The ARC HS can be configured with a pipeline performance monitor for counting CPU and cache events like cache misses and hits. Like conventional PCT there -are 100+ hardware conditions dynamically mapped to upto 32 counters. +are 100+ hardware conditions dynamically mapped to up to 32 counters. It also supports overflow interrupts. Required properties: diff --git a/Documentation/devicetree/bindings/arc/pct.txt b/Documentation/devicetree/bindings/arc/pct.txt index 7b9588444f20..4e874d9a38a6 100644 --- a/Documentation/devicetree/bindings/arc/pct.txt +++ b/Documentation/devicetree/bindings/arc/pct.txt @@ -2,7 +2,7 @@ The ARC700 can be configured with a pipeline performance monitor for counting CPU and cache events like cache misses and hits. Like conventional PCT there -are 100+ hardware conditions dynamically mapped to upto 32 counters +are 100+ hardware conditions dynamically mapped to up to 32 counters Note that: * The ARC 700 PCT does not support interrupts; although HW events may be -- cgit v1.2.3 From a0a966b83873f33778710a4fc59240244b0734a5 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 22 Apr 2016 09:26:52 +0200 Subject: ARM: EXYNOS: Properly skip unitialized parent clock in power domain on We want to skip reparenting a clock on turning on power domain, if we do not have the parent yet. The parent is obtained when turning the domain off. However due to a typo, the loop is continued on IS_ERR() of clock being reparented, not on the IS_ERR() of the parent. Theoretically this could lead to OOPS on first turn on of a power domain, if there was no turn off before. Practically that should never happen because all power domains are turned on by default (reset value, bootloader does not turn off them usually) so the first action will be always turn off. Fixes: 29e5eea06bc1 ("ARM: EXYNOS: Get current parent clock for power domain on/off") Reported-by: Vladimir Zapolskiy Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/pm_domains.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index 7c21760f590f..875a2bab64f6 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c @@ -92,7 +92,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) if (IS_ERR(pd->clk[i])) break; - if (IS_ERR(pd->clk[i])) + if (IS_ERR(pd->pclk[i])) continue; /* Skip on first power up */ if (clk_set_parent(pd->clk[i], pd->pclk[i])) pr_err("%s: error setting parent to clock%d\n", -- cgit v1.2.3 From 2c932d4c9165ddbe417af612dbe2113df7f2057e Mon Sep 17 00:00:00 2001 From: Ashish Samant Date: Fri, 25 Mar 2016 10:53:41 -0700 Subject: fuse: Fix return value from fuse_get_user_pages() fuse_get_user_pages() should return error or 0. Otherwise fuse_direct_io read will not return 0 to indicate that read has completed. Fixes: 742f992708df ("fuse: return patrial success from fuse_direct_io()") Signed-off-by: Ashish Samant Signed-off-by: Seth Forshee Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 719924d6c706..dcad5e210525 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1295,7 +1295,7 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii, *nbytesp = nbytes; - return ret; + return ret < 0 ? ret : 0; } static inline int fuse_iter_npages(const struct iov_iter *ii_p) -- cgit v1.2.3 From c26f6c61578852f679787d555e6d07804e1f5f14 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Mon, 25 Apr 2016 06:19:38 -0500 Subject: udf: Fix conversion of 'dstring' fields to UTF8 Commit 9293fcfbc1812a22ad5ce1b542eb90c1bbe01be1 ("udf: Remove struct ustr as non-needed intermediate storage"), while getting rid of 'struct ustr', does not take any special care of 'dstring' fields and effectively use fixed field length instead of actual string length, encoded in the last byte of the field. Also, commit 484a10f49387e4386bf2708532e75bf78ffea2cb ("udf: Merge linux specific translation into CS0 conversion function") introduced checking of the length of the string being converted, requiring proper alignment to number of bytes constituing each character. The UDF volume identifier is represented as a 32-bytes 'dstring', and needs to be converted from CS0 to UTF8, while mounting UDF filesystem. The changes in mentioned commits can in some cases lead to incorrect handling of volume identifier: - if the actual string in 'dstring' is of maximal length and does not have zero bytes separating it from dstring encoded length in last byte, that last byte may be included in conversion, thus making incorrect resulting string; - if the identifier is encoded with 2-bytes characters (compression code is 16), the length of 31 bytes (32 bytes of field length minus 1 byte of compression code), taken as the string length, is reported as an incorrect (unaligned) length, and the conversion fails, which in its turn leads to volume mounting failure. This patch introduces handling of 'dstring' encoded length field in udf_CS0toUTF8 function, that is used in all and only cases when 'dstring' fields are converted. Currently these cases are processing of Volume Identifier and Volume Set Identifier fields. The function is also renamed to udf_dstrCS0toUTF8 to distinctly indicate that it handles 'dstring' input. Signed-off-by: Andrew Gabbasov Signed-off-by: Jan Kara --- fs/udf/super.c | 4 ++-- fs/udf/udfdecl.h | 2 +- fs/udf/unicode.c | 16 ++++++++++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index fa92fe839fda..36661acaf33b 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -919,14 +919,14 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) #endif } - ret = udf_CS0toUTF8(outstr, 31, pvoldesc->volIdent, 32); + ret = udf_dstrCS0toUTF8(outstr, 31, pvoldesc->volIdent, 32); if (ret < 0) goto out_bh; strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret); udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); - ret = udf_CS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128); + ret = udf_dstrCS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128); if (ret < 0) goto out_bh; diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 972b70625614..263829ef1873 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -212,7 +212,7 @@ extern int udf_get_filename(struct super_block *, const uint8_t *, int, uint8_t *, int); extern int udf_put_filename(struct super_block *, const uint8_t *, int, uint8_t *, int); -extern int udf_CS0toUTF8(uint8_t *, int, const uint8_t *, int); +extern int udf_dstrCS0toUTF8(uint8_t *, int, const uint8_t *, int); /* ialloc.c */ extern void udf_free_inode(struct inode *); diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index 3ff42f4437f3..695389a4fc23 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -335,9 +335,21 @@ try_again: return u_len; } -int udf_CS0toUTF8(uint8_t *utf_o, int o_len, const uint8_t *ocu_i, int i_len) +int udf_dstrCS0toUTF8(uint8_t *utf_o, int o_len, + const uint8_t *ocu_i, int i_len) { - return udf_name_from_CS0(utf_o, o_len, ocu_i, i_len, + int s_len = 0; + + if (i_len > 0) { + s_len = ocu_i[i_len - 1]; + if (s_len >= i_len) { + pr_err("incorrect dstring lengths (%d/%d)\n", + s_len, i_len); + return -EINVAL; + } + } + + return udf_name_from_CS0(utf_o, o_len, ocu_i, s_len, udf_uni2char_utf8, 0); } -- cgit v1.2.3 From 3020ca711871fdaf0c15c8bab677a6bc302e28fe Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 Apr 2016 04:00:50 -0300 Subject: [media] v4l2-dv-timings.h: fix polarity for 4k formats The VSync polarity was negative instead of positive for the 4k CEA formats. I probably copy-and-pasted these from the DMT 4k format, which does have a negative VSync polarity. Signed-off-by: Hans Verkuil Reported-by: Martin Bugge Cc: # for v4.1 and up Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/v4l2-dv-timings.h | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/include/uapi/linux/v4l2-dv-timings.h b/include/uapi/linux/v4l2-dv-timings.h index c039f1d68a09..086168e18ca8 100644 --- a/include/uapi/linux/v4l2-dv-timings.h +++ b/include/uapi/linux/v4l2-dv-timings.h @@ -183,7 +183,8 @@ #define V4L2_DV_BT_CEA_3840X2160P24 { \ .type = V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ @@ -191,14 +192,16 @@ #define V4L2_DV_BT_CEA_3840X2160P25 { \ .type = V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_3840X2160P30 { \ .type = V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ @@ -206,14 +209,16 @@ #define V4L2_DV_BT_CEA_3840X2160P50 { \ .type = V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_3840X2160P60 { \ .type = V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(3840, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ @@ -221,7 +226,8 @@ #define V4L2_DV_BT_CEA_4096X2160P24 { \ .type = V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ @@ -229,14 +235,16 @@ #define V4L2_DV_BT_CEA_4096X2160P25 { \ .type = V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_4096X2160P30 { \ .type = V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 297000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ @@ -244,14 +252,16 @@ #define V4L2_DV_BT_CEA_4096X2160P50 { \ .type = V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_IS_CE_VIDEO) \ } #define V4L2_DV_BT_CEA_4096X2160P60 { \ .type = V4L2_DV_BT_656_1120, \ - V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ + V4L2_INIT_BT_TIMINGS(4096, 2160, 0, \ + V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \ 594000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ V4L2_DV_BT_STD_CEA861, \ V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_IS_CE_VIDEO) \ -- cgit v1.2.3 From b93876845c5e30a92964eeb088d9d2e024118022 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 25 Apr 2016 06:04:45 -0300 Subject: [media] media: vb2: Fix regression on poll() for RW mode When using a device is read/write mode, vb2 does not handle properly the first select/poll operation. The reason for this, is that when this code has been refactored, some of the operations have changed their order, and now fileio emulator is not started. The reintroduced check to the core is enabled by a quirk flag, that avoids this check by other subsystems like DVB. Fixes: 49d8ab9feaf2 ("media] media: videobuf2: Separate vb2_poll()") Reported-by: Dimitrios Katsaros Cc: Junghak Sung Cc: # for v4.5 and up Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 10 ++++++++++ drivers/media/v4l2-core/videobuf2-v4l2.c | 14 ++++++-------- include/media/videobuf2-core.h | 4 ++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 2169544883e8..9fbcb67a9ee6 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -2297,6 +2297,16 @@ unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file, if (!vb2_is_streaming(q) || q->error) return POLLERR; + /* + * If this quirk is set and QBUF hasn't been called yet then + * return POLLERR as well. This only affects capture queues, output + * queues will always initialize waiting_for_buffers to false. + * This quirk is set by V4L2 for backwards compatibility reasons. + */ + if (q->quirk_poll_must_check_waiting_for_buffers && + q->waiting_for_buffers && (req_events & (POLLIN | POLLRDNORM))) + return POLLERR; + /* * For output streams you can call write() as long as there are fewer * buffers queued than there are buffers available. diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c index 8da7470ca364..7f366f1b0377 100644 --- a/drivers/media/v4l2-core/videobuf2-v4l2.c +++ b/drivers/media/v4l2-core/videobuf2-v4l2.c @@ -771,6 +771,12 @@ int vb2_queue_init(struct vb2_queue *q) q->is_output = V4L2_TYPE_IS_OUTPUT(q->type); q->copy_timestamp = (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) == V4L2_BUF_FLAG_TIMESTAMP_COPY; + /* + * For compatibility with vb1: if QBUF hasn't been called yet, then + * return POLLERR as well. This only affects capture queues, output + * queues will always initialize waiting_for_buffers to false. + */ + q->quirk_poll_must_check_waiting_for_buffers = true; return vb2_core_queue_init(q); } @@ -824,14 +830,6 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) poll_wait(file, &fh->wait, wait); } - /* - * For compatibility with vb1: if QBUF hasn't been called yet, then - * return POLLERR as well. This only affects capture queues, output - * queues will always initialize waiting_for_buffers to false. - */ - if (q->waiting_for_buffers && (req_events & (POLLIN | POLLRDNORM))) - return POLLERR; - return res | vb2_core_poll(q, file, wait); } EXPORT_SYMBOL_GPL(vb2_poll); diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 5342ff4d748f..88e3ab496e8f 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -404,6 +404,9 @@ struct vb2_buf_ops { * @fileio_read_once: report EOF after reading the first buffer * @fileio_write_immediately: queue buffer after each write() call * @allow_zero_bytesused: allow bytesused == 0 to be passed to the driver + * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF + * has not been called. This is a vb1 idiom that has been adopted + * also by vb2. * @lock: pointer to a mutex that protects the vb2_queue struct. The * driver can set this to a mutex to let the v4l2 core serialize * the queuing ioctls. If the driver wants to handle locking @@ -467,6 +470,7 @@ struct vb2_queue { unsigned fileio_read_once:1; unsigned fileio_write_immediately:1; unsigned allow_zero_bytesused:1; + unsigned quirk_poll_must_check_waiting_for_buffers:1; struct mutex *lock; void *owner; -- cgit v1.2.3 From 89a095668304e8a02502ffd35edacffdbf49aa8c Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Thu, 3 Mar 2016 16:12:48 -0300 Subject: [media] vb2-memops: Fix over allocation of frame vectors On page unaligned frames, create_framevec forces get_vaddr_frames to allocate an extra page at the end of the buffer. Under some circumstances, this leads to -EINVAL on VIDIOC_QBUF. E.g: We have vm_a that vm_area that goes from 0x1000 to 0x3000. And a frame that goes from 0x1800 to 0x2800, i.e. 2 pages. frame_vector_create will be called with the following params: get_vaddr_frames(0x1800, 2, write, 1, vec); get_vaddr will allocate the first page after checking that the memory 0x1800-0x27ff is valid, but it will not allocate the second page because the range 0x2800-0x37ff is out of the vm_a range. This results in create_framevec returning -EFAULT Error Trace: [ 9083.793015] video0: VIDIOC_QBUF: 00:00:00.00000000 index=1, type=vid-cap, flags=0x00002002, field=any, sequence=0, memory=userptr, bytesused=0, offset/userptr=0x7ff2b023ca80, length=5765760 [ 9083.793028] timecode=00:00:00 type=0, flags=0x00000000, frames=0, userbits=0x00000000 [ 9083.793117] video0: VIDIOC_QBUF: error -22: 00:00:00.00000000 index=2, type=vid-cap, flags=0x00000000, field=any, sequence=0, memory=userptr, bytesused=0, offset/userptr=0x7ff2b07bc500, length=5765760 Also use true instead of 1 since that argument is a bool in the get_vaddr_frames() prototype. Fixes: 21fb0cb7ec65 ("[media] vb2: Provide helpers for mapping virtual addresses") Reported-by: Albert Antony Signed-off-by: Ricardo Ribalda Delgado [hans.verkuil@cisco.com: merged the 'bool' change into this patch] Acked-by: Marek Szyprowski Reviewed-by: Jan Kara Cc: # for v4.3 and up Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-memops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c index dbec5923fcf0..3c3b517f1d1c 100644 --- a/drivers/media/v4l2-core/videobuf2-memops.c +++ b/drivers/media/v4l2-core/videobuf2-memops.c @@ -49,7 +49,7 @@ struct frame_vector *vb2_create_framevec(unsigned long start, vec = frame_vector_create(nr); if (!vec) return ERR_PTR(-ENOMEM); - ret = get_vaddr_frames(start, nr, write, 1, vec); + ret = get_vaddr_frames(start & PAGE_MASK, nr, write, true, vec); if (ret < 0) goto out_destroy; /* We accept only complete set of PFNs */ -- cgit v1.2.3 From 567a44ecb44eb2584ddb93e962cfb133ce77e0bb Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Mon, 25 Apr 2016 17:01:56 +0300 Subject: HID: Fix boot delay for Creative SB Omni Surround 5.1 with quirk Needed for v2 of the device firmware, otherwise kernel will stuck for few seconds and throw "usb_submit_urb(ctrl) failed: -1" early on system boot. Signed-off-by: Nazar Mokrynskyi Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/usbhid/hid-quirks.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index c6eaff5f8845..0238f0169e48 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -259,6 +259,7 @@ #define USB_DEVICE_ID_CORSAIR_K90 0x1b02 #define USB_VENDOR_ID_CREATIVELABS 0x041e +#define USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51 0x322c #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 #define USB_VENDOR_ID_CVTOUCH 0x1ff7 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index ed2f68edc8f1..53fc856d6867 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -71,6 +71,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, -- cgit v1.2.3 From b297874a2d5c5fcaeb5242a8b4708e54c5477d90 Mon Sep 17 00:00:00 2001 From: Michał Pecio Date: Sun, 24 Apr 2016 18:11:45 +0200 Subject: md/raid0: remove empty line printk from dump_zones Remove the final printk. All preceding output is already properly newline-terminated and the printk isn't even KERN_CONT to begin with, so it only adds one empty line to the log. Signed-off-by: Michal Pecio Signed-off-by: Shaohua Li --- drivers/md/raid0.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index f63dbb68e3a9..34783a3c8b3c 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -70,7 +70,6 @@ static void dump_zones(struct mddev *mddev) (unsigned long long)zone_size>>1); zone_start = conf->strip_zone[j].zone_end; } - printk(KERN_INFO "\n"); } static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) -- cgit v1.2.3 From a30b8f81d9d6fe24eab8a023794548b048f08e3c Mon Sep 17 00:00:00 2001 From: Azael Avalos Date: Fri, 22 Apr 2016 09:29:36 -0600 Subject: toshiba_acpi: Fix regression caused by hotkey enabling value Commit 52cbae0127ad ("toshiba_acpi: Change default Hotkey enabling value") changed the hotkeys enabling value, as it was the same value Windows uses, however, it turns out that the value tells the EC that the driver will now take care of the hardware events like the physical RFKill switch or the pointing device toggle button. This patch reverts such commit by changing the default hotkey enabling value to 0x09, which enables hotkey events only, making the hardware buttons working again. Fixes bugs 113331 and 114941. Signed-off-by: Azael Avalos Cc: stable@vger.kernel.org Signed-off-by: Darren Hart --- drivers/platform/x86/toshiba_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index df1f1a76a862..01e12d221a8b 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -135,7 +135,7 @@ MODULE_LICENSE("GPL"); /* Field definitions */ #define HCI_ACCEL_MASK 0x7fff #define HCI_HOTKEY_DISABLE 0x0b -#define HCI_HOTKEY_ENABLE 0x01 +#define HCI_HOTKEY_ENABLE 0x09 #define HCI_HOTKEY_SPECIAL_FUNCTIONS 0x10 #define HCI_LCD_BRIGHTNESS_BITS 3 #define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) -- cgit v1.2.3 From 6c1ea260f89709e0021d2c59f8fd2a104b5b1123 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Mon, 11 Apr 2016 19:34:49 +0200 Subject: libceph: make authorizer destruction independent of ceph_auth_client Starting the kernel client with cephx disabled and then enabling cephx and restarting userspace daemons can result in a crash: [262671.478162] BUG: unable to handle kernel paging request at ffffebe000000000 [262671.531460] IP: [] kfree+0x5a/0x130 [262671.584334] PGD 0 [262671.635847] Oops: 0000 [#1] SMP [262672.055841] CPU: 22 PID: 2961272 Comm: kworker/22:2 Not tainted 4.2.0-34-generic #39~14.04.1-Ubuntu [262672.162338] Hardware name: Dell Inc. PowerEdge R720/068CDY, BIOS 2.4.3 07/09/2014 [262672.268937] Workqueue: ceph-msgr con_work [libceph] [262672.322290] task: ffff88081c2d0dc0 ti: ffff880149ae8000 task.ti: ffff880149ae8000 [262672.428330] RIP: 0010:[] [] kfree+0x5a/0x130 [262672.535880] RSP: 0018:ffff880149aeba58 EFLAGS: 00010286 [262672.589486] RAX: 000001e000000000 RBX: 0000000000000012 RCX: ffff8807e7461018 [262672.695980] RDX: 000077ff80000000 RSI: ffff88081af2be04 RDI: 0000000000000012 [262672.803668] RBP: ffff880149aeba78 R08: 0000000000000000 R09: 0000000000000000 [262672.912299] R10: ffffebe000000000 R11: ffff880819a60e78 R12: ffff8800aec8df40 [262673.021769] R13: ffffffffc035f70f R14: ffff8807e5b138e0 R15: ffff880da9785840 [262673.131722] FS: 0000000000000000(0000) GS:ffff88081fac0000(0000) knlGS:0000000000000000 [262673.245377] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [262673.303281] CR2: ffffebe000000000 CR3: 0000000001c0d000 CR4: 00000000001406e0 [262673.417556] Stack: [262673.472943] ffff880149aeba88 ffff88081af2be04 ffff8800aec8df40 ffff88081af2be04 [262673.583767] ffff880149aeba98 ffffffffc035f70f ffff880149aebac8 ffff8800aec8df00 [262673.694546] ffff880149aebac8 ffffffffc035c89e ffff8807e5b138e0 ffff8805b047f800 [262673.805230] Call Trace: [262673.859116] [] ceph_x_destroy_authorizer+0x1f/0x50 [libceph] [262673.968705] [] ceph_auth_destroy_authorizer+0x3e/0x60 [libceph] [262674.078852] [] put_osd+0x45/0x80 [libceph] [262674.134249] [] remove_osd+0xae/0x140 [libceph] [262674.189124] [] __reset_osd+0x103/0x150 [libceph] [262674.243749] [] kick_requests+0x223/0x460 [libceph] [262674.297485] [] ceph_osdc_handle_map+0x282/0x5e0 [libceph] [262674.350813] [] dispatch+0x4e/0x720 [libceph] [262674.403312] [] try_read+0x3d1/0x1090 [libceph] [262674.454712] [] ? dequeue_entity+0x152/0x690 [262674.505096] [] con_work+0xcb/0x1300 [libceph] [262674.555104] [] process_one_work+0x14e/0x3d0 [262674.604072] [] worker_thread+0x11a/0x470 [262674.652187] [] ? rescuer_thread+0x310/0x310 [262674.699022] [] kthread+0xd2/0xf0 [262674.744494] [] ? kthread_create_on_node+0x1c0/0x1c0 [262674.789543] [] ret_from_fork+0x3f/0x70 [262674.834094] [] ? kthread_create_on_node+0x1c0/0x1c0 What happens is the following: (1) new MON session is established (2) old "none" ac is destroyed (3) new "cephx" ac is constructed ... (4) old OSD session (w/ "none" authorizer) is put ceph_auth_destroy_authorizer(ac, osd->o_auth.authorizer) osd->o_auth.authorizer in the "none" case is just a bare pointer into ac, which contains a single static copy for all services. By the time we get to (4), "none" ac, freed in (2), is long gone. On top of that, a new vtable installed in (3) points us at ceph_x_destroy_authorizer(), so we end up trying to destroy a "none" authorizer with a "cephx" destructor operating on invalid memory! To fix this, decouple authorizer destruction from ac and do away with a single static "none" authorizer by making a copy for each OSD or MDS session. Authorizers themselves are independent of ac and so there is no reason for destroy_authorizer() to be an ac op. Make it an op on the authorizer itself by turning ceph_authorizer into a real struct. Fixes: http://tracker.ceph.com/issues/15447 Reported-by: Alan Zhang Signed-off-by: Ilya Dryomov Reviewed-by: Sage Weil --- fs/ceph/mds_client.c | 6 ++-- include/linux/ceph/auth.h | 10 +++--- include/linux/ceph/osd_client.h | 1 - net/ceph/auth.c | 8 ++--- net/ceph/auth_none.c | 71 ++++++++++++++++++++++------------------- net/ceph/auth_none.h | 3 +- net/ceph/auth_x.c | 21 ++++++------ net/ceph/auth_x.h | 1 + net/ceph/osd_client.c | 6 ++-- 9 files changed, 62 insertions(+), 65 deletions(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 541ead4d8965..85b8517f17a0 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -386,9 +386,7 @@ void ceph_put_mds_session(struct ceph_mds_session *s) atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); if (atomic_dec_and_test(&s->s_ref)) { if (s->s_auth.authorizer) - ceph_auth_destroy_authorizer( - s->s_mdsc->fsc->client->monc.auth, - s->s_auth.authorizer); + ceph_auth_destroy_authorizer(s->s_auth.authorizer); kfree(s); } } @@ -3900,7 +3898,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, struct ceph_auth_handshake *auth = &s->s_auth; if (force_new && auth->authorizer) { - ceph_auth_destroy_authorizer(ac, auth->authorizer); + ceph_auth_destroy_authorizer(auth->authorizer); auth->authorizer = NULL; } if (!auth->authorizer) { diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h index 260d78b587c4..1563265d2097 100644 --- a/include/linux/ceph/auth.h +++ b/include/linux/ceph/auth.h @@ -12,9 +12,12 @@ */ struct ceph_auth_client; -struct ceph_authorizer; struct ceph_msg; +struct ceph_authorizer { + void (*destroy)(struct ceph_authorizer *); +}; + struct ceph_auth_handshake { struct ceph_authorizer *authorizer; void *authorizer_buf; @@ -62,8 +65,6 @@ struct ceph_auth_client_ops { struct ceph_auth_handshake *auth); int (*verify_authorizer_reply)(struct ceph_auth_client *ac, struct ceph_authorizer *a, size_t len); - void (*destroy_authorizer)(struct ceph_auth_client *ac, - struct ceph_authorizer *a); void (*invalidate_authorizer)(struct ceph_auth_client *ac, int peer_type); @@ -112,8 +113,7 @@ extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac); extern int ceph_auth_create_authorizer(struct ceph_auth_client *ac, int peer_type, struct ceph_auth_handshake *auth); -extern void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, - struct ceph_authorizer *a); +void ceph_auth_destroy_authorizer(struct ceph_authorizer *a); extern int ceph_auth_update_authorizer(struct ceph_auth_client *ac, int peer_type, struct ceph_auth_handshake *a); diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index 4343df806710..cbf460927c42 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h @@ -16,7 +16,6 @@ struct ceph_msg; struct ceph_snap_context; struct ceph_osd_request; struct ceph_osd_client; -struct ceph_authorizer; /* * completion callback for async writepages diff --git a/net/ceph/auth.c b/net/ceph/auth.c index 6b923bcaa2a4..2bc5965fdd1e 100644 --- a/net/ceph/auth.c +++ b/net/ceph/auth.c @@ -293,13 +293,9 @@ int ceph_auth_create_authorizer(struct ceph_auth_client *ac, } EXPORT_SYMBOL(ceph_auth_create_authorizer); -void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, - struct ceph_authorizer *a) +void ceph_auth_destroy_authorizer(struct ceph_authorizer *a) { - mutex_lock(&ac->mutex); - if (ac->ops && ac->ops->destroy_authorizer) - ac->ops->destroy_authorizer(ac, a); - mutex_unlock(&ac->mutex); + a->destroy(a); } EXPORT_SYMBOL(ceph_auth_destroy_authorizer); diff --git a/net/ceph/auth_none.c b/net/ceph/auth_none.c index 8c93fa8d81bc..5f836f02ae36 100644 --- a/net/ceph/auth_none.c +++ b/net/ceph/auth_none.c @@ -16,7 +16,6 @@ static void reset(struct ceph_auth_client *ac) struct ceph_auth_none_info *xi = ac->private; xi->starting = true; - xi->built_authorizer = false; } static void destroy(struct ceph_auth_client *ac) @@ -39,6 +38,27 @@ static int should_authenticate(struct ceph_auth_client *ac) return xi->starting; } +static int ceph_auth_none_build_authorizer(struct ceph_auth_client *ac, + struct ceph_none_authorizer *au) +{ + void *p = au->buf; + void *const end = p + sizeof(au->buf); + int ret; + + ceph_encode_8_safe(&p, end, 1, e_range); + ret = ceph_entity_name_encode(ac->name, &p, end); + if (ret < 0) + return ret; + + ceph_encode_64_safe(&p, end, ac->global_id, e_range); + au->buf_len = p - (void *)au->buf; + dout("%s built authorizer len %d\n", __func__, au->buf_len); + return 0; + +e_range: + return -ERANGE; +} + static int build_request(struct ceph_auth_client *ac, void *buf, void *end) { return 0; @@ -57,32 +77,32 @@ static int handle_reply(struct ceph_auth_client *ac, int result, return result; } +static void ceph_auth_none_destroy_authorizer(struct ceph_authorizer *a) +{ + kfree(a); +} + /* - * build an 'authorizer' with our entity_name and global_id. we can - * reuse a single static copy since it is identical for all services - * we connect to. + * build an 'authorizer' with our entity_name and global_id. it is + * identical for all services we connect to. */ static int ceph_auth_none_create_authorizer( struct ceph_auth_client *ac, int peer_type, struct ceph_auth_handshake *auth) { - struct ceph_auth_none_info *ai = ac->private; - struct ceph_none_authorizer *au = &ai->au; - void *p, *end; + struct ceph_none_authorizer *au; int ret; - if (!ai->built_authorizer) { - p = au->buf; - end = p + sizeof(au->buf); - ceph_encode_8(&p, 1); - ret = ceph_entity_name_encode(ac->name, &p, end - 8); - if (ret < 0) - goto bad; - ceph_decode_need(&p, end, sizeof(u64), bad2); - ceph_encode_64(&p, ac->global_id); - au->buf_len = p - (void *)au->buf; - ai->built_authorizer = true; - dout("built authorizer len %d\n", au->buf_len); + au = kmalloc(sizeof(*au), GFP_NOFS); + if (!au) + return -ENOMEM; + + au->base.destroy = ceph_auth_none_destroy_authorizer; + + ret = ceph_auth_none_build_authorizer(ac, au); + if (ret) { + kfree(au); + return ret; } auth->authorizer = (struct ceph_authorizer *) au; @@ -92,17 +112,6 @@ static int ceph_auth_none_create_authorizer( auth->authorizer_reply_buf_len = sizeof (au->reply_buf); return 0; - -bad2: - ret = -ERANGE; -bad: - return ret; -} - -static void ceph_auth_none_destroy_authorizer(struct ceph_auth_client *ac, - struct ceph_authorizer *a) -{ - /* nothing to do */ } static const struct ceph_auth_client_ops ceph_auth_none_ops = { @@ -114,7 +123,6 @@ static const struct ceph_auth_client_ops ceph_auth_none_ops = { .build_request = build_request, .handle_reply = handle_reply, .create_authorizer = ceph_auth_none_create_authorizer, - .destroy_authorizer = ceph_auth_none_destroy_authorizer, }; int ceph_auth_none_init(struct ceph_auth_client *ac) @@ -127,7 +135,6 @@ int ceph_auth_none_init(struct ceph_auth_client *ac) return -ENOMEM; xi->starting = true; - xi->built_authorizer = false; ac->protocol = CEPH_AUTH_NONE; ac->private = xi; diff --git a/net/ceph/auth_none.h b/net/ceph/auth_none.h index 059a3ce4b53f..62021535ae4a 100644 --- a/net/ceph/auth_none.h +++ b/net/ceph/auth_none.h @@ -12,6 +12,7 @@ */ struct ceph_none_authorizer { + struct ceph_authorizer base; char buf[128]; int buf_len; char reply_buf[0]; @@ -19,8 +20,6 @@ struct ceph_none_authorizer { struct ceph_auth_none_info { bool starting; - bool built_authorizer; - struct ceph_none_authorizer au; /* we only need one; it's static */ }; int ceph_auth_none_init(struct ceph_auth_client *ac); diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index 9e43a315e662..a0905f04bd13 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c @@ -565,6 +565,14 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, return -EAGAIN; } +static void ceph_x_destroy_authorizer(struct ceph_authorizer *a) +{ + struct ceph_x_authorizer *au = (void *)a; + + ceph_x_authorizer_cleanup(au); + kfree(au); +} + static int ceph_x_create_authorizer( struct ceph_auth_client *ac, int peer_type, struct ceph_auth_handshake *auth) @@ -581,6 +589,8 @@ static int ceph_x_create_authorizer( if (!au) return -ENOMEM; + au->base.destroy = ceph_x_destroy_authorizer; + ret = ceph_x_build_authorizer(ac, th, au); if (ret) { kfree(au); @@ -643,16 +653,6 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, return ret; } -static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac, - struct ceph_authorizer *a) -{ - struct ceph_x_authorizer *au = (void *)a; - - ceph_x_authorizer_cleanup(au); - kfree(au); -} - - static void ceph_x_reset(struct ceph_auth_client *ac) { struct ceph_x_info *xi = ac->private; @@ -770,7 +770,6 @@ static const struct ceph_auth_client_ops ceph_x_ops = { .create_authorizer = ceph_x_create_authorizer, .update_authorizer = ceph_x_update_authorizer, .verify_authorizer_reply = ceph_x_verify_authorizer_reply, - .destroy_authorizer = ceph_x_destroy_authorizer, .invalidate_authorizer = ceph_x_invalidate_authorizer, .reset = ceph_x_reset, .destroy = ceph_x_destroy, diff --git a/net/ceph/auth_x.h b/net/ceph/auth_x.h index 40b1a3cf7397..21a5af904bae 100644 --- a/net/ceph/auth_x.h +++ b/net/ceph/auth_x.h @@ -26,6 +26,7 @@ struct ceph_x_ticket_handler { struct ceph_x_authorizer { + struct ceph_authorizer base; struct ceph_crypto_key session_key; struct ceph_buffer *buf; unsigned int service; diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 32355d9d0103..40a53a70efdf 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -1087,10 +1087,8 @@ static void put_osd(struct ceph_osd *osd) dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref), atomic_read(&osd->o_ref) - 1); if (atomic_dec_and_test(&osd->o_ref)) { - struct ceph_auth_client *ac = osd->o_osdc->client->monc.auth; - if (osd->o_auth.authorizer) - ceph_auth_destroy_authorizer(ac, osd->o_auth.authorizer); + ceph_auth_destroy_authorizer(osd->o_auth.authorizer); kfree(osd); } } @@ -2984,7 +2982,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, struct ceph_auth_handshake *auth = &o->o_auth; if (force_new && auth->authorizer) { - ceph_auth_destroy_authorizer(ac, auth->authorizer); + ceph_auth_destroy_authorizer(auth->authorizer); auth->authorizer = NULL; } if (!auth->authorizer) { -- cgit v1.2.3 From 841645b5f2dfceac69b78fcd0c9050868d41ea61 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 25 Apr 2016 15:33:55 -0400 Subject: ipv6: Revert optional address flusing on ifdown. This reverts the following three commits: 70af921db6f8835f4b11c65731116560adb00c14 799977d9aafbf0ca0b9c39b04cbfb16db71302c9 f1705ec197e705b79ea40fe7a2cc5acfa1d3bfac The feature was ill conceived, has terrible semantics, and has added nothing but regressions to the already fragile ipv6 stack. Fixes: f1705ec197e7 ("net: ipv6: Make address flushing on ifdown optional") Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 9 -- include/linux/ipv6.h | 1 - include/uapi/linux/ipv6.h | 1 - net/ipv6/addrconf.c | 162 +++------------------------------ 4 files changed, 12 insertions(+), 161 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index b183e2b606c8..e0ac25210f7c 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1568,15 +1568,6 @@ temp_prefered_lft - INTEGER Preferred lifetime (in seconds) for temporary addresses. Default: 86400 (1 day) -keep_addr_on_down - INTEGER - Keep all IPv6 addresses on an interface down event. If set static - global addresses with no expiration time are not flushed. - >0 : enabled - 0 : system default - <0 : disabled - - Default: 0 (addresses are removed) - max_desync_factor - INTEGER Maximum value for DESYNC_FACTOR, which is a random value that ensures that clients don't synchronize with each diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 7edc14fb66b6..4b2267e1b7c3 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -62,7 +62,6 @@ struct ipv6_devconf { struct in6_addr secret; } stable_secret; __s32 use_oif_addrs_only; - __s32 keep_addr_on_down; void *sysctl; }; diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h index 395876060f50..ec117b65d5a5 100644 --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h @@ -176,7 +176,6 @@ enum { DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN, DEVCONF_DROP_UNICAST_IN_L2_MULTICAST, DEVCONF_DROP_UNSOLICITED_NA, - DEVCONF_KEEP_ADDR_ON_DOWN, DEVCONF_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 23cec53b568a..d77ba395d593 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -216,7 +216,6 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { }, .use_oif_addrs_only = 0, .ignore_routes_with_linkdown = 0, - .keep_addr_on_down = 0, }; static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { @@ -261,7 +260,6 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { }, .use_oif_addrs_only = 0, .ignore_routes_with_linkdown = 0, - .keep_addr_on_down = 0, }; /* Check if a valid qdisc is available */ @@ -3176,81 +3174,6 @@ static void addrconf_gre_config(struct net_device *dev) } #endif -#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) -/* If the host route is cached on the addr struct make sure it is associated - * with the proper table. e.g., enslavement can change and if so the cached - * host route needs to move to the new table. - */ -static void l3mdev_check_host_rt(struct inet6_dev *idev, - struct inet6_ifaddr *ifp) -{ - if (ifp->rt) { - u32 tb_id = l3mdev_fib_table(idev->dev) ? : RT6_TABLE_LOCAL; - - if (tb_id != ifp->rt->rt6i_table->tb6_id) { - ip6_del_rt(ifp->rt); - ifp->rt = NULL; - } - } -} -#else -static void l3mdev_check_host_rt(struct inet6_dev *idev, - struct inet6_ifaddr *ifp) -{ -} -#endif - -static int fixup_permanent_addr(struct inet6_dev *idev, - struct inet6_ifaddr *ifp) -{ - l3mdev_check_host_rt(idev, ifp); - - if (!ifp->rt) { - struct rt6_info *rt; - - rt = addrconf_dst_alloc(idev, &ifp->addr, false); - if (unlikely(IS_ERR(rt))) - return PTR_ERR(rt); - - ifp->rt = rt; - } - - if (!(ifp->flags & IFA_F_NOPREFIXROUTE)) { - addrconf_prefix_route(&ifp->addr, ifp->prefix_len, - idev->dev, 0, 0); - } - - addrconf_dad_start(ifp); - - return 0; -} - -static void addrconf_permanent_addr(struct net_device *dev) -{ - struct inet6_ifaddr *ifp, *tmp; - struct inet6_dev *idev; - - idev = __in6_dev_get(dev); - if (!idev) - return; - - write_lock_bh(&idev->lock); - - list_for_each_entry_safe(ifp, tmp, &idev->addr_list, if_list) { - if ((ifp->flags & IFA_F_PERMANENT) && - fixup_permanent_addr(idev, ifp) < 0) { - write_unlock_bh(&idev->lock); - ipv6_del_addr(ifp); - write_lock_bh(&idev->lock); - - net_info_ratelimited("%s: Failed to add prefix route for address %pI6c; dropping\n", - idev->dev->name, &ifp->addr); - } - } - - write_unlock_bh(&idev->lock); -} - static int addrconf_notify(struct notifier_block *this, unsigned long event, void *ptr) { @@ -3337,9 +3260,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, run_pending = 1; } - /* restore routes for permanent addresses */ - addrconf_permanent_addr(dev); - switch (dev->type) { #if IS_ENABLED(CONFIG_IPV6_SIT) case ARPHRD_SIT: @@ -3448,20 +3368,11 @@ static void addrconf_type_change(struct net_device *dev, unsigned long event) ipv6_mc_unmap(idev); } -static bool addr_is_local(const struct in6_addr *addr) -{ - return ipv6_addr_type(addr) & - (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); -} - static int addrconf_ifdown(struct net_device *dev, int how) { struct net *net = dev_net(dev); struct inet6_dev *idev; - struct inet6_ifaddr *ifa, *tmp; - struct list_head del_list; - int _keep_addr; - bool keep_addr; + struct inet6_ifaddr *ifa; int state, i; ASSERT_RTNL(); @@ -3488,16 +3399,6 @@ static int addrconf_ifdown(struct net_device *dev, int how) } - /* aggregate the system setting and interface setting */ - _keep_addr = net->ipv6.devconf_all->keep_addr_on_down; - if (!_keep_addr) - _keep_addr = idev->cnf.keep_addr_on_down; - - /* combine the user config with event to determine if permanent - * addresses are to be removed from address hash table - */ - keep_addr = !(how || _keep_addr <= 0); - /* Step 2: clear hash table */ for (i = 0; i < IN6_ADDR_HSIZE; i++) { struct hlist_head *h = &inet6_addr_lst[i]; @@ -3506,16 +3407,9 @@ static int addrconf_ifdown(struct net_device *dev, int how) restart: hlist_for_each_entry_rcu(ifa, h, addr_lst) { if (ifa->idev == idev) { + hlist_del_init_rcu(&ifa->addr_lst); addrconf_del_dad_work(ifa); - /* combined flag + permanent flag decide if - * address is retained on a down event - */ - if (!keep_addr || - !(ifa->flags & IFA_F_PERMANENT) || - addr_is_local(&ifa->addr)) { - hlist_del_init_rcu(&ifa->addr_lst); - goto restart; - } + goto restart; } } spin_unlock_bh(&addrconf_hash_lock); @@ -3549,54 +3443,31 @@ restart: write_lock_bh(&idev->lock); } - /* re-combine the user config with event to determine if permanent - * addresses are to be removed from the interface list - */ - keep_addr = (!how && _keep_addr > 0); - - INIT_LIST_HEAD(&del_list); - list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { + while (!list_empty(&idev->addr_list)) { + ifa = list_first_entry(&idev->addr_list, + struct inet6_ifaddr, if_list); addrconf_del_dad_work(ifa); - write_unlock_bh(&idev->lock); - spin_lock_bh(&ifa->lock); - - if (keep_addr && (ifa->flags & IFA_F_PERMANENT) && - !addr_is_local(&ifa->addr)) { - /* set state to skip the notifier below */ - state = INET6_IFADDR_STATE_DEAD; - ifa->state = 0; - if (!(ifa->flags & IFA_F_NODAD)) - ifa->flags |= IFA_F_TENTATIVE; - } else { - state = ifa->state; - ifa->state = INET6_IFADDR_STATE_DEAD; + list_del(&ifa->if_list); - list_del(&ifa->if_list); - list_add(&ifa->if_list, &del_list); - } + write_unlock_bh(&idev->lock); + spin_lock_bh(&ifa->lock); + state = ifa->state; + ifa->state = INET6_IFADDR_STATE_DEAD; spin_unlock_bh(&ifa->lock); if (state != INET6_IFADDR_STATE_DEAD) { __ipv6_ifa_notify(RTM_DELADDR, ifa); inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); } + in6_ifa_put(ifa); write_lock_bh(&idev->lock); } write_unlock_bh(&idev->lock); - /* now clean up addresses to be removed */ - while (!list_empty(&del_list)) { - ifa = list_first_entry(&del_list, - struct inet6_ifaddr, if_list); - list_del(&ifa->if_list); - - in6_ifa_put(ifa); - } - /* Step 5: Discard anycast and multicast list */ if (how) { ipv6_ac_destroy_dev(idev); @@ -4861,7 +4732,6 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_USE_OIF_ADDRS_ONLY] = cnf->use_oif_addrs_only; array[DEVCONF_DROP_UNICAST_IN_L2_MULTICAST] = cnf->drop_unicast_in_l2_multicast; array[DEVCONF_DROP_UNSOLICITED_NA] = cnf->drop_unsolicited_na; - array[DEVCONF_KEEP_ADDR_ON_DOWN] = cnf->keep_addr_on_down; } static inline size_t inet6_ifla6_size(void) @@ -5949,14 +5819,6 @@ static struct addrconf_sysctl_table .mode = 0644, .proc_handler = proc_dointvec, }, - { - .procname = "keep_addr_on_down", - .data = &ipv6_devconf.keep_addr_on_down, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec, - - }, { /* sentinel */ } -- cgit v1.2.3 From 5cf1cacb49aee39c3e02ae87068fc3c6430659b0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 21 Apr 2016 19:06:48 -0400 Subject: cgroup, cpuset: replace cpuset_post_attach_flush() with cgroup_subsys->post_attach callback Since e93ad19d0564 ("cpuset: make mm migration asynchronous"), cpuset kicks off asynchronous NUMA node migration if necessary during task migration and flushes it from cpuset_post_attach_flush() which is called at the end of __cgroup_procs_write(). This is to avoid performing migration with cgroup_threadgroup_rwsem write-locked which can lead to deadlock through dependency on kworker creation. memcg has a similar issue with charge moving, so let's convert it to an official callback rather than the current one-off cpuset specific function. This patch adds cgroup_subsys->post_attach callback and makes cpuset register cpuset_post_attach_flush() as its ->post_attach. The conversion is mostly one-to-one except that the new callback is called under cgroup_mutex. This is to guarantee that no other migration operations are started before ->post_attach callbacks are finished. cgroup_mutex is one of the outermost mutex in the system and has never been and shouldn't be a problem. We can add specialized synchronization around __cgroup_procs_write() but I don't think there's any noticeable benefit. Signed-off-by: Tejun Heo Cc: Li Zefan Cc: Johannes Weiner Cc: Michal Hocko Cc: # 4.4+ prerequisite for the next patch --- include/linux/cgroup-defs.h | 1 + include/linux/cpuset.h | 6 ------ kernel/cgroup.c | 7 +++++-- kernel/cpuset.c | 4 ++-- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 3e39ae5bc799..5b17de62c962 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -444,6 +444,7 @@ struct cgroup_subsys { int (*can_attach)(struct cgroup_taskset *tset); void (*cancel_attach)(struct cgroup_taskset *tset); void (*attach)(struct cgroup_taskset *tset); + void (*post_attach)(void); int (*can_fork)(struct task_struct *task); void (*cancel_fork)(struct task_struct *task); void (*fork)(struct task_struct *task); diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index fea160ee5803..85a868ccb493 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -137,8 +137,6 @@ static inline void set_mems_allowed(nodemask_t nodemask) task_unlock(current); } -extern void cpuset_post_attach_flush(void); - #else /* !CONFIG_CPUSETS */ static inline bool cpusets_enabled(void) { return false; } @@ -245,10 +243,6 @@ static inline bool read_mems_allowed_retry(unsigned int seq) return false; } -static inline void cpuset_post_attach_flush(void) -{ -} - #endif /* !CONFIG_CPUSETS */ #endif /* _LINUX_CPUSET_H */ diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 671dc05c0b0f..909a7d31ffd3 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2825,9 +2825,10 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off, bool threadgroup) { struct task_struct *tsk; + struct cgroup_subsys *ss; struct cgroup *cgrp; pid_t pid; - int ret; + int ssid, ret; if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0) return -EINVAL; @@ -2875,8 +2876,10 @@ out_unlock_rcu: rcu_read_unlock(); out_unlock_threadgroup: percpu_up_write(&cgroup_threadgroup_rwsem); + for_each_subsys(ss, ssid) + if (ss->post_attach) + ss->post_attach(); cgroup_kn_unlock(of->kn); - cpuset_post_attach_flush(); return ret ?: nbytes; } diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 00ab5c2b7c5b..1902956baba1 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include @@ -1016,7 +1015,7 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, } } -void cpuset_post_attach_flush(void) +static void cpuset_post_attach(void) { flush_workqueue(cpuset_migrate_mm_wq); } @@ -2087,6 +2086,7 @@ struct cgroup_subsys cpuset_cgrp_subsys = { .can_attach = cpuset_can_attach, .cancel_attach = cpuset_cancel_attach, .attach = cpuset_attach, + .post_attach = cpuset_post_attach, .bind = cpuset_bind, .legacy_cftypes = files, .early_init = true, -- cgit v1.2.3 From 264a0ae164bc0e9144bebcd25ff030d067b1a878 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 21 Apr 2016 19:09:02 -0400 Subject: memcg: relocate charge moving from ->attach to ->post_attach Hello, So, this ended up a lot simpler than I originally expected. I tested it lightly and it seems to work fine. Petr, can you please test these two patches w/o the lru drain drop patch and see whether the problem is gone? Thanks. ------ 8< ------ If charge moving is used, memcg performs relabeling of the affected pages from its ->attach callback which is called under both cgroup_threadgroup_rwsem and thus can't create new kthreads. This is fragile as various operations may depend on workqueues making forward progress which relies on the ability to create new kthreads. There's no reason to perform charge moving from ->attach which is deep in the task migration path. Move it to ->post_attach which is called after the actual migration is finished and cgroup_threadgroup_rwsem is dropped. * move_charge_struct->mm is added and ->can_attach is now responsible for pinning and recording the target mm. mem_cgroup_clear_mc() is updated accordingly. This also simplifies mem_cgroup_move_task(). * mem_cgroup_move_task() is now called from ->post_attach instead of ->attach. Signed-off-by: Tejun Heo Cc: Johannes Weiner Acked-by: Michal Hocko Debugged-and-tested-by: Petr Mladek Reported-by: Cyril Hrubis Reported-by: Johannes Weiner Fixes: 1ed1328792ff ("sched, cgroup: replace signal_struct->group_rwsem with a global percpu_rwsem") Cc: # 4.4+ --- mm/memcontrol.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 36db05fa8acb..fe787f5c41bd 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -207,6 +207,7 @@ static void mem_cgroup_oom_notify(struct mem_cgroup *memcg); /* "mc" and its members are protected by cgroup_mutex */ static struct move_charge_struct { spinlock_t lock; /* for from, to */ + struct mm_struct *mm; struct mem_cgroup *from; struct mem_cgroup *to; unsigned long flags; @@ -4667,6 +4668,8 @@ static void __mem_cgroup_clear_mc(void) static void mem_cgroup_clear_mc(void) { + struct mm_struct *mm = mc.mm; + /* * we must clear moving_task before waking up waiters at the end of * task migration. @@ -4676,7 +4679,10 @@ static void mem_cgroup_clear_mc(void) spin_lock(&mc.lock); mc.from = NULL; mc.to = NULL; + mc.mm = NULL; spin_unlock(&mc.lock); + + mmput(mm); } static int mem_cgroup_can_attach(struct cgroup_taskset *tset) @@ -4733,6 +4739,7 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset) VM_BUG_ON(mc.moved_swap); spin_lock(&mc.lock); + mc.mm = mm; mc.from = from; mc.to = memcg; mc.flags = move_flags; @@ -4742,8 +4749,9 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset) ret = mem_cgroup_precharge_mc(mm); if (ret) mem_cgroup_clear_mc(); + } else { + mmput(mm); } - mmput(mm); return ret; } @@ -4852,11 +4860,11 @@ put: /* get_mctgt_type() gets the page */ return ret; } -static void mem_cgroup_move_charge(struct mm_struct *mm) +static void mem_cgroup_move_charge(void) { struct mm_walk mem_cgroup_move_charge_walk = { .pmd_entry = mem_cgroup_move_charge_pte_range, - .mm = mm, + .mm = mc.mm, }; lru_add_drain_all(); @@ -4868,7 +4876,7 @@ static void mem_cgroup_move_charge(struct mm_struct *mm) atomic_inc(&mc.from->moving_account); synchronize_rcu(); retry: - if (unlikely(!down_read_trylock(&mm->mmap_sem))) { + if (unlikely(!down_read_trylock(&mc.mm->mmap_sem))) { /* * Someone who are holding the mmap_sem might be waiting in * waitq. So we cancel all extra charges, wake up all waiters, @@ -4885,23 +4893,16 @@ retry: * additional charge, the page walk just aborts. */ walk_page_range(0, ~0UL, &mem_cgroup_move_charge_walk); - up_read(&mm->mmap_sem); + up_read(&mc.mm->mmap_sem); atomic_dec(&mc.from->moving_account); } -static void mem_cgroup_move_task(struct cgroup_taskset *tset) +static void mem_cgroup_move_task(void) { - struct cgroup_subsys_state *css; - struct task_struct *p = cgroup_taskset_first(tset, &css); - struct mm_struct *mm = get_task_mm(p); - - if (mm) { - if (mc.to) - mem_cgroup_move_charge(mm); - mmput(mm); - } - if (mc.to) + if (mc.to) { + mem_cgroup_move_charge(); mem_cgroup_clear_mc(); + } } #else /* !CONFIG_MMU */ static int mem_cgroup_can_attach(struct cgroup_taskset *tset) @@ -4911,7 +4912,7 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset) static void mem_cgroup_cancel_attach(struct cgroup_taskset *tset) { } -static void mem_cgroup_move_task(struct cgroup_taskset *tset) +static void mem_cgroup_move_task(void) { } #endif @@ -5195,7 +5196,7 @@ struct cgroup_subsys memory_cgrp_subsys = { .css_reset = mem_cgroup_css_reset, .can_attach = mem_cgroup_can_attach, .cancel_attach = mem_cgroup_cancel_attach, - .attach = mem_cgroup_move_task, + .post_attach = mem_cgroup_move_task, .bind = mem_cgroup_bind, .dfl_cftypes = memory_files, .legacy_cftypes = mem_cgroup_legacy_files, -- cgit v1.2.3 From 3d6d30d60abb19ba9a20e53ce65b18a9c148fcd1 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Fri, 22 Apr 2016 13:09:13 +0200 Subject: cxgbi: fix uninitialized flowi6 ip6_route_output looks into different fields in the passed flowi6 structure, yet cxgbi passes garbage in nearly all those fields. Zero the structure out first. Fixes: fc8d0590d9142 ("libcxgbi: Add ipv6 api to driver") Signed-off-by: Jiri Benc Signed-off-by: David S. Miller --- drivers/scsi/cxgbi/libcxgbi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index f3bb7af4e984..ead83a24bcd1 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -688,6 +688,7 @@ static struct rt6_info *find_route_ipv6(const struct in6_addr *saddr, { struct flowi6 fl; + memset(&fl, 0, sizeof(fl)); if (saddr) memcpy(&fl.saddr, saddr, sizeof(struct in6_addr)); if (daddr) -- cgit v1.2.3 From 28a994fad95dd8475f04bd036e08a14aa8d125ea Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Mon, 25 Apr 2016 14:02:36 -0700 Subject: Input: twl6040-vibra - fix atomic schedule panic commit c6f39257c952 ("mfd: twl6040: Use regmap for register cache") did remove the private cache for the vibra control registers and replaced access within twl6040_get_vibralr_status() by calls to regmap. This is OK, as long as twl6040_get_vibralr_status() uses already cached values or is not called from interrupt context. But we call this in vibra_play() for checking that the vibrator is not configured for audio mode. The result is a "BUG: scheduling while atomic" if the first use of the twl6040 is a vibra effect, because the first fetch is by reading the twl6040 registers through (blocking) i2c and not from the cache. As soon as the regmap has cached the status, further calls are fine. The solution is to move the condition to the work() function which runs in context that can block. The original code returns -EBUSY, but the return value of ->play() functions is ignored anyways. Hence, we do not loose functionality by not returning an error but just reporting the issue to INFO loglevel. Tested-on: Pyra (omap5) prototype Signed-off-by: H. Nikolaus Schaller Signed-off-by: Dmitry Torokhov --- drivers/input/misc/twl6040-vibra.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 53e33fab3f7a..df3581f60628 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -181,6 +181,14 @@ static void vibra_play_work(struct work_struct *work) { struct vibra_info *info = container_of(work, struct vibra_info, play_work); + int ret; + + /* Do not allow effect, while the routing is set to use audio */ + ret = twl6040_get_vibralr_status(info->twl6040); + if (ret & TWL6040_VIBSEL) { + dev_info(info->dev, "Vibra is configured for audio\n"); + return; + } mutex_lock(&info->mutex); @@ -199,14 +207,6 @@ static int vibra_play(struct input_dev *input, void *data, struct ff_effect *effect) { struct vibra_info *info = input_get_drvdata(input); - int ret; - - /* Do not allow effect, while the routing is set to use audio */ - ret = twl6040_get_vibralr_status(info->twl6040); - if (ret & TWL6040_VIBSEL) { - dev_info(&input->dev, "Vibra is configured for audio\n"); - return -EBUSY; - } info->weak_speed = effect->u.rumble.weak_magnitude; info->strong_speed = effect->u.rumble.strong_magnitude; -- cgit v1.2.3 From 6984ab1ab35f422292b7781c65284038bcc0f6a6 Mon Sep 17 00:00:00 2001 From: Knut Wohlrab Date: Mon, 25 Apr 2016 14:08:25 -0700 Subject: Input: zforce_ts - fix dual touch recognition A wrong decoding of the touch coordinate message causes a wrong touch ID. Touch ID for dual touch must be 0 or 1. According to the actual Neonode nine byte touch coordinate coding, the state is transported in the lower nibble and the touch ID in the higher nibble of payload byte five. Signed-off-by: Knut Wohlrab Signed-off-by: Oleksij Rempel Signed-off-by: Dirk Behme Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/zforce_ts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c index 9bbadaaf6bc3..7b3845aa5983 100644 --- a/drivers/input/touchscreen/zforce_ts.c +++ b/drivers/input/touchscreen/zforce_ts.c @@ -370,8 +370,8 @@ static int zforce_touch_event(struct zforce_ts *ts, u8 *payload) point.coord_x = point.coord_y = 0; } - point.state = payload[9 * i + 5] & 0x03; - point.id = (payload[9 * i + 5] & 0xfc) >> 2; + point.state = payload[9 * i + 5] & 0x0f; + point.id = (payload[9 * i + 5] & 0xf0) >> 4; /* determine touch major, minor and orientation */ point.area_major = max(payload[9 * i + 6], -- cgit v1.2.3 From eb43335c409543506dd84b59f5c6bdd35cecf2c7 Mon Sep 17 00:00:00 2001 From: Nick Dyer Date: Mon, 25 Apr 2016 14:18:52 -0700 Subject: Input: atmel_mxt_ts - use mxt_acquire_irq in mxt_soft_reset If using IRQF_TRIGGER_FALLING, then there is a race here: if the reset completes before we enable the IRQ, then CHG is already low and touch will be broken. This has been seen on Chromebook Pixel 2. A workaround is to reconfig T18 COMMSCONFIG to enable the RETRIGEN bit using mxt-app: mxt-app -W -T18 44 mxt-app --backup Tested-by: Tom Rini Signed-off-by: Nick Dyer Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/atmel_mxt_ts.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 2160512e861a..5af7907d0af4 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -1093,6 +1093,19 @@ static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset, return 0; } +static int mxt_acquire_irq(struct mxt_data *data) +{ + int error; + + enable_irq(data->irq); + + error = mxt_process_messages_until_invalid(data); + if (error) + return error; + + return 0; +} + static int mxt_soft_reset(struct mxt_data *data) { struct device *dev = &data->client->dev; @@ -1111,7 +1124,7 @@ static int mxt_soft_reset(struct mxt_data *data) /* Ignore CHG line for 100ms after reset */ msleep(100); - enable_irq(data->irq); + mxt_acquire_irq(data); ret = mxt_wait_for_completion(data, &data->reset_completion, MXT_RESET_TIMEOUT); @@ -1466,19 +1479,6 @@ release_mem: return ret; } -static int mxt_acquire_irq(struct mxt_data *data) -{ - int error; - - enable_irq(data->irq); - - error = mxt_process_messages_until_invalid(data); - if (error) - return error; - - return 0; -} - static int mxt_get_info(struct mxt_data *data) { struct i2c_client *client = data->client; -- cgit v1.2.3 From 1becf03545a0859ceaaf9e8c2d9861882a71cb01 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Fri, 22 Apr 2016 19:53:59 -0700 Subject: cpufreq: intel_pstate: Fix processing for turbo activation ratio When the config TDP level is not nominal (level = 0), the MSR values for reading level 1 and level 2 ratios contain power in low 14 bits and actual ratio bits are at bits [23:16]. The current processing for level 1 and level 2 is wrong as there is no shift done to get actual ratio. Fixes: 6a35fc2d6c22 (cpufreq: intel_pstate: get P1 from TAR when available) Signed-off-by: Srinivas Pandruvada Cc: 4.4+ # 4.4+ Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 30fe323c4551..f502d5b90c25 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -813,6 +813,11 @@ static int core_get_max_pstate(void) if (err) goto skip_tar; + /* For level 1 and 2, bits[23:16] contain the ratio */ + if (tdp_ctrl) + tdp_ratio >>= 16; + + tdp_ratio &= 0xff; /* ratios are only 8 bits long */ if (tdp_ratio - 1 == tar) { max_pstate = tar; pr_debug("max_pstate=TAC %x\n", max_pstate); -- cgit v1.2.3 From f5515f9cdff136dc32517d4b81fe2b9091237b4a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 25 Apr 2016 16:08:30 +0200 Subject: arm64: dts: r8a7795: Don't disable referenced optional scif clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clk_get() on a disabled clock node will return -EPROBE_DEFER, which can cause drivers to be deferred forever if such clocks are referenced in their devices' clocks properties. Update the disabled external scif clock node so that it is not disabled to prevent this. Reported-by: Jürg Billeter Signed-off-by: Geert Uytterhoeven [simon: fix for v4.6 extracted from a larger patch targeted at v4.7] Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index a7315ebe3883..706d2426024f 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -120,7 +120,6 @@ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; - status = "disabled"; }; soc { -- cgit v1.2.3 From 9c573de3283af007ea11c17bde1e4568d9417328 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 25 Apr 2016 16:52:38 -0700 Subject: MD: make bio mergeable blk_queue_split marks bio unmergeable, which makes sense for normal bio. But if dispatching the bio to underlayer disk, the blk_queue_split checks are invalid, hence it's possible the bio becomes mergeable. In the reported bug, this bug causes trim against raid0 performance slash https://bugzilla.kernel.org/show_bug.cgi?id=117051 Reported-and-tested-by: Park Ju Hyung Fixes: 6ac45aeb6bca(block: avoid to merge splitted bio) Cc: stable@vger.kernel.org (v4.3+) Cc: Ming Lei Cc: Neil Brown Reviewed-by: Jens Axboe Signed-off-by: Shaohua Li --- drivers/md/md.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/md/md.c b/drivers/md/md.c index 194580fba7fd..14d3b37944df 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -284,6 +284,8 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio) * go away inside make_request */ sectors = bio_sectors(bio); + /* bio could be mergeable after passing to underlayer */ + bio->bi_rw &= ~REQ_NOMERGE; mddev->pers->make_request(mddev, bio); cpu = part_stat_lock(); -- cgit v1.2.3 From 9f5db53507b6607dc1b5d59547097966c0e71047 Mon Sep 17 00:00:00 2001 From: Ivan Babrou Date: Sat, 23 Apr 2016 12:58:03 +0000 Subject: net: dummy: remove note about being Y by default Signed-off-by: Ivan Babrou Signed-off-by: David S. Miller --- drivers/net/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a24c18eee598..befd67df08e1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -62,9 +62,8 @@ config DUMMY this device is consigned into oblivion) with a configurable IP address. It is most commonly used in order to make your currently inactive SLIP address seem like a real address for local programs. - If you use SLIP or PPP, you might want to say Y here. Since this - thing often comes in handy, the default is Y. It won't enlarge your - kernel either. What a deal. Read about it in the Network + If you use SLIP or PPP, you might want to say Y here. It won't + enlarge your kernel. What a deal. Read about it in the Network Administrator's Guide, available from . -- cgit v1.2.3 From fc96256c906362e845d848d0f6a6354450059e81 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 23 Apr 2016 11:35:46 -0700 Subject: net/mlx4_en: fix spurious timestamping callbacks When multiple skb are TX-completed in a row, we might incorrectly keep a timestamp of a prior skb and cause extra work. Fixes: ec693d47010e8 ("net/mlx4_en: Add HW timestamping (TS) support") Signed-off-by: Eric Dumazet Cc: Willem de Bruijn Reviewed-by: Eran Ben Elisha Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index c0d7b7296236..a386f047c1af 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -405,7 +405,6 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev, u32 packets = 0; u32 bytes = 0; int factor = priv->cqe_factor; - u64 timestamp = 0; int done = 0; int budget = priv->tx_work_limit; u32 last_nr_txbb; @@ -445,9 +444,12 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev, new_index = be16_to_cpu(cqe->wqe_index) & size_mask; do { + u64 timestamp = 0; + txbbs_skipped += last_nr_txbb; ring_index = (ring_index + last_nr_txbb) & size_mask; - if (ring->tx_info[ring_index].ts_requested) + + if (unlikely(ring->tx_info[ring_index].ts_requested)) timestamp = mlx4_en_get_cqe_ts(cqe); /* free next descriptor */ -- cgit v1.2.3 From 037e119738120c1cdc460c6ae33871c3000531f3 Mon Sep 17 00:00:00 2001 From: Conrad Kostecki Date: Tue, 26 Apr 2016 10:08:10 +0200 Subject: ALSA: hda - Add dock support for ThinkPad X260 Fixes audio output on a ThinkPad X260, when using Lenovo CES 2013 docking station series (basic, pro, ultra). Signed-off-by: Conrad Kostecki Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 810bceee4fd2..ac4490a96863 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5584,6 +5584,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK), + SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK), SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE), SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), -- cgit v1.2.3 From bb03ed216370cb021f377f923471e56d1de3ff5d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Apr 2016 16:39:17 +0200 Subject: ALSA: hda - Update BCLK also at hotplug for i915 HSW/BDW The recent bug report suggests that BCLK setup for i915 HSW/BDW needs to be updated at each HDMI hotplug, not only at initialization and resume. That is, we need to update HSW_EM4 and HSW_EM5 registers at ELD notification, too. Otherwise the HDMI audio may be out of sync and played in a wrong pitch. However, the HDA codec driver has no access to the controller registers, and currently the code managing these registers is in hda_intel.c, i.e. local to the controller driver. For allowing the explicit BCLK update from the codec driver, as in this patch, the former haswell_set_bclk() in hda_intel.c is moved to hdac_i915.c and exposed as snd_hdac_i915_set_bclk(). This is called from both the HDA controller driver and intel_pin_eld_notify() in HDMI codec driver. Along with this change, snd_hdac_get_display_clk() gets dropped as it's no longer used. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91410 Cc: # v4.5+ Signed-off-by: Takashi Iwai --- include/sound/hda_i915.h | 5 ++-- sound/hda/hdac_i915.c | 62 ++++++++++++++++++++++++++++++++++++++-------- sound/pci/hda/hda_intel.c | 56 +++-------------------------------------- sound/pci/hda/patch_hdmi.c | 1 + 4 files changed, 58 insertions(+), 66 deletions(-) diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h index fa341fcb5829..f5842bcd9c94 100644 --- a/include/sound/hda_i915.h +++ b/include/sound/hda_i915.h @@ -9,7 +9,7 @@ #ifdef CONFIG_SND_HDA_I915 int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable); int snd_hdac_display_power(struct hdac_bus *bus, bool enable); -int snd_hdac_get_display_clk(struct hdac_bus *bus); +void snd_hdac_i915_set_bclk(struct hdac_bus *bus); int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate); int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid, bool *audio_enabled, char *buffer, int max_bytes); @@ -25,9 +25,8 @@ static inline int snd_hdac_display_power(struct hdac_bus *bus, bool enable) { return 0; } -static inline int snd_hdac_get_display_clk(struct hdac_bus *bus) +static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus) { - return 0; } static inline int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate) diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index 54babe1c0b16..607bbeaebddf 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -20,6 +20,7 @@ #include #include #include +#include static struct i915_audio_component *hdac_acomp; @@ -97,26 +98,65 @@ int snd_hdac_display_power(struct hdac_bus *bus, bool enable) } EXPORT_SYMBOL_GPL(snd_hdac_display_power); +#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \ + ((pci)->device == 0x0c0c) || \ + ((pci)->device == 0x0d0c) || \ + ((pci)->device == 0x160c)) + /** - * snd_hdac_get_display_clk - Get CDCLK in kHz + * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW * @bus: HDA core bus * - * This function is supposed to be used only by a HD-audio controller - * driver that needs the interaction with i915 graphics. + * Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK + * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value) + * are used to convert CDClk (Core Display Clock) to 24MHz BCLK: + * BCLK = CDCLK * M / N + * The values will be lost when the display power well is disabled and need to + * be restored to avoid abnormal playback speed. * - * This function queries CDCLK value in kHz from the graphics driver and - * returns the value. A negative code is returned in error. + * Call this function at initializing and changing power well, as well as + * at ELD notifier for the hotplug. */ -int snd_hdac_get_display_clk(struct hdac_bus *bus) +void snd_hdac_i915_set_bclk(struct hdac_bus *bus) { struct i915_audio_component *acomp = bus->audio_component; + struct pci_dev *pci = to_pci_dev(bus->dev); + int cdclk_freq; + unsigned int bclk_m, bclk_n; + + if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq) + return; /* only for i915 binding */ + if (!CONTROLLER_IN_GPU(pci)) + return; /* only HSW/BDW */ + + cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev); + switch (cdclk_freq) { + case 337500: + bclk_m = 16; + bclk_n = 225; + break; + + case 450000: + default: /* default CDCLK 450MHz */ + bclk_m = 4; + bclk_n = 75; + break; + + case 540000: + bclk_m = 4; + bclk_n = 90; + break; + + case 675000: + bclk_m = 8; + bclk_n = 225; + break; + } - if (!acomp || !acomp->ops) - return -ENODEV; - - return acomp->ops->get_cdclk_freq(acomp->dev); + snd_hdac_chip_writew(bus, HSW_EM4, bclk_m); + snd_hdac_chip_writew(bus, HSW_EM5, bclk_n); } -EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk); +EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk); /* There is a fixed mapping between audio pin node and display port * on current Intel platforms: diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 637b8a0e2a91..9a0d1445ca5c 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -857,50 +857,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) #define azx_del_card_list(chip) /* NOP */ #endif /* CONFIG_PM */ -/* Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK - * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value) - * are used to convert CDClk (Core Display Clock) to 24MHz BCLK: - * BCLK = CDCLK * M / N - * The values will be lost when the display power well is disabled and need to - * be restored to avoid abnormal playback speed. - */ -static void haswell_set_bclk(struct hda_intel *hda) -{ - struct azx *chip = &hda->chip; - int cdclk_freq; - unsigned int bclk_m, bclk_n; - - if (!hda->need_i915_power) - return; - - cdclk_freq = snd_hdac_get_display_clk(azx_bus(chip)); - switch (cdclk_freq) { - case 337500: - bclk_m = 16; - bclk_n = 225; - break; - - case 450000: - default: /* default CDCLK 450MHz */ - bclk_m = 4; - bclk_n = 75; - break; - - case 540000: - bclk_m = 4; - bclk_n = 90; - break; - - case 675000: - bclk_m = 8; - bclk_n = 225; - break; - } - - azx_writew(chip, HSW_EM4, bclk_m); - azx_writew(chip, HSW_EM5, bclk_n); -} - #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) /* * power management @@ -958,7 +914,7 @@ static int azx_resume(struct device *dev) if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL && hda->need_i915_power) { snd_hdac_display_power(azx_bus(chip), true); - haswell_set_bclk(hda); + snd_hdac_i915_set_bclk(azx_bus(chip)); } if (chip->msi) if (pci_enable_msi(pci) < 0) @@ -1058,7 +1014,7 @@ static int azx_runtime_resume(struct device *dev) bus = azx_bus(chip); if (hda->need_i915_power) { snd_hdac_display_power(bus, true); - haswell_set_bclk(hda); + snd_hdac_i915_set_bclk(bus); } else { /* toggle codec wakeup bit for STATESTS read */ snd_hdac_set_codec_wakeup(bus, true); @@ -1796,12 +1752,8 @@ static int azx_first_init(struct azx *chip) /* initialize chip */ azx_init_pci(chip); - if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { - struct hda_intel *hda; - - hda = container_of(chip, struct hda_intel, chip); - haswell_set_bclk(hda); - } + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) + snd_hdac_i915_set_bclk(bus); hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0); diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 40933aa33afe..1483f85999ec 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -2232,6 +2232,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port) if (atomic_read(&(codec)->core.in_pm)) return; + snd_hdac_i915_set_bclk(&codec->bus->core); check_presence_and_report(codec, pin_nid); } -- cgit v1.2.3 From 978fa436231a834dc686292efc7d944d9013e035 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 22 Apr 2016 16:18:02 +0100 Subject: drivers: firmware: psci: unify enable-method binding on ARM {64,32}-bit systems Currently ARM CPUs DT bindings allows different enable-method value for PSCI based systems. On ARM 64-bit this property is required and must be "psci" while on ARM 32-bit systems this property is optional and must be "arm,psci" if present. However, "arm,psci" has always been the compatible string for the PSCI node, and was never intended to be the enable-method. So this is a bug in the binding and not a deliberate attempt at specifying 32-bit differently. This is problematic if 32-bit OS is run on 64-bit system which has "psci" as enable-method rather than the expected "arm,psci". So let's unify the value into "psci" and remove support for "arm,psci" before it finds any users. Reported-by: Soby Mathew Cc: Rob Herring Acked-by: Mark Rutland Acked-by: Lorenzo Pieralisi Signed-off-by: Sudeep Holla Signed-off-by: Arnd Bergmann --- Documentation/devicetree/bindings/arm/cpus.txt | 1 - drivers/firmware/psci.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index ccc62f145306..3f0cbbb8395f 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -192,7 +192,6 @@ nodes to be present and contain the properties described below. can be one of: "allwinner,sun6i-a31" "allwinner,sun8i-a23" - "arm,psci" "arm,realview-smp" "brcm,bcm-nsp-smp" "brcm,brahma-b15" diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index 11bfee8b79a9..b5d05807e6ec 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -360,7 +360,7 @@ static struct cpuidle_ops psci_cpuidle_ops __initdata = { .init = psci_dt_cpu_init_idle, }; -CPUIDLE_METHOD_OF_DECLARE(psci, "arm,psci", &psci_cpuidle_ops); +CPUIDLE_METHOD_OF_DECLARE(psci, "psci", &psci_cpuidle_ops); #endif #endif -- cgit v1.2.3 From 346c09f80459a3ad97df1816d6d606169a51001a Mon Sep 17 00:00:00 2001 From: Roman Pen Date: Tue, 26 Apr 2016 13:15:35 +0200 Subject: workqueue: fix ghost PENDING flag while doing MQ IO The bug in a workqueue leads to a stalled IO request in MQ ctx->rq_list with the following backtrace: [ 601.347452] INFO: task kworker/u129:5:1636 blocked for more than 120 seconds. [ 601.347574] Tainted: G O 4.4.5-1-storage+ #6 [ 601.347651] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 601.348142] kworker/u129:5 D ffff880803077988 0 1636 2 0x00000000 [ 601.348519] Workqueue: ibnbd_server_fileio_wq ibnbd_dev_file_submit_io_worker [ibnbd_server] [ 601.348999] ffff880803077988 ffff88080466b900 ffff8808033f9c80 ffff880803078000 [ 601.349662] ffff880807c95000 7fffffffffffffff ffffffff815b0920 ffff880803077ad0 [ 601.350333] ffff8808030779a0 ffffffff815b01d5 0000000000000000 ffff880803077a38 [ 601.350965] Call Trace: [ 601.351203] [] ? bit_wait+0x60/0x60 [ 601.351444] [] schedule+0x35/0x80 [ 601.351709] [] schedule_timeout+0x192/0x230 [ 601.351958] [] ? blk_flush_plug_list+0xc7/0x220 [ 601.352208] [] ? ktime_get+0x37/0xa0 [ 601.352446] [] ? bit_wait+0x60/0x60 [ 601.352688] [] io_schedule_timeout+0xa4/0x110 [ 601.352951] [] ? _raw_spin_unlock_irqrestore+0xe/0x10 [ 601.353196] [] bit_wait_io+0x1b/0x70 [ 601.353440] [] __wait_on_bit+0x5d/0x90 [ 601.353689] [] wait_on_page_bit+0xc0/0xd0 [ 601.353958] [] ? autoremove_wake_function+0x40/0x40 [ 601.354200] [] __filemap_fdatawait_range+0xe4/0x140 [ 601.354441] [] filemap_fdatawait_range+0x14/0x30 [ 601.354688] [] filemap_write_and_wait_range+0x3f/0x70 [ 601.354932] [] blkdev_fsync+0x1b/0x50 [ 601.355193] [] vfs_fsync_range+0x49/0xa0 [ 601.355432] [] blkdev_write_iter+0xca/0x100 [ 601.355679] [] __vfs_write+0xaa/0xe0 [ 601.355925] [] vfs_write+0xa9/0x1a0 [ 601.356164] [] kernel_write+0x38/0x50 The underlying device is a null_blk, with default parameters: queue_mode = MQ submit_queues = 1 Verification that nullb0 has something inflight: root@pserver8:~# cat /sys/block/nullb0/inflight 0 1 root@pserver8:~# find /sys/block/nullb0/mq/0/cpu* -name rq_list -print -exec cat {} \; ... /sys/block/nullb0/mq/0/cpu2/rq_list CTX pending: ffff8838038e2400 ... During debug it became clear that stalled request is always inserted in the rq_list from the following path: save_stack_trace_tsk + 34 blk_mq_insert_requests + 231 blk_mq_flush_plug_list + 281 blk_flush_plug_list + 199 wait_on_page_bit + 192 __filemap_fdatawait_range + 228 filemap_fdatawait_range + 20 filemap_write_and_wait_range + 63 blkdev_fsync + 27 vfs_fsync_range + 73 blkdev_write_iter + 202 __vfs_write + 170 vfs_write + 169 kernel_write + 56 So blk_flush_plug_list() was called with from_schedule == true. If from_schedule is true, that means that finally blk_mq_insert_requests() offloads execution of __blk_mq_run_hw_queue() and uses kblockd workqueue, i.e. it calls kblockd_schedule_delayed_work_on(). That means, that we race with another CPU, which is about to execute __blk_mq_run_hw_queue() work. Further debugging shows the following traces from different CPUs: CPU#0 CPU#1 ---------------------------------- ------------------------------- reqeust A inserted STORE hctx->ctx_map[0] bit marked kblockd_schedule...() returns 1 request B inserted STORE hctx->ctx_map[1] bit marked kblockd_schedule...() returns 0 *** WORK PENDING bit is cleared *** flush_busy_ctxs() is executed, but bit 1, set by CPU#1, is not observed As a result request B pended forever. This behaviour can be explained by speculative LOAD of hctx->ctx_map on CPU#0, which is reordered with clear of PENDING bit and executed _before_ actual STORE of bit 1 on CPU#1. The proper fix is an explicit full barrier , which guarantees that clear of PENDING bit is to be executed before all possible speculative LOADS or STORES inside actual work function. Signed-off-by: Roman Pen Cc: Gioh Kim Cc: Michael Wang Cc: Tejun Heo Cc: Jens Axboe Cc: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Tejun Heo --- kernel/workqueue.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 16e13d8628a3..801a698564d4 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -666,6 +666,35 @@ static void set_work_pool_and_clear_pending(struct work_struct *work, */ smp_wmb(); set_work_data(work, (unsigned long)pool_id << WORK_OFFQ_POOL_SHIFT, 0); + /* + * The following mb guarantees that previous clear of a PENDING bit + * will not be reordered with any speculative LOADS or STORES from + * work->current_func, which is executed afterwards. This possible + * reordering can lead to a missed execution on attempt to qeueue + * the same @work. E.g. consider this case: + * + * CPU#0 CPU#1 + * ---------------------------- -------------------------------- + * + * 1 STORE event_indicated + * 2 queue_work_on() { + * 3 test_and_set_bit(PENDING) + * 4 } set_..._and_clear_pending() { + * 5 set_work_data() # clear bit + * 6 smp_mb() + * 7 work->current_func() { + * 8 LOAD event_indicated + * } + * + * Without an explicit full barrier speculative LOAD on line 8 can + * be executed before CPU#0 does STORE on line 1. If that happens, + * CPU#0 observes the PENDING bit is still set and new execution of + * a @work is not queued in a hope, that CPU#1 will eventually + * finish the queued @work. Meanwhile CPU#1 does not see + * event_indicated is set, because speculative LOAD was executed + * before actual STORE. + */ + smp_mb(); } static void clear_work_data(struct work_struct *work) -- cgit v1.2.3 From 6a923934c33c750a595868af6bef5f1a1fa90054 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Apr 2016 11:47:41 -0400 Subject: Revert "ipv6: Revert optional address flusing on ifdown." This reverts commit 841645b5f2dfceac69b78fcd0c9050868d41ea61. Ok, this puts the feature back. I've decided to apply David A.'s bug fix and run with that rather than make everyone wait another whole release for this feature. Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 9 ++ include/linux/ipv6.h | 1 + include/uapi/linux/ipv6.h | 1 + net/ipv6/addrconf.c | 162 ++++++++++++++++++++++++++++++--- 4 files changed, 161 insertions(+), 12 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index e0ac25210f7c..b183e2b606c8 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1568,6 +1568,15 @@ temp_prefered_lft - INTEGER Preferred lifetime (in seconds) for temporary addresses. Default: 86400 (1 day) +keep_addr_on_down - INTEGER + Keep all IPv6 addresses on an interface down event. If set static + global addresses with no expiration time are not flushed. + >0 : enabled + 0 : system default + <0 : disabled + + Default: 0 (addresses are removed) + max_desync_factor - INTEGER Maximum value for DESYNC_FACTOR, which is a random value that ensures that clients don't synchronize with each diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 4b2267e1b7c3..7edc14fb66b6 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -62,6 +62,7 @@ struct ipv6_devconf { struct in6_addr secret; } stable_secret; __s32 use_oif_addrs_only; + __s32 keep_addr_on_down; void *sysctl; }; diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h index ec117b65d5a5..395876060f50 100644 --- a/include/uapi/linux/ipv6.h +++ b/include/uapi/linux/ipv6.h @@ -176,6 +176,7 @@ enum { DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN, DEVCONF_DROP_UNICAST_IN_L2_MULTICAST, DEVCONF_DROP_UNSOLICITED_NA, + DEVCONF_KEEP_ADDR_ON_DOWN, DEVCONF_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d77ba395d593..23cec53b568a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -216,6 +216,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { }, .use_oif_addrs_only = 0, .ignore_routes_with_linkdown = 0, + .keep_addr_on_down = 0, }; static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { @@ -260,6 +261,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { }, .use_oif_addrs_only = 0, .ignore_routes_with_linkdown = 0, + .keep_addr_on_down = 0, }; /* Check if a valid qdisc is available */ @@ -3174,6 +3176,81 @@ static void addrconf_gre_config(struct net_device *dev) } #endif +#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) +/* If the host route is cached on the addr struct make sure it is associated + * with the proper table. e.g., enslavement can change and if so the cached + * host route needs to move to the new table. + */ +static void l3mdev_check_host_rt(struct inet6_dev *idev, + struct inet6_ifaddr *ifp) +{ + if (ifp->rt) { + u32 tb_id = l3mdev_fib_table(idev->dev) ? : RT6_TABLE_LOCAL; + + if (tb_id != ifp->rt->rt6i_table->tb6_id) { + ip6_del_rt(ifp->rt); + ifp->rt = NULL; + } + } +} +#else +static void l3mdev_check_host_rt(struct inet6_dev *idev, + struct inet6_ifaddr *ifp) +{ +} +#endif + +static int fixup_permanent_addr(struct inet6_dev *idev, + struct inet6_ifaddr *ifp) +{ + l3mdev_check_host_rt(idev, ifp); + + if (!ifp->rt) { + struct rt6_info *rt; + + rt = addrconf_dst_alloc(idev, &ifp->addr, false); + if (unlikely(IS_ERR(rt))) + return PTR_ERR(rt); + + ifp->rt = rt; + } + + if (!(ifp->flags & IFA_F_NOPREFIXROUTE)) { + addrconf_prefix_route(&ifp->addr, ifp->prefix_len, + idev->dev, 0, 0); + } + + addrconf_dad_start(ifp); + + return 0; +} + +static void addrconf_permanent_addr(struct net_device *dev) +{ + struct inet6_ifaddr *ifp, *tmp; + struct inet6_dev *idev; + + idev = __in6_dev_get(dev); + if (!idev) + return; + + write_lock_bh(&idev->lock); + + list_for_each_entry_safe(ifp, tmp, &idev->addr_list, if_list) { + if ((ifp->flags & IFA_F_PERMANENT) && + fixup_permanent_addr(idev, ifp) < 0) { + write_unlock_bh(&idev->lock); + ipv6_del_addr(ifp); + write_lock_bh(&idev->lock); + + net_info_ratelimited("%s: Failed to add prefix route for address %pI6c; dropping\n", + idev->dev->name, &ifp->addr); + } + } + + write_unlock_bh(&idev->lock); +} + static int addrconf_notify(struct notifier_block *this, unsigned long event, void *ptr) { @@ -3260,6 +3337,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, run_pending = 1; } + /* restore routes for permanent addresses */ + addrconf_permanent_addr(dev); + switch (dev->type) { #if IS_ENABLED(CONFIG_IPV6_SIT) case ARPHRD_SIT: @@ -3368,11 +3448,20 @@ static void addrconf_type_change(struct net_device *dev, unsigned long event) ipv6_mc_unmap(idev); } +static bool addr_is_local(const struct in6_addr *addr) +{ + return ipv6_addr_type(addr) & + (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); +} + static int addrconf_ifdown(struct net_device *dev, int how) { struct net *net = dev_net(dev); struct inet6_dev *idev; - struct inet6_ifaddr *ifa; + struct inet6_ifaddr *ifa, *tmp; + struct list_head del_list; + int _keep_addr; + bool keep_addr; int state, i; ASSERT_RTNL(); @@ -3399,6 +3488,16 @@ static int addrconf_ifdown(struct net_device *dev, int how) } + /* aggregate the system setting and interface setting */ + _keep_addr = net->ipv6.devconf_all->keep_addr_on_down; + if (!_keep_addr) + _keep_addr = idev->cnf.keep_addr_on_down; + + /* combine the user config with event to determine if permanent + * addresses are to be removed from address hash table + */ + keep_addr = !(how || _keep_addr <= 0); + /* Step 2: clear hash table */ for (i = 0; i < IN6_ADDR_HSIZE; i++) { struct hlist_head *h = &inet6_addr_lst[i]; @@ -3407,9 +3506,16 @@ static int addrconf_ifdown(struct net_device *dev, int how) restart: hlist_for_each_entry_rcu(ifa, h, addr_lst) { if (ifa->idev == idev) { - hlist_del_init_rcu(&ifa->addr_lst); addrconf_del_dad_work(ifa); - goto restart; + /* combined flag + permanent flag decide if + * address is retained on a down event + */ + if (!keep_addr || + !(ifa->flags & IFA_F_PERMANENT) || + addr_is_local(&ifa->addr)) { + hlist_del_init_rcu(&ifa->addr_lst); + goto restart; + } } } spin_unlock_bh(&addrconf_hash_lock); @@ -3443,31 +3549,54 @@ restart: write_lock_bh(&idev->lock); } - while (!list_empty(&idev->addr_list)) { - ifa = list_first_entry(&idev->addr_list, - struct inet6_ifaddr, if_list); - addrconf_del_dad_work(ifa); + /* re-combine the user config with event to determine if permanent + * addresses are to be removed from the interface list + */ + keep_addr = (!how && _keep_addr > 0); - list_del(&ifa->if_list); + INIT_LIST_HEAD(&del_list); + list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { + addrconf_del_dad_work(ifa); write_unlock_bh(&idev->lock); - spin_lock_bh(&ifa->lock); - state = ifa->state; - ifa->state = INET6_IFADDR_STATE_DEAD; + + if (keep_addr && (ifa->flags & IFA_F_PERMANENT) && + !addr_is_local(&ifa->addr)) { + /* set state to skip the notifier below */ + state = INET6_IFADDR_STATE_DEAD; + ifa->state = 0; + if (!(ifa->flags & IFA_F_NODAD)) + ifa->flags |= IFA_F_TENTATIVE; + } else { + state = ifa->state; + ifa->state = INET6_IFADDR_STATE_DEAD; + + list_del(&ifa->if_list); + list_add(&ifa->if_list, &del_list); + } + spin_unlock_bh(&ifa->lock); if (state != INET6_IFADDR_STATE_DEAD) { __ipv6_ifa_notify(RTM_DELADDR, ifa); inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); } - in6_ifa_put(ifa); write_lock_bh(&idev->lock); } write_unlock_bh(&idev->lock); + /* now clean up addresses to be removed */ + while (!list_empty(&del_list)) { + ifa = list_first_entry(&del_list, + struct inet6_ifaddr, if_list); + list_del(&ifa->if_list); + + in6_ifa_put(ifa); + } + /* Step 5: Discard anycast and multicast list */ if (how) { ipv6_ac_destroy_dev(idev); @@ -4732,6 +4861,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_USE_OIF_ADDRS_ONLY] = cnf->use_oif_addrs_only; array[DEVCONF_DROP_UNICAST_IN_L2_MULTICAST] = cnf->drop_unicast_in_l2_multicast; array[DEVCONF_DROP_UNSOLICITED_NA] = cnf->drop_unsolicited_na; + array[DEVCONF_KEEP_ADDR_ON_DOWN] = cnf->keep_addr_on_down; } static inline size_t inet6_ifla6_size(void) @@ -5819,6 +5949,14 @@ static struct addrconf_sysctl_table .mode = 0644, .proc_handler = proc_dointvec, }, + { + .procname = "keep_addr_on_down", + .data = &ipv6_devconf.keep_addr_on_down, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + + }, { /* sentinel */ } -- cgit v1.2.3 From 38bd10c447f8e8980753149a8a65108159871df5 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 21 Apr 2016 20:56:12 -0700 Subject: net: ipv6: Delete host routes on an ifdown It was a simple idea -- save IPv6 configured addresses on a link down so that IPv6 behaves similar to IPv4. As always the devil is in the details and the IPv6 stack as too many behavioral differences from IPv4 making the simple idea more complicated than it needs to be. The current implementation for keeping IPv6 addresses can panic or spit out a warning in one of many paths: 1. IPv6 route gets an IPv4 route as its 'next' which causes a panic in rt6_fill_node while handling a route dump request. 2. rt->dst.obsolete is set to DST_OBSOLETE_DEAD hitting the WARN_ON in fib6_del 3. Panic in fib6_purge_rt because rt6i_ref count is not 1. The root cause of all these is references related to the host route for an address that is retained. So, this patch deletes the host route every time the ifdown loop runs. Since the host route is deleted and will be re-generated an up there is no longer a need for the l3mdev fix up. On the 'admin up' side move addrconf_permanent_addr into the NETDEV_UP event handling so that it runs only once versus on UP and CHANGE events. All of the current panics and warnings appear to be related to addresses on the loopback device, but given the catastrophic nature when a bug is triggered this patch takes the conservative approach and evicts all host routes rather than trying to determine when it can be re-used and when it can not. That can be a later optimizaton if desired. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 48 +++++++++++++++--------------------------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 23cec53b568a..8ec4b3089e20 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3176,35 +3176,9 @@ static void addrconf_gre_config(struct net_device *dev) } #endif -#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) -/* If the host route is cached on the addr struct make sure it is associated - * with the proper table. e.g., enslavement can change and if so the cached - * host route needs to move to the new table. - */ -static void l3mdev_check_host_rt(struct inet6_dev *idev, - struct inet6_ifaddr *ifp) -{ - if (ifp->rt) { - u32 tb_id = l3mdev_fib_table(idev->dev) ? : RT6_TABLE_LOCAL; - - if (tb_id != ifp->rt->rt6i_table->tb6_id) { - ip6_del_rt(ifp->rt); - ifp->rt = NULL; - } - } -} -#else -static void l3mdev_check_host_rt(struct inet6_dev *idev, - struct inet6_ifaddr *ifp) -{ -} -#endif - static int fixup_permanent_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) { - l3mdev_check_host_rt(idev, ifp); - if (!ifp->rt) { struct rt6_info *rt; @@ -3304,6 +3278,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, break; if (event == NETDEV_UP) { + /* restore routes for permanent addresses */ + addrconf_permanent_addr(dev); + if (!addrconf_qdisc_ok(dev)) { /* device is not ready yet. */ pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n", @@ -3337,9 +3314,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, run_pending = 1; } - /* restore routes for permanent addresses */ - addrconf_permanent_addr(dev); - switch (dev->type) { #if IS_ENABLED(CONFIG_IPV6_SIT) case ARPHRD_SIT: @@ -3556,6 +3530,8 @@ restart: INIT_LIST_HEAD(&del_list); list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { + struct rt6_info *rt = NULL; + addrconf_del_dad_work(ifa); write_unlock_bh(&idev->lock); @@ -3568,6 +3544,9 @@ restart: ifa->state = 0; if (!(ifa->flags & IFA_F_NODAD)) ifa->flags |= IFA_F_TENTATIVE; + + rt = ifa->rt; + ifa->rt = NULL; } else { state = ifa->state; ifa->state = INET6_IFADDR_STATE_DEAD; @@ -3578,6 +3557,9 @@ restart: spin_unlock_bh(&ifa->lock); + if (rt) + ip6_del_rt(rt); + if (state != INET6_IFADDR_STATE_DEAD) { __ipv6_ifa_notify(RTM_DELADDR, ifa); inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); @@ -5343,10 +5325,10 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) if (rt) ip6_del_rt(rt); } - dst_hold(&ifp->rt->dst); - - ip6_del_rt(ifp->rt); - + if (ifp->rt) { + dst_hold(&ifp->rt->dst); + ip6_del_rt(ifp->rt); + } rt_genid_bump_ipv6(net); break; } -- cgit v1.2.3 From 42235f80ab205bf5020cf33cb3e94455410abe36 Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Tue, 26 Apr 2016 17:55:38 +0300 Subject: IB/core: Don't drain non-existent rq queue-pair The drain_rq function expects a normal receive qp to drain. A qp can only have either a normal rq or an srq. If there is an srq, there is no rq to drain. Until the API supports draining SRQs, simply skip draining the rq when the qp has an srq attached. Fixes: 765d67748bcf ("IB: new common API for draining queues") Signed-off-by: Sagi Grimberg Signed-off-by: Doug Ledford --- drivers/infiniband/core/verbs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 15b8adbf39c0..b65b3541e732 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1860,6 +1860,7 @@ EXPORT_SYMBOL(ib_drain_rq); void ib_drain_qp(struct ib_qp *qp) { ib_drain_sq(qp); - ib_drain_rq(qp); + if (!qp->srq) + ib_drain_rq(qp); } EXPORT_SYMBOL(ib_drain_qp); -- cgit v1.2.3 From 851d7b6b8a954b28f85e62a53cbba472907e21e4 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Tue, 12 Apr 2016 06:54:54 -0700 Subject: iw_cxgb4: initialize ibdev.iwcm->ifname for port mapping The IWCM uses ibdev.iwcm->ifname for registration with the iwarp port map daemon. But iw_cxgb4 did not initialize this field which causes intermittent registration failures based on the contents of the uninitialized memory. Fixes: 170003c894d9 ("iw_cxgb4: remove port mapper related code") Signed-off-by: Steve Wise Signed-off-by: Doug Ledford --- drivers/infiniband/hw/cxgb4/provider.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c index 124682dc5709..7574f394fdac 100644 --- a/drivers/infiniband/hw/cxgb4/provider.c +++ b/drivers/infiniband/hw/cxgb4/provider.c @@ -580,6 +580,8 @@ int c4iw_register_device(struct c4iw_dev *dev) dev->ibdev.iwcm->add_ref = c4iw_qp_add_ref; dev->ibdev.iwcm->rem_ref = c4iw_qp_rem_ref; dev->ibdev.iwcm->get_qp = c4iw_get_qp; + memcpy(dev->ibdev.iwcm->ifname, dev->rdev.lldi.ports[0]->name, + sizeof(dev->ibdev.iwcm->ifname)); ret = ib_register_device(&dev->ibdev, NULL); if (ret) -- cgit v1.2.3 From ad202348fe3fa8187c43af5ab5b86fe6de057bd3 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Tue, 12 Apr 2016 06:55:01 -0700 Subject: iw_cxgb3: initialize ibdev.iwcm->ifname for port mapping The IWCM uses ibdev.iwcm->ifname for registration with the iwarp port map daemon. But iw_cxgb3 did not initialize this field which causes intermittent registration failures based on the contents of the uninitialized memory. Fixes: c1340e8aa628 ("iw_cxgb3: support for iWARP port mapping") Signed-off-by: Steve Wise Signed-off-by: Doug Ledford --- drivers/infiniband/hw/cxgb3/iwch_provider.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 42a7b8952d13..3234a8be16f6 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -1390,6 +1390,8 @@ int iwch_register_device(struct iwch_dev *dev) dev->ibdev.iwcm->add_ref = iwch_qp_add_ref; dev->ibdev.iwcm->rem_ref = iwch_qp_rem_ref; dev->ibdev.iwcm->get_qp = iwch_get_qp; + memcpy(dev->ibdev.iwcm->ifname, dev->rdev.t3cdev_p->lldev->name, + sizeof(dev->ibdev.iwcm->ifname)); ret = ib_register_device(&dev->ibdev, NULL); if (ret) -- cgit v1.2.3 From 40edd7fdfc8a2c838c313b982f318cd69e638750 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Tue, 12 Apr 2016 06:55:03 -0700 Subject: iw_cxgb4: handle draining an idle qp In c4iw_drain_sq/rq(), if the particular queue is already empty then don't block. Fixes: ce4af14d94aa ('iw_cxgb4: add queue drain functions') Signed-off-by: Steve Wise Signed-off-by: Doug Ledford --- drivers/infiniband/hw/cxgb4/qp.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index e17fb5d5e033..8aa2e52b453e 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -1895,13 +1895,27 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, void c4iw_drain_sq(struct ib_qp *ibqp) { struct c4iw_qp *qp = to_c4iw_qp(ibqp); + unsigned long flag; + bool need_to_wait; + + spin_lock_irqsave(&qp->lock, flag); + need_to_wait = !t4_sq_empty(&qp->wq); + spin_unlock_irqrestore(&qp->lock, flag); - wait_for_completion(&qp->sq_drained); + if (need_to_wait) + wait_for_completion(&qp->sq_drained); } void c4iw_drain_rq(struct ib_qp *ibqp) { struct c4iw_qp *qp = to_c4iw_qp(ibqp); + unsigned long flag; + bool need_to_wait; + + spin_lock_irqsave(&qp->lock, flag); + need_to_wait = !t4_rq_empty(&qp->wq); + spin_unlock_irqrestore(&qp->lock, flag); - wait_for_completion(&qp->rq_drained); + if (need_to_wait) + wait_for_completion(&qp->rq_drained); } -- cgit v1.2.3 From 32cc92c7b5e52357a0a24010bae9eb257fa75d3e Mon Sep 17 00:00:00 2001 From: Hariprasad S Date: Tue, 5 Apr 2016 10:23:48 +0530 Subject: RDMA/iw_cxgb4: Fix bar2 virt addr calculation for T4 chips For T4, kernel mode qps don't use the user doorbell. User mode qps during flow control db ringing are forced into kernel, where user doorbell is treated as kernel doorbell and proper bar2 offset in bar2 virtual space is calculated, which incase of T4 is a bogus address, causing a kernel panic due to illegal write during doorbell ringing. In case of T4, kernel mode qp bar2 virtual address should be 0. Added T4 check during bar2 virtual address calculation to return 0. Fixed Bar2 range checks based on bar2 physical address. The below oops will be fixed <1>BUG: unable to handle kernel paging request at 000000000002aa08 <1>IP: [] c4iw_uld_control+0x4e0/0x880 [iw_cxgb4] <4>PGD 1416a8067 PUD 15bf35067 PMD 0 <4>Oops: 0002 [#1] SMP <4>last sysfs file: /sys/devices/pci0000:00/0000:00:03.0/0000:02:00.4/infiniband/cxgb4_0/node_guid <4>CPU 5 <4>Modules linked in: rdma_ucm rdma_cm ib_cm ib_sa ib_mad ib_uverbs ip6table_filter ip6_tables ebtable_nat ebtables ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack ipt_REJECT xt_CHECKSUM iptable_mangle iptable_filter ip_tables bridge autofs4 target_core_iblock target_core_file target_core_pscsi target_core_mod configfs bnx2fc cnic uio fcoe libfcoe libfc scsi_transport_fc scsi_tgt 8021q garp stp llc cpufreq_ondemand acpi_cpufreq freq_table mperf vhost_net macvtap macvlan tun kvm uinput microcode iTCO_wdt iTCO_vendor_support sg joydev serio_raw i2c_i801 i2c_core lpc_ich mfd_core e1000e ptp pps_core ioatdma dca i7core_edac edac_core shpchp ext3 jbd mbcache sd_mod crc_t10dif pata_acpi ata_generic ata_piix iw_cxgb4 iw_cm ib_core ib_addr cxgb4 ipv6 dm_mirror dm_region_hash dm_log dm_mod [last unloaded: scsi_wait_scan] <4> Supermicro X8ST3/X8ST3 <4>RIP: 0010:[] [] c4iw_uld_control+0x4e0/0x880 [iw_cxgb4] <4>RSP: 0000:ffff880155a03db0 EFLAGS: 00010006 <4>RAX: 000000000000001d RBX: ffff88013ae5fc00 RCX: ffff880155adb180 <4>RDX: 000000000002aa00 RSI: 0000000000000001 RDI: ffff88013ae5fdf8 <4>RBP: ffff880155a03e10 R08: 0000000000000000 R09: 0000000000000001 <4>R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 <4>R13: 000000000000001d R14: ffff880156414ab0 R15: ffffe8ffffc05b88 <4>FS: 0000000000000000(0000) GS:ffff8800282a0000(0000) knlGS:0000000000000000 <4>CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b <4>CR2: 000000000002aa08 CR3: 000000015bd0e000 CR4: 00000000000007e0 <4>DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 <4>DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 <4>Process cxgb4 (pid: 394, threadinfo ffff880155a00000, task ffff880156414ab0) <4>Stack: <4> ffff880156415068 ffff880155adb180 ffff880155a03df0 ffffffffa00a344b <4> 00000000000003e8 ffff880155920000 0000000000000004 ffff880155920000 <4> ffff88015592d438 ffffffffa00a3860 ffff880155a03fd8 ffffe8ffffc05b88 <4>Call Trace: <4> [] ? enable_txq_db+0x2b/0x80 [cxgb4] <4> [] ? process_db_full+0x0/0xa0 [cxgb4] <4> [] process_db_full+0x46/0xa0 [cxgb4] <4> [] worker_thread+0x170/0x2a0 <4> [] ? autoremove_wake_function+0x0/0x40 <4> [] ? worker_thread+0x0/0x2a0 <4> [] kthread+0x9e/0xc0 <4> [] child_rip+0xa/0x20 <4> [] ? kthread+0x0/0xc0 <4> [] ? child_rip+0x0/0x20 <4>Code: e9 ba 00 00 00 66 0f 1f 44 00 00 44 8b 05 29 07 02 00 45 85 c0 0f 85 71 02 00 00 8b 83 70 01 00 00 45 0f b7 ed c1 e0 0f 44 09 e8 <89> 42 08 0f ae f8 66 c7 83 82 01 00 00 00 00 44 0f b7 ab dc 01 <1>RIP [] c4iw_uld_control+0x4e0/0x880 [iw_cxgb4] <4> RSP <4>CR2: 000000000002aa08` Based on original work by Bharat Potnuri Fixes: 74217d4c6a4fb0d8 ("iw_cxgb4: support for bar2 qid densities exceeding the page size") Signed-off-by: Steve Wise Signed-off-by: Hariprasad Shenai Reviewed-by: Leon Romanovsky Signed-off-by: Doug Ledford --- drivers/infiniband/hw/cxgb4/cq.c | 2 +- drivers/infiniband/hw/cxgb4/qp.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index b4eeb783573c..b0b955724458 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c @@ -162,7 +162,7 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, cq->bar2_va = c4iw_bar2_addrs(rdev, cq->cqid, T4_BAR2_QTYPE_INGRESS, &cq->bar2_qid, user ? &cq->bar2_pa : NULL); - if (user && !cq->bar2_va) { + if (user && !cq->bar2_pa) { pr_warn(MOD "%s: cqid %u not in BAR2 range.\n", pci_name(rdev->lldi.pdev), cq->cqid); ret = -EINVAL; diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 8aa2e52b453e..e8993e49b8b3 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -185,6 +185,10 @@ void __iomem *c4iw_bar2_addrs(struct c4iw_rdev *rdev, unsigned int qid, if (pbar2_pa) *pbar2_pa = (rdev->bar2_pa + bar2_qoffset) & PAGE_MASK; + + if (is_t4(rdev->lldi.adapter_type)) + return NULL; + return rdev->bar2_kva + bar2_qoffset; } @@ -270,7 +274,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, /* * User mode must have bar2 access. */ - if (user && (!wq->sq.bar2_va || !wq->rq.bar2_va)) { + if (user && (!wq->sq.bar2_pa || !wq->rq.bar2_pa)) { pr_warn(MOD "%s: sqid %u or rqid %u not in BAR2 range.\n", pci_name(rdev->lldi.pdev), wq->sq.qid, wq->rq.qid); goto free_dma; -- cgit v1.2.3 From 5086e5c79602a4620fbc3ec208f38e445982e301 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 18 Apr 2016 13:06:06 +0300 Subject: ARM: dts: omap5-board-common: fix ldo1_reg and ldo4_reg ranges ldo4_reg is connected to DSS, and should always be 1.8V. However the The dts defines a range of 1.5V-1.8V, which requires somethings to set the actual voltage at runtime. Currently we set the voltage in omapdss driver. As the voltage must always be 1.8V, let's just define the range to 1.8V so that the driver doesn't need to deal with the voltage. In fact, the driver should not touch the voltage, except in the cases where the voltage needs to be changed at runtime. I presume the situation is the same for ldo1_reg, used for CSI, although I think it is not currently used in the mainline. Signed-off-by: Tomi Valkeinen Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap5-board-common.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi index 902657d6713b..914bf4c47404 100644 --- a/arch/arm/boot/dts/omap5-board-common.dtsi +++ b/arch/arm/boot/dts/omap5-board-common.dtsi @@ -472,7 +472,7 @@ ldo1_reg: ldo1 { /* VDDAPHY_CAM: vdda_csiport */ regulator-name = "ldo1"; - regulator-min-microvolt = <1500000>; + regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; @@ -498,7 +498,7 @@ ldo4_reg: ldo4 { /* VDDAPHY_DISP: vdda_dsiport/hdmi */ regulator-name = "ldo4"; - regulator-min-microvolt = <1500000>; + regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; -- cgit v1.2.3 From 5607959a4d5b54dcc9a3572bdbf967dfda88ae66 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 18 Apr 2016 13:06:07 +0300 Subject: ARM: dts: omap5-cm-t54: fix ldo1_reg and ldo4_reg ranges ldo4_reg is connected to DSS, and should always be 1.8V. However the The dts defines a range of 1.5V-1.8V, which requires somethings to set the actual voltage at runtime. Currently we set the voltage in omapdss driver. As the voltage must always be 1.8V, let's just define the range to 1.8V so that the driver doesn't need to deal with the voltage. In fact, the driver should not touch the voltage, except in the cases where the voltage needs to be changed at runtime. I presume the situation is the same for ldo1_reg, used for CSI, although I think it is not currently used in the mainline. Signed-off-by: Tomi Valkeinen Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap5-cm-t54.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts index ecc591dc0778..4d87d9c6c86d 100644 --- a/arch/arm/boot/dts/omap5-cm-t54.dts +++ b/arch/arm/boot/dts/omap5-cm-t54.dts @@ -513,7 +513,7 @@ ldo1_reg: ldo1 { /* VDDAPHY_CAM: vdda_csiport */ regulator-name = "ldo1"; - regulator-min-microvolt = <1500000>; + regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; @@ -537,7 +537,7 @@ ldo4_reg: ldo4 { /* VDDAPHY_DISP: vdda_dsiport/hdmi */ regulator-name = "ldo4"; - regulator-min-microvolt = <1500000>; + regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; -- cgit v1.2.3 From e180feaf79b54d999329b194a3650f390acedf2c Mon Sep 17 00:00:00 2001 From: Ivaylo Dimitrov Date: Sat, 16 Apr 2016 09:20:28 +0300 Subject: ARM: dts: omap3: Fix ISP syscon register offset According to the TRM, SCM CONTROL_CSIRXFE register is on offset 0x6c Signed-off-by: Ivaylo Dimitrov Reviewed-By: Sebastian Reichel Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap34xx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/omap34xx.dtsi b/arch/arm/boot/dts/omap34xx.dtsi index 387dc31822fe..96f8ce7bd2af 100644 --- a/arch/arm/boot/dts/omap34xx.dtsi +++ b/arch/arm/boot/dts/omap34xx.dtsi @@ -46,7 +46,7 @@ 0x480bd800 0x017c>; interrupts = <24>; iommus = <&mmu_isp>; - syscon = <&scm_conf 0xdc>; + syscon = <&scm_conf 0x6c>; ti,phy-type = ; #clock-cells = <1>; ports { -- cgit v1.2.3 From 0698178c608e5f48ac78cde8c08260c2d7041a39 Mon Sep 17 00:00:00 2001 From: Ivaylo Dimitrov Date: Sun, 17 Apr 2016 17:29:23 +0300 Subject: ARM: dts: omap3-n900: Specify peripherals LDO regulators initial mode Without that, regulators are left in the mode last set by the bootloader or by the kernel the device was rebooted from. This leads to various problems, like non-working peripherals. Signed-off-by: Ivaylo Dimitrov Reviewed-By: Sebastian Reichel Reviewed-by: Javier Martinez Canillas Reviewed-by: Pavel Machek Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-n900.dts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index b3c26a96a726..d9e2d9c6e999 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -329,6 +329,7 @@ regulator-name = "V28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ regulator-always-on; /* due to battery cover sensor */ }; @@ -336,30 +337,35 @@ regulator-name = "VCSI"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ }; &vaux3 { regulator-name = "VMMC2_30"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <3000000>; + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ }; &vaux4 { regulator-name = "VCAM_ANA_28"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ }; &vmmc1 { regulator-name = "VMMC1"; regulator-min-microvolt = <1850000>; regulator-max-microvolt = <3150000>; + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ }; &vmmc2 { regulator-name = "V28_A"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <3000000>; + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ regulator-always-on; /* due VIO leak to AIC34 VDDs */ }; @@ -367,6 +373,7 @@ regulator-name = "VPLL"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ regulator-always-on; }; @@ -374,6 +381,7 @@ regulator-name = "VSDI_CSI"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ regulator-always-on; }; @@ -381,6 +389,7 @@ regulator-name = "VMMC2_IO_18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + regulator-initial-mode = <0x0e>; /* RES_STATE_ACTIVE */ }; &vio { -- cgit v1.2.3 From 7472931f7f1e9d91f761dce30107ae345b61a5c3 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Mon, 18 Apr 2016 20:20:59 +0200 Subject: ARM: dts: omap5: fix range of permitted wakeup pinmux registers otherwise we can't define gpio1_wk14 Signed-off-by: H. Nikolaus Schaller Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap5.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 38805ebbe2ba..120b6b80cd39 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -269,7 +269,7 @@ omap5_pmx_wkup: pinmux@c840 { compatible = "ti,omap5-padconf", "pinctrl-single"; - reg = <0xc840 0x0038>; + reg = <0xc840 0x003c>; #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; -- cgit v1.2.3 From e16d8a6cbb499c5c8bfe9330d3351b649bded4af Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Tue, 26 Apr 2016 08:52:44 -0700 Subject: Revert "x86/mm/32: Set NX in __supported_pte_mask before enabling paging" This reverts commit 320d25b6a05f8b73c23fc21025d2906ecdd2d4fc. This change was problematic for a couple of reasons: 1. It missed a some entry points (Xen things and 64-bit native). 2. The entry it changed can be executed more than once. This isn't really a problem, but it conflated per-cpu state setup and global state setup. 3. It broke 64-bit non-NX. 64-bit non-NX worked the other way around from 32-bit -- __supported_pte_mask had NX set initially and was *cleared* in x86_configure_nx. With the patch applied, it never got cleared. Reported-and-tested-by: Meelis Roos Signed-off-by: Andy Lutomirski Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/59bd15f7f4b56b633a611b7f70876c6d2ad01a98.1461685884.git.luto@kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/head_32.S | 6 ------ arch/x86/mm/setup_nx.c | 5 +++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 54cdbd2003fe..af1112980dd4 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -389,12 +389,6 @@ default_entry: /* Make changes effective */ wrmsr - /* - * And make sure that all the mappings we set up have NX set from - * the beginning. - */ - orl $(1 << (_PAGE_BIT_NX - 32)), pa(__supported_pte_mask + 4) - enable_paging: /* diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c index 8bea84724a7d..f65a33f505b6 100644 --- a/arch/x86/mm/setup_nx.c +++ b/arch/x86/mm/setup_nx.c @@ -32,8 +32,9 @@ early_param("noexec", noexec_setup); void x86_configure_nx(void) { - /* If disable_nx is set, clear NX on all new mappings going forward. */ - if (disable_nx) + if (boot_cpu_has(X86_FEATURE_NX) && !disable_nx) + __supported_pte_mask |= _PAGE_NX; + else __supported_pte_mask &= ~_PAGE_NX; } -- cgit v1.2.3 From 8358b02bf67d3a5d8a825070e1aa73f25fb2e4c7 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Tue, 26 Apr 2016 22:26:26 +0200 Subject: bpf: fix double-fdput in replace_map_fd_with_map_ptr() When bpf(BPF_PROG_LOAD, ...) was invoked with a BPF program whose bytecode references a non-map file descriptor as a map file descriptor, the error handling code called fdput() twice instead of once (in __bpf_map_get() and in replace_map_fd_with_map_ptr()). If the file descriptor table of the current task is shared, this causes f_count to be decremented too much, allowing the struct file to be freed while it is still in use (use-after-free). This can be exploited to gain root privileges by an unprivileged user. This bug was introduced in commit 0246e64d9a5f ("bpf: handle pseudo BPF_LD_IMM64 insn"), but is only exploitable since commit 1be7f75d1668 ("bpf: enable non-root eBPF programs") because previously, CAP_SYS_ADMIN was required to reach the vulnerable code. (posted publicly according to request by maintainer) Signed-off-by: Jann Horn Signed-off-by: Linus Torvalds Acked-by: Alexei Starovoitov Acked-by: Daniel Borkmann Signed-off-by: David S. Miller --- kernel/bpf/verifier.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 618ef77c302a..db2574e7b8b0 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2030,7 +2030,6 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env) if (IS_ERR(map)) { verbose("fd %d is not pointing to valid bpf_map\n", insn->imm); - fdput(f); return PTR_ERR(map); } -- cgit v1.2.3 From 607fb0f4d90cc9a4463bcb17c1417d8a709dfda1 Mon Sep 17 00:00:00 2001 From: Tal Shorer Date: Mon, 25 Apr 2016 15:53:29 -0500 Subject: usb: musb: gadget: nuke endpoint before setting its descriptor to NULL Some functions, such as f_sourcesink, rely on an endpoint's desc field during their requests' complete() callback, so clear it only _after_ nuking all requests to avoid NULL pointer dereference. Signed-off-by: Tal Shorer Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_gadget.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 87bd578799a8..152865b36522 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1164,12 +1164,12 @@ static int musb_gadget_disable(struct usb_ep *ep) musb_writew(epio, MUSB_RXMAXP, 0); } - musb_ep->desc = NULL; - musb_ep->end_point.desc = NULL; - /* abort all pending DMA and requests */ nuke(musb_ep, -ESHUTDOWN); + musb_ep->desc = NULL; + musb_ep->end_point.desc = NULL; + schedule_work(&musb->irq_work); spin_unlock_irqrestore(&(musb->lock), flags); -- cgit v1.2.3 From f551e13529833e052f75ec628a8af7b034af20f9 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Mon, 25 Apr 2016 15:53:30 -0500 Subject: Revert "usb: musb: musb_host: Enable HCD_BH flag to handle urb return in bottom half" This reverts commit 2035772010db634ec8566b658fb1cd87ec47ac77. Commit 20357720 claims throughput improvement for MSC/UVC, but I don't see much improvement. Following are the MSC measurement using dd on AM335x GP EVM. with BCD_BH: read: 14.9MB/s, write: 20.9MB/s without BCD_BH: read: 15.2MB/s, write: 21.2MB/s However with this commit the following regressions have been observed. 1. ASIX usb-ethernet dongle is completely broken on UDP RX. 2. Unpluging a 3G modem, which uses option driver, behind a hub causes console log flooding with the following message. option_instat_callback: error -71 Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 58487a473521..2f8ad7f1f482 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2735,7 +2735,7 @@ static const struct hc_driver musb_hc_driver = { .description = "musb-hcd", .product_desc = "MUSB HDRC host driver", .hcd_priv_size = sizeof(struct musb *), - .flags = HCD_USB2 | HCD_MEMORY | HCD_BH, + .flags = HCD_USB2 | HCD_MEMORY, /* not using irq handler or reset hooks from usbcore, since * those must be shared with peripheral code for OTG configs -- cgit v1.2.3 From 97b9b7dc7722dc78d46046fc7a0dd0264832327f Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Mon, 25 Apr 2016 15:53:31 -0500 Subject: usb: musb: jz4740: fix error check of usb_get_phy() The usb_get_phy() function returns either a valid pointer to phy or ERR_PTR() error, check for NULL always fails and may lead to oops on error path, fix this issue. Signed-off-by: Vladimir Zapolskiy Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/jz4740.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index 5e5a8fa005f8..bc8889956d17 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c @@ -83,9 +83,9 @@ static int jz4740_musb_init(struct musb *musb) { usb_phy_generic_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); - if (!musb->xceiv) { + if (IS_ERR(musb->xceiv)) { pr_err("HS UDC: no transceiver configured\n"); - return -ENODEV; + return PTR_ERR(musb->xceiv); } /* Silicon does not implement ConfigData register. -- cgit v1.2.3 From 8ead9dd54716d1e05e129959f702fcc1786f82b4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 25 Apr 2016 20:04:08 -0700 Subject: devpts: more pty driver interface cleanups This is more prep-work for the upcoming pty changes. Still just code cleanup with no actual semantic changes. This removes a bunch pointless complexity by just having the slave pty side remember the dentry associated with the devpts slave rather than the inode. That allows us to remove all the "look up the dentry" code for when we want to remove it again. Together with moving the tty pointer from "inode->i_private" to "dentry->d_fsdata" and getting rid of pointless inode locking, this removes about 30 lines of code. Not only is the end result smaller, it's simpler and easier to understand. The old code, for example, depended on the d_find_alias() to not just find the dentry, but also to check that it is still hashed, which in turn validated the tty pointer in the inode. That is a _very_ roundabout way to say "invalidate the cached tty pointer when the dentry is removed". The new code just does dentry->d_fsdata = NULL; in devpts_pty_kill() instead, invalidating the tty pointer rather more directly and obviously. Don't do something complex and subtle when the obvious straightforward approach will do. The rest of the patch (ie apart from code deletion and the above tty pointer clearing) is just switching the calling convention to pass the dentry or file pointer around instead of the inode. Cc: Eric Biederman Cc: Peter Anvin Cc: Andy Lutomirski Cc: Al Viro Cc: Peter Hurley Cc: Serge Hallyn Cc: Willy Tarreau Cc: Aurelien Jarno Cc: Alan Cox Cc: Jann Horn Cc: Greg KH Cc: Jiri Slaby Cc: Florian Weimer Signed-off-by: Linus Torvalds --- drivers/tty/pty.c | 18 +++++++--------- drivers/tty/tty_io.c | 6 +++--- fs/devpts/inode.c | 53 +++++++++++----------------------------------- include/linux/devpts_fs.h | 6 +++--- include/linux/tty_driver.h | 4 ++-- 5 files changed, 28 insertions(+), 59 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 0058d9fbf931..cf0dc51a2690 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -626,7 +626,7 @@ static int pty_unix98_ioctl(struct tty_struct *tty, */ static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, - struct inode *ptm_inode, int idx) + struct file *file, int idx) { /* Master must be open via /dev/ptmx */ return ERR_PTR(-EIO); @@ -642,12 +642,12 @@ static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, */ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, - struct inode *pts_inode, int idx) + struct file *file, int idx) { struct tty_struct *tty; mutex_lock(&devpts_mutex); - tty = devpts_get_priv(pts_inode); + tty = devpts_get_priv(file->f_path.dentry); mutex_unlock(&devpts_mutex); /* Master must be open before slave */ if (!tty) @@ -722,7 +722,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) { struct pts_fs_info *fsi; struct tty_struct *tty; - struct inode *slave_inode; + struct dentry *dentry; int retval; int index; @@ -769,14 +769,12 @@ static int ptmx_open(struct inode *inode, struct file *filp) tty_add_file(tty, filp); - slave_inode = devpts_pty_new(fsi, - MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index, - tty->link); - if (IS_ERR(slave_inode)) { - retval = PTR_ERR(slave_inode); + dentry = devpts_pty_new(fsi, index, tty->link); + if (IS_ERR(dentry)) { + retval = PTR_ERR(dentry); goto err_release; } - tty->link->driver_data = slave_inode; + tty->link->driver_data = dentry; retval = ptm_driver->ops->open(tty, filp); if (retval) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 9b04d72e752e..24d5491ef0da 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1367,12 +1367,12 @@ static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p) * Locking: tty_mutex must be held. If the tty is found, bump the tty kref. */ static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, - struct inode *inode, int idx) + struct file *file, int idx) { struct tty_struct *tty; if (driver->ops->lookup) - tty = driver->ops->lookup(driver, inode, idx); + tty = driver->ops->lookup(driver, file, idx); else tty = driver->ttys[idx]; @@ -2040,7 +2040,7 @@ static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, } /* check whether we're reopening an existing tty */ - tty = tty_driver_lookup_tty(driver, inode, index); + tty = tty_driver_lookup_tty(driver, filp, index); if (IS_ERR(tty)) { mutex_unlock(&tty_mutex); goto out; diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 0af8e7d70d27..0b2954d7172d 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -604,8 +604,7 @@ void devpts_put_ref(struct pts_fs_info *fsi) * * The created inode is returned. Remove it from /dev/pts/ by devpts_pty_kill. */ -struct inode *devpts_pty_new(struct pts_fs_info *fsi, dev_t device, int index, - void *priv) +struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv) { struct dentry *dentry; struct super_block *sb; @@ -629,25 +628,21 @@ struct inode *devpts_pty_new(struct pts_fs_info *fsi, dev_t device, int index, inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - init_special_inode(inode, S_IFCHR|opts->mode, device); - inode->i_private = priv; + init_special_inode(inode, S_IFCHR|opts->mode, MKDEV(UNIX98_PTY_SLAVE_MAJOR, index)); sprintf(s, "%d", index); - inode_lock(d_inode(root)); - dentry = d_alloc_name(root, s); if (dentry) { + dentry->d_fsdata = priv; d_add(dentry, inode); fsnotify_create(d_inode(root), dentry); } else { iput(inode); - inode = ERR_PTR(-ENOMEM); + dentry = ERR_PTR(-ENOMEM); } - inode_unlock(d_inode(root)); - - return inode; + return dentry; } /** @@ -656,24 +651,10 @@ struct inode *devpts_pty_new(struct pts_fs_info *fsi, dev_t device, int index, * * Returns whatever was passed as priv in devpts_pty_new for a given inode. */ -void *devpts_get_priv(struct inode *pts_inode) +void *devpts_get_priv(struct dentry *dentry) { - struct dentry *dentry; - void *priv = NULL; - - BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); - - /* Ensure dentry has not been deleted by devpts_pty_kill() */ - dentry = d_find_alias(pts_inode); - if (!dentry) - return NULL; - - if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) - priv = pts_inode->i_private; - - dput(dentry); - - return priv; + WARN_ON_ONCE(dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC); + return dentry->d_fsdata; } /** @@ -682,24 +663,14 @@ void *devpts_get_priv(struct inode *pts_inode) * * This is an inverse operation of devpts_pty_new. */ -void devpts_pty_kill(struct inode *inode) +void devpts_pty_kill(struct dentry *dentry) { - struct super_block *sb = pts_sb_from_inode(inode); - struct dentry *root = sb->s_root; - struct dentry *dentry; + WARN_ON_ONCE(dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC); - BUG_ON(inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); - - inode_lock(d_inode(root)); - - dentry = d_find_alias(inode); - - drop_nlink(inode); + dentry->d_fsdata = NULL; + drop_nlink(dentry->d_inode); d_delete(dentry); dput(dentry); /* d_alloc_name() in devpts_pty_new() */ - dput(dentry); /* d_find_alias above */ - - inode_unlock(d_inode(root)); } static int __init init_devpts_fs(void) diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h index 358a4db72a27..5871f292b596 100644 --- a/include/linux/devpts_fs.h +++ b/include/linux/devpts_fs.h @@ -27,11 +27,11 @@ int devpts_new_index(struct pts_fs_info *); void devpts_kill_index(struct pts_fs_info *, int); /* mknod in devpts */ -struct inode *devpts_pty_new(struct pts_fs_info *, dev_t, int, void *); +struct dentry *devpts_pty_new(struct pts_fs_info *, int, void *); /* get private structure */ -void *devpts_get_priv(struct inode *pts_inode); +void *devpts_get_priv(struct dentry *); /* unlink */ -void devpts_pty_kill(struct inode *inode); +void devpts_pty_kill(struct dentry *); #endif diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 161052477f77..b742b5e47cc2 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -7,7 +7,7 @@ * defined; unless noted otherwise, they are optional, and can be * filled in with a null pointer. * - * struct tty_struct * (*lookup)(struct tty_driver *self, int idx) + * struct tty_struct * (*lookup)(struct tty_driver *self, struct file *, int idx) * * Return the tty device corresponding to idx, NULL if there is not * one currently in use and an ERR_PTR value on error. Called under @@ -250,7 +250,7 @@ struct serial_icounter_struct; struct tty_operations { struct tty_struct * (*lookup)(struct tty_driver *driver, - struct inode *inode, int idx); + struct file *filp, int idx); int (*install)(struct tty_driver *driver, struct tty_struct *tty); void (*remove)(struct tty_driver *driver, struct tty_struct *tty); int (*open)(struct tty_struct * tty, struct file * filp); -- cgit v1.2.3 From 263efde31f97c498e1ebad30e4d2906609d7ad6b Mon Sep 17 00:00:00 2001 From: "cpaul@redhat.com" Date: Fri, 22 Apr 2016 16:08:46 -0400 Subject: drm/dp/mst: Get validated port ref in drm_dp_update_payload_part1() We can thank KASAN for finding this, otherwise I probably would have spent hours on it. This fixes a somewhat harder to trigger kernel panic, occuring while enabling MST where the port we were currently updating the payload on would have all of it's refs dropped before we finished what we were doing: ================================================================== BUG: KASAN: use-after-free in drm_dp_update_payload_part1+0xb3f/0xdb0 [drm_kms_helper] at addr ffff8800d29de018 Read of size 4 by task Xorg/973 ============================================================================= BUG kmalloc-2048 (Tainted: G B W ): kasan: bad access detected ----------------------------------------------------------------------------- INFO: Allocated in drm_dp_add_port+0x1aa/0x1ed0 [drm_kms_helper] age=16477 cpu=0 pid=2175 ___slab_alloc+0x472/0x490 __slab_alloc+0x20/0x40 kmem_cache_alloc_trace+0x151/0x190 drm_dp_add_port+0x1aa/0x1ed0 [drm_kms_helper] drm_dp_send_link_address+0x526/0x960 [drm_kms_helper] drm_dp_check_and_send_link_address+0x1ac/0x210 [drm_kms_helper] drm_dp_mst_link_probe_work+0x77/0xd0 [drm_kms_helper] process_one_work+0x562/0x1350 worker_thread+0xd9/0x1390 kthread+0x1c5/0x260 ret_from_fork+0x22/0x40 INFO: Freed in drm_dp_free_mst_port+0x50/0x60 [drm_kms_helper] age=7521 cpu=0 pid=2175 __slab_free+0x17f/0x2d0 kfree+0x169/0x180 drm_dp_free_mst_port+0x50/0x60 [drm_kms_helper] drm_dp_destroy_connector_work+0x2b8/0x490 [drm_kms_helper] process_one_work+0x562/0x1350 worker_thread+0xd9/0x1390 kthread+0x1c5/0x260 ret_from_fork+0x22/0x40 which on this T460s, would eventually lead to kernel panics in somewhat random places later in intel_mst_enable_dp() if we got lucky enough. Signed-off-by: Lyude Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_dp_mst_topology.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index e17fbdaf874b..935d8cc46841 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1796,6 +1796,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) req_payload.start_slot = cur_slots; if (mgr->proposed_vcpis[i]) { port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi); + port = drm_dp_get_validated_port_ref(mgr, port); + if (!port) { + mutex_unlock(&mgr->payload_lock); + return -EINVAL; + } req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots; req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi; } else { @@ -1823,6 +1828,9 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) mgr->payloads[i].payload_state = req_payload.payload_state; } cur_slots += req_payload.num_slots; + + if (port) + drm_dp_put_port(port); } for (i = 0; i < mgr->max_payloads; i++) { -- cgit v1.2.3 From 9dc0487d96a0396367a1451b31873482080b527f Mon Sep 17 00:00:00 2001 From: Lyude Date: Wed, 13 Apr 2016 16:50:18 -0400 Subject: drm/dp/mst: Restore primary hub guid on resume Some hubs are forgetful, and end up forgetting whatever GUID we set previously after we do a suspend/resume cycle. This can lead to hotplugging breaking (along with probably other things) since the hub will start sending connection notifications with the wrong GUID. As such, we need to check on resume whether or not the GUID the hub is giving us is valid. Signed-off-by: Lyude Reviewed-by: Harry Wentland Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1460580618-7421-1-git-send-email-cpaul@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_dp_mst_topology.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 935d8cc46841..71ea0521ea96 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -2136,6 +2136,8 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr) if (mgr->mst_primary) { int sret; + u8 guid[16]; + sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE); if (sret != DP_RECEIVER_CAP_SIZE) { DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); @@ -2150,6 +2152,16 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr) ret = -1; goto out_unlock; } + + /* Some hubs forget their guids after they resume */ + sret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16); + if (sret != 16) { + DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); + ret = -1; + goto out_unlock; + } + drm_dp_check_mstb_guid(mgr->mst_primary, guid); + ret = 0; } else ret = -1; -- cgit v1.2.3 From 9a11d2e7e66b6b8764a2430686b8716637bf812e Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 14 Apr 2016 10:58:54 -0700 Subject: drm/virtio: send vblank event after crtc updates virtio_gpu was failing to send vblank events when using the atomic IOCTL with the DRM_MODE_PAGE_FLIP_EVENT flag set. This patch fixes each and enables atomic pageflips updates. Signed-off-by: Gustavo Padovan Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/virtio/virtgpu_display.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 4854dac87e24..5fd1fd06effc 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -267,11 +267,23 @@ static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc, return 0; } +static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, + struct drm_crtc_state *old_state) +{ + unsigned long flags; + + spin_lock_irqsave(&crtc->dev->event_lock, flags); + if (crtc->state->event) + drm_crtc_send_vblank_event(crtc, crtc->state->event); + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); +} + static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = { .enable = virtio_gpu_crtc_enable, .disable = virtio_gpu_crtc_disable, .mode_set_nofb = virtio_gpu_crtc_mode_set_nofb, .atomic_check = virtio_gpu_crtc_atomic_check, + .atomic_flush = virtio_gpu_crtc_atomic_flush, }; static void virtio_gpu_enc_mode_set(struct drm_encoder *encoder, -- cgit v1.2.3 From d6776bba44d9752f6cdf640046070e71ee4bba7b Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 22 Apr 2016 14:57:48 +1000 Subject: cxl: Keep IRQ mappings on context teardown Keep IRQ mappings on context teardown. This won't leak IRQs as if we allocate the mapping again, the generic code will give the same mapping used last time. Doing this works around a race in the generic code. Masking the interrupt introduces a race which can crash the kernel or result in IRQ that is never EOIed. The lost of EOI results in all subsequent mappings to the same HW IRQ never receiving an interrupt. We've seen this race with cxl test cases which are doing heavy context startup and teardown at the same time as heavy interrupt load. A fix to the generic code is being investigated also. Signed-off-by: Michael Neuling Cc: stable@vger.kernel.org # 3.8 Tested-by: Andrew Donnellan Acked-by: Ian Munsie Tested-by: Vaibhav Jain Signed-off-by: Michael Ellerman --- drivers/misc/cxl/irq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c index be646dc41a2c..8def4553acba 100644 --- a/drivers/misc/cxl/irq.c +++ b/drivers/misc/cxl/irq.c @@ -203,7 +203,6 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq, void cxl_unmap_irq(unsigned int virq, void *cookie) { free_irq(virq, cookie); - irq_dispose_mapping(virq); } int cxl_register_one_irq(struct cxl *adapter, -- cgit v1.2.3 From 2bc79ffcbb817873cc43d63118008ab75181b73d Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 22 Apr 2016 14:57:49 +1000 Subject: cxl: Poll for outstanding IRQs when detaching a context When detaching contexts, we may still have interrupts in the system which are yet to be delivered to any CPU and be acked in the PSL. This can result in a subsequent unrelated process getting an spurious IRQ or an interrupt for a non-existent context. This polls the PSL to ensure that the PSL is clear of IRQs for the detached context, before removing the context from the idr. Signed-off-by: Michael Neuling Tested-by: Andrew Donnellan Acked-by: Ian Munsie Tested-by: Vaibhav Jain Signed-off-by: Michael Ellerman --- drivers/misc/cxl/context.c | 7 +++++++ drivers/misc/cxl/cxl.h | 2 ++ drivers/misc/cxl/native.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 10370f280500..7edea9c19199 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c @@ -223,6 +223,13 @@ int __detach_context(struct cxl_context *ctx) cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)); flush_work(&ctx->fault_work); /* Only needed for dedicated process */ + /* + * Wait until no further interrupts are presented by the PSL + * for this context. + */ + if (cxl_ops->irq_wait) + cxl_ops->irq_wait(ctx); + /* release the reference to the group leader and mm handling pid */ put_pid(ctx->pid); put_pid(ctx->glpid); diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 38e21cf7806e..73dc2a33da74 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -274,6 +274,7 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0}; #define CXL_PSL_DSISR_An_PE (1ull << (63-4)) /* PSL Error (implementation specific) */ #define CXL_PSL_DSISR_An_AE (1ull << (63-5)) /* AFU Error */ #define CXL_PSL_DSISR_An_OC (1ull << (63-6)) /* OS Context Warning */ +#define CXL_PSL_DSISR_PENDING (CXL_PSL_DSISR_TRANS | CXL_PSL_DSISR_An_PE | CXL_PSL_DSISR_An_AE | CXL_PSL_DSISR_An_OC) /* NOTE: Bits 32:63 are undefined if DSISR[DS] = 1 */ #define CXL_PSL_DSISR_An_M DSISR_NOHPTE /* PTE not found */ #define CXL_PSL_DSISR_An_P DSISR_PROTFAULT /* Storage protection violation */ @@ -855,6 +856,7 @@ struct cxl_backend_ops { u64 dsisr, u64 errstat); irqreturn_t (*psl_interrupt)(int irq, void *data); int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask); + void (*irq_wait)(struct cxl_context *ctx); int (*attach_process)(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr); int (*detach_process)(struct cxl_context *ctx); diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 387fcbdf9793..ecf7557cd657 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -797,6 +798,35 @@ static irqreturn_t native_irq_multiplexed(int irq, void *data) return fail_psl_irq(afu, &irq_info); } +void native_irq_wait(struct cxl_context *ctx) +{ + u64 dsisr; + int timeout = 1000; + int ph; + + /* + * Wait until no further interrupts are presented by the PSL + * for this context. + */ + while (timeout--) { + ph = cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) & 0xffff; + if (ph != ctx->pe) + return; + dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An); + if ((dsisr & CXL_PSL_DSISR_PENDING) == 0) + return; + /* + * We are waiting for the workqueue to process our + * irq, so need to let that run here. + */ + msleep(1); + } + + dev_warn(&ctx->afu->dev, "WARNING: waiting on DSI for PE %i" + " DSISR %016llx!\n", ph, dsisr); + return; +} + static irqreturn_t native_slice_irq_err(int irq, void *data) { struct cxl_afu *afu = data; @@ -1076,6 +1106,7 @@ const struct cxl_backend_ops cxl_native_ops = { .handle_psl_slice_error = native_handle_psl_slice_error, .psl_interrupt = NULL, .ack_irq = native_ack_irq, + .irq_wait = native_irq_wait, .attach_process = native_attach_process, .detach_process = native_detach_process, .support_attributes = native_support_attributes, -- cgit v1.2.3 From d701cca6744fe0d67c86346dcfc9b128b17b5045 Mon Sep 17 00:00:00 2001 From: Rui Salvaterra Date: Tue, 19 Apr 2016 13:23:36 +0100 Subject: powerpc: wire up preadv2 and pwritev2 syscalls Wire up preadv2/pwritev2 in the same way as preadv/pwritev. Fixes two build warnings on ppc64. mpe: Lightly tested with fio (slightly hacked to add the syscall wrappers): fio-4217 [009] .... 1304.635300: sys_preadv2(fd: 3, vec: 10025821de0, vlen: 1, pos_l: 6253000, pos_h: 0, flags: 1) fio-4217 [009] .... 1304.635474: sys_preadv2 -> 0x1000 Signed-off-by: Rui Salvaterra Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/systbl.h | 2 ++ arch/powerpc/include/asm/unistd.h | 2 +- arch/powerpc/include/uapi/asm/unistd.h | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 3fa9df70aa20..2fc5d4db503c 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -384,3 +384,5 @@ SYSCALL(ni_syscall) SYSCALL(ni_syscall) SYSCALL(mlock2) SYSCALL(copy_file_range) +COMPAT_SYS_SPU(preadv2) +COMPAT_SYS_SPU(pwritev2) diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 1f2594d45605..cf12c580f6b2 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -12,7 +12,7 @@ #include -#define NR_syscalls 380 +#define NR_syscalls 382 #define __NR__exit __NR_exit diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h index 940290d45b08..e9f5f41aa55a 100644 --- a/arch/powerpc/include/uapi/asm/unistd.h +++ b/arch/powerpc/include/uapi/asm/unistd.h @@ -390,5 +390,7 @@ #define __NR_membarrier 365 #define __NR_mlock2 378 #define __NR_copy_file_range 379 +#define __NR_preadv2 380 +#define __NR_pwritev2 381 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ -- cgit v1.2.3 From 532c34b5fbf1687df63b3fcd5b2846312ac943c6 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 25 Apr 2016 17:54:28 +0200 Subject: s390/sclp_ctl: fix potential information leak with /dev/sclp The sclp_ctl_ioctl_sccb function uses two copy_from_user calls to retrieve the sclp request from user space. The first copy_from_user fetches the length of the request which is stored in the first two bytes of the request. The second copy_from_user gets the complete sclp request, but this copies the length field a second time. A malicious user may have changed the length in the meantime. Reported-by: Pengfei Wang Reviewed-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp_ctl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/s390/char/sclp_ctl.c b/drivers/s390/char/sclp_ctl.c index 648cb86afd42..ea607a4a1bdd 100644 --- a/drivers/s390/char/sclp_ctl.c +++ b/drivers/s390/char/sclp_ctl.c @@ -56,6 +56,7 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area) { struct sclp_ctl_sccb ctl_sccb; struct sccb_header *sccb; + unsigned long copied; int rc; if (copy_from_user(&ctl_sccb, user_area, sizeof(ctl_sccb))) @@ -65,14 +66,15 @@ static int sclp_ctl_ioctl_sccb(void __user *user_area) sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!sccb) return -ENOMEM; - if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sizeof(*sccb))) { + copied = PAGE_SIZE - + copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), PAGE_SIZE); + if (offsetof(struct sccb_header, length) + + sizeof(sccb->length) > copied || sccb->length > copied) { rc = -EFAULT; goto out_free; } - if (sccb->length > PAGE_SIZE || sccb->length < 8) - return -EINVAL; - if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sccb->length)) { - rc = -EFAULT; + if (sccb->length < 8) { + rc = -EINVAL; goto out_free; } rc = sclp_sync_request(ctl_sccb.cmdw, sccb); -- cgit v1.2.3 From 7ac7d19f808697abe6658c64c96868f728273f9c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 17 Apr 2016 20:42:46 +0100 Subject: drm/i915: Avoid stalling on pending flips for legacy cursor updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The legacy cursor ioctl expects to be asynchronous with respect to other screen updates, in particular page flips. As X updates the cursor from a signal context, if the cursor blocks then it will stall both the input and output chains causing bad stuttering and horrible UX. Reported-and-tested-by: Rafael Ristovski Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94980 Fixes: 5008e874edd34 ("drm/i915: Make wait_for_flips interruptible.") Suggested-by: Maarten Lankhorst Signed-off-by: Chris Wilson Cc: Maarten Lankhorst Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Jani Nikula Cc: stable@vger.kernel.org Link: http://patchwork.freedesktop.org/patch/msgid/1460922166-20292-1-git-send-email-chris@chris-wilson.co.uk Acked-by: Daniel Vetter Reviewed-by: Maarten Lankhorst (cherry picked from commit acf4e84d6167317ff21be5c03e1ea76ea5783701) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6e0d8283daa6..182f84937345 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13351,6 +13351,9 @@ static int intel_atomic_prepare_commit(struct drm_device *dev, } for_each_crtc_in_state(state, crtc, crtc_state, i) { + if (state->legacy_cursor_update) + continue; + ret = intel_crtc_wait_for_pending_flips(crtc); if (ret) return ret; -- cgit v1.2.3 From dab9a2663f4e688106c041f7cd2797a721382f0a Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 18 Apr 2016 14:45:54 +0300 Subject: drm/i915: Fix system resume if PCI device remained enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During system resume we depended on pci_enable_device() also putting the device into PCI D0 state. This won't work if the PCI device was already enabled but still in D3 state. This is because pci_enable_device() is refcounted and will not change the HW state if called with a non-zero refcount. Leaving the device in D3 will make all subsequent device accesses fail. This didn't cause a problem most of the time, since we resumed with an enable refcount of 0. But it fails at least after module reload because after that we also happen to leak a PCI device enable reference: During probing we call drm_get_pci_dev() which will enable the PCI device, but during device removal drm_put_dev() won't disable it. This is a bug of its own in DRM core, but without much harm as it only leaves the PCI device enabled. Fixing it is also a bit more involved, due to DRM mid-layering and because it affects non-i915 drivers too. The fix in this patch is valid regardless of the problem in DRM core. v2: - Add a code comment about the relation of this fix to the freeze/thaw vs. the suspend/resume phases. (Ville) - Add a code comment about the inconsistent ordering of set power state and device enable calls. (Chris) CC: Ville Syrjälä CC: Chris Wilson CC: stable@vger.kernel.org Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1460979954-14503-1-git-send-email-imre.deak@intel.com (cherry picked from commit 44410cd0bfb26bde9288da34c190cc9267d42a20) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 30798cbc6fc0..6d2fb3f4ac62 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -792,7 +792,7 @@ static int i915_drm_resume(struct drm_device *dev) static int i915_drm_resume_early(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int ret = 0; + int ret; /* * We have a resume ordering issue with the snd-hda driver also @@ -803,6 +803,36 @@ static int i915_drm_resume_early(struct drm_device *dev) * FIXME: This should be solved with a special hdmi sink device or * similar so that power domains can be employed. */ + + /* + * Note that we need to set the power state explicitly, since we + * powered off the device during freeze and the PCI core won't power + * it back up for us during thaw. Powering off the device during + * freeze is not a hard requirement though, and during the + * suspend/resume phases the PCI core makes sure we get here with the + * device powered on. So in case we change our freeze logic and keep + * the device powered we can also remove the following set power state + * call. + */ + ret = pci_set_power_state(dev->pdev, PCI_D0); + if (ret) { + DRM_ERROR("failed to set PCI D0 power state (%d)\n", ret); + goto out; + } + + /* + * Note that pci_enable_device() first enables any parent bridge + * device and only then sets the power state for this device. The + * bridge enabling is a nop though, since bridge devices are resumed + * first. The order of enabling power and enabling the device is + * imposed by the PCI core as described above, so here we preserve the + * same order for the freeze/thaw phases. + * + * TODO: eventually we should remove pci_disable_device() / + * pci_enable_enable_device() from suspend/resume. Due to how they + * depend on the device enable refcount we can't anyway depend on them + * disabling/enabling the device. + */ if (pci_enable_device(dev->pdev)) { ret = -EIO; goto out; -- cgit v1.2.3 From 5eaa60c7109b40f17ac81090bc8b90482da76cd1 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 18 Apr 2016 10:04:21 +0300 Subject: drm/i915/ddi: Fix eDP VDD handling during booting and suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver's VDD on/off logic assumes that whenever the VDD is on we also hold an AUX power domain reference. Since BIOS can leave the VDD on during booting and resuming and on DDI platforms we won't take a corresponding power reference, the above assumption won't hold on those platforms and an eventual delayed VDD off work will do an extraneous AUX power domain put resulting in a refcount underflow. Fix this the same way we did this for non-DDI DP encoders: commit 6d93c0c41760c0 ("drm/i915: fix VDD state tracking after system resume") At the same time call the DP encoder suspend handler the same way as the non-DDI DP encoders do to flush any pending VDD off work. Leaving the work running may cause a HW access where we don't expect this (at a point where power domains are suspended already). While at it remove an unnecessary function call indirection. This fixed for me AUX refcount underflow problems on BXT during suspend/resume. CC: Ville Syrjälä CC: stable@vger.kernel.org Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1460963062-13211-4-git-send-email-imre.deak@intel.com (cherry picked from commit bf93ba67e9c05882f05b7ca2d773cfc8bf462c2a) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ddi.c | 10 +++------- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- drivers/gpu/drm/i915/intel_drv.h | 2 ++ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 62de9f4bce09..94e6deb4b910 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3201,12 +3201,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder, intel_ddi_clock_get(encoder, pipe_config); } -static void intel_ddi_destroy(struct drm_encoder *encoder) -{ - /* HDMI has nothing special to destroy, so we can go with this. */ - intel_dp_encoder_destroy(encoder); -} - static bool intel_ddi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { @@ -3225,7 +3219,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder, } static const struct drm_encoder_funcs intel_ddi_funcs = { - .destroy = intel_ddi_destroy, + .reset = intel_dp_encoder_reset, + .destroy = intel_dp_encoder_destroy, }; static struct intel_connector * @@ -3324,6 +3319,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) intel_encoder->post_disable = intel_ddi_post_disable; intel_encoder->get_hw_state = intel_ddi_get_hw_state; intel_encoder->get_config = intel_ddi_get_config; + intel_encoder->suspend = intel_dp_encoder_suspend; intel_dig_port->port = port; intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f069a82deb57..412a34c39522 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4898,7 +4898,7 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) kfree(intel_dig_port); } -static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) +void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); @@ -4940,7 +4940,7 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) edp_panel_vdd_schedule_off(intel_dp); } -static void intel_dp_encoder_reset(struct drm_encoder *encoder) +void intel_dp_encoder_reset(struct drm_encoder *encoder) { struct intel_dp *intel_dp; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4c027d69fac9..7d3af3a72abe 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1238,6 +1238,8 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp, void intel_dp_start_link_train(struct intel_dp *intel_dp); void intel_dp_stop_link_train(struct intel_dp *intel_dp); void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); +void intel_dp_encoder_reset(struct drm_encoder *encoder); +void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder); void intel_dp_encoder_destroy(struct drm_encoder *encoder); int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc); bool intel_dp_compute_config(struct intel_encoder *encoder, -- cgit v1.2.3 From 992e7a41f9fcc7bcd10e7d346aee5ed7a2c241cb Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Wed, 20 Apr 2016 15:39:02 +0300 Subject: drm/i915: Fix eDP low vswing for Broadwell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was noticed on bug #94087 that module parameter i915.edp_vswing=2 that should override the VBT setting to use default voltage swing (400 mV) was not applied for Broadwell. This patch provides a fix for this by checking if default i.e. higher voltage swing is requested to be used and applies the DDI translations table for DP instead of eDP (low vswing) table. v2: Combine two if statements into one (Jani) v3: Change dev_priv->edp_low_vswing to use dev_priv->vbt.edp.low_vswing Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94087 Signed-off-by: Mika Kahola Link: http://patchwork.freedesktop.org/patch/msgid/1461155942-7749-1-git-send-email-mika.kahola@intel.com Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä (cherry picked from commit 00983519214b61c1b9371ec2ed55a4dde773e384) [Jani: s/dev_priv->vbt.edp.low_vswing/dev_priv->edp_low_vswing/ to backport] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ddi.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 94e6deb4b910..3b57bf06abe8 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -443,9 +443,17 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) } else if (IS_BROADWELL(dev_priv)) { ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; - ddi_translations_edp = bdw_ddi_translations_edp; + + if (dev_priv->edp_low_vswing) { + ddi_translations_edp = bdw_ddi_translations_edp; + n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); + } else { + ddi_translations_edp = bdw_ddi_translations_dp; + n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); + } + ddi_translations_hdmi = bdw_ddi_translations_hdmi; - n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); + n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); hdmi_default_entry = 7; -- cgit v1.2.3 From 60b3143c7cac7e8d2ca65c0b347466c5776395d1 Mon Sep 17 00:00:00 2001 From: Shashank Sharma Date: Thu, 21 Apr 2016 16:48:32 +0530 Subject: drm/i915: Fake HDMI live status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch does the following: - Fakes live status of HDMI as connected (even if that's not). While testing certain (monitor + cable) combinations with various intel platforms, it seems that live status register doesn't work reliably on some older devices. So limit the live_status check for HDMI detection, only for platforms from gen7 onwards. V2: restrict faking live_status to certain platforms V3: (Ville) - keep the debug message for !live_status case - fix indentation of comment - remove "warning" from the debug message (Jani) - Change format of fix details in the commit message Fixes: 237ed86c693d ("drm/i915: Check live status before reading edid") Cc: stable@vger.kernel.org # v4.4 Suggested-by: Ville Syrjala Signed-off-by: Shashank Sharma Link: http://patchwork.freedesktop.org/patch/msgid/1461237606-16491-1-git-send-email-shashank.sharma@intel.com Signed-off-by: Ville Syrjälä (cherry picked from commit 4f4a8185011773f7520d9916c6857db946e7f9d1) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_hdmi.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index a0d8daed2470..1ab6f687f640 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1415,8 +1415,16 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) hdmi_to_dig_port(intel_hdmi)); } - if (!live_status) - DRM_DEBUG_KMS("Live status not up!"); + if (!live_status) { + DRM_DEBUG_KMS("HDMI live status down\n"); + /* + * Live status register is not reliable on all intel platforms. + * So consider live_status only for certain platforms, for + * others, read EDID to determine presence of sink. + */ + if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv)) + live_status = true; + } intel_hdmi_unset_edid(connector); -- cgit v1.2.3 From 4ea3959018d09edfa36a9e7b5ccdbd4ec4b99e49 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 20 Apr 2016 16:43:56 +0300 Subject: drm/i915: Make RPS EI/thresholds multiple of 25 on SNB-BDW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Somehow my SNB GT1 (Dell XPS 8300) gets very unhappy around GPU hangs if the RPS EI/thresholds aren't suitably aligned. It seems like scheduling/timer interupts stop working somehow and things get stuck eg. in usleep_range(). I bisected the problem down to commit 8a5864377b12 ("drm/i915/skl: Restructured the gen6_set_rps_thresholds function") I observed that before all the values were at least multiples of 25, but afterwards they are not. And rounding things up to the next multiple of 25 does seem to help, so lets' do that. I also tried roundup(..., 5) but that wasn't sufficient. Also I have no idea if we might need this sort of thing on gen9+ as well. These are the original EI/thresholds: LOW_POWER GEN6_RP_UP_EI 12500 GEN6_RP_UP_THRESHOLD 11800 GEN6_RP_DOWN_EI 25000 GEN6_RP_DOWN_THRESHOLD 21250 BETWEEN GEN6_RP_UP_EI 10250 GEN6_RP_UP_THRESHOLD 9225 GEN6_RP_DOWN_EI 25000 GEN6_RP_DOWN_THRESHOLD 18750 HIGH_POWER GEN6_RP_UP_EI 8000 GEN6_RP_UP_THRESHOLD 6800 GEN6_RP_DOWN_EI 25000 GEN6_RP_DOWN_THRESHOLD 15000 These are after 8a5864377b12: LOW_POWER GEN6_RP_UP_EI 12500 GEN6_RP_UP_THRESHOLD 11875 GEN6_RP_DOWN_EI 25000 GEN6_RP_DOWN_THRESHOLD 21250 BETWEEN GEN6_RP_UP_EI 10156 GEN6_RP_UP_THRESHOLD 9140 GEN6_RP_DOWN_EI 25000 GEN6_RP_DOWN_THRESHOLD 18750 HIGH_POWER GEN6_RP_UP_EI 7812 GEN6_RP_UP_THRESHOLD 6640 GEN6_RP_DOWN_EI 25000 GEN6_RP_DOWN_THRESHOLD 15000 And these are what we have after this patch: LOW_POWER GEN6_RP_UP_EI 12500 GEN6_RP_UP_THRESHOLD 11875 GEN6_RP_DOWN_EI 25000 GEN6_RP_DOWN_THRESHOLD 21250 BETWEEN GEN6_RP_UP_EI 10175 GEN6_RP_UP_THRESHOLD 9150 GEN6_RP_DOWN_EI 25000 GEN6_RP_DOWN_THRESHOLD 18750 HIGH_POWER GEN6_RP_UP_EI 7825 GEN6_RP_UP_THRESHOLD 6650 GEN6_RP_DOWN_EI 25000 GEN6_RP_DOWN_THRESHOLD 15000 Cc: stable@vger.kernel.org Cc: Akash Goel Cc: Chris Wilson Testcase: igt/kms_pipe_crc_basic/hang-read-crc-pipe-B Fixes: 8a5864377b12 ("drm/i915/skl: Restructured the gen6_set_rps_thresholds function") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1461159836-9108-1-git-send-email-ville.syrjala@linux.intel.com Acked-by: Chris Wilson Reviewed-by: Patrik Jakobsson (cherry picked from commit 8a292d016d1cc4938ff14b4df25328230b08a408) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f76cbf3e5d1e..fffdac801d3b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2907,7 +2907,14 @@ enum skl_disp_power_wells { #define GEN6_RP_STATE_CAP _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998) #define BXT_RP_STATE_CAP _MMIO(0x138170) -#define INTERVAL_1_28_US(us) (((us) * 100) >> 7) +/* + * Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS + * 8300) freezing up around GPU hangs. Looks as if even + * scheduling/timer interrupts start misbehaving if the RPS + * EI/thresholds are "bad", leading to a very sluggish or even + * frozen machine. + */ +#define INTERVAL_1_28_US(us) roundup(((us) * 100) >> 7, 25) #define INTERVAL_1_33_US(us) (((us) * 3) >> 2) #define INTERVAL_0_833_US(us) (((us) * 6) / 5) #define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \ -- cgit v1.2.3 From e6436be21e77e3659b4ff7e357ab5a8342d132d2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Apr 2016 13:47:08 +0200 Subject: mac80211: fix statistics leak if dev_alloc_name() fails In the case that dev_alloc_name() fails, e.g. because the name was given by the user and already exists, we need to clean up properly and free the per-CPU statistics. Fix that. Cc: stable@vger.kernel.org Fixes: 5a490510ba5f ("mac80211: use per-CPU TX/RX statistics") Signed-off-by: Johannes Berg --- net/mac80211/iface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 453b4e741780..e1cb22c16530 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1761,7 +1761,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, ret = dev_alloc_name(ndev, ndev->name); if (ret < 0) { - free_netdev(ndev); + ieee80211_if_free(ndev); return ret; } @@ -1847,7 +1847,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, ret = register_netdevice(ndev); if (ret) { - free_netdev(ndev); + ieee80211_if_free(ndev); return ret; } } -- cgit v1.2.3 From a8950e49bd241dc9ad90c24e92e23e95dbe9f018 Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Tue, 19 Apr 2016 18:17:32 +0800 Subject: nios2: memset: use the right constraint modifier for the %4 output operand Depending on the size of the area to be memset'ed, the nios2 memset implementation either uses a naive loop (for buffers smaller or equal than 8 bytes) or a more optimized implementation (for buffers larger than 8 bytes). This implementation does 4-byte stores rather than 1-byte stores to speed up memset. However, we discovered that on our nios2 platform, memset() was not properly setting the buffer to the expected value. A memset of 0xff would not set the entire buffer to 0xff, but to: 0xff 0x00 0xff 0x00 0xff 0x00 0xff 0x00 ... Which is obviously incorrect. Our investigation has revealed that the problem lies in the incorrect constraints used in the inline assembly. The following piece of assembly, from the nios2 memset implementation, is supposed to create a 4-byte value that repeats 4 times the 1-byte pattern passed as memset argument: /* fill8 %3, %5 (c & 0xff) */ " slli %4, %5, 8\n" " or %4, %4, %5\n" " slli %3, %4, 16\n" " or %3, %3, %4\n" However, depending on the compiler and optimization level, this code might be compiled as: 34: 280a923a slli r5,r5,8 38: 294ab03a or r5,r5,r5 3c: 2808943a slli r4,r5,16 40: 2148b03a or r4,r4,r5 This is wrong because r5 gets used both for %5 and %4, which leads to the final pattern stored in r4 to be 0xff00ff00 rather than the expected 0xffffffff. %4 is defined with the "=r" constraint, i.e as an output operand. However, as explained in http://www.ethernut.de/en/documents/arm-inline-asm.html, this does not prevent gcc from using the same register for an output operand (%4) and input operand (%5). By using the constraint modifier '&', we indicate that the register should be used for output only. With this change, we get the following assembly output: 34: 2810923a slli r8,r5,8 38: 4150b03a or r8,r8,r5 3c: 400e943a slli r7,r8,16 40: 3a0eb03a or r7,r7,r8 Which correctly produces the 0xffffffff pattern when 0xff is passed as the memset() pattern. It is worth mentioning the observed consequence of this bug: we were hitting the kernel BUG() in mm/bootmem.c:__free() that verifies when marking a page as free that it was previously marked as occupied (i.e that the bit was set to 1). The entire bootmem bitmap is set to 0xff bit via a memset() during the bootmem initialization. The bootmem_free() call right after the initialization was finding some bits to be set to 0, which didn't make sense since the bitmap has just been memset'ed to 0xff. Except that due to the bug explained above, the bitmap was in fact initialized to 0xff00ff00. Thanks to Marek Vasut for his help and feedback. Signed-off-by: Romain Perier Acked-by: Marek Vasut Acked-by: Ley Foon Tan --- arch/nios2/lib/memset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/nios2/lib/memset.c b/arch/nios2/lib/memset.c index c2cfcb121e34..2fcefe720283 100644 --- a/arch/nios2/lib/memset.c +++ b/arch/nios2/lib/memset.c @@ -68,7 +68,7 @@ void *memset(void *s, int c, size_t count) "=r" (charcnt), /* %1 Output */ "=r" (dwordcnt), /* %2 Output */ "=r" (fill8reg), /* %3 Output */ - "=r" (wrkrega) /* %4 Output */ + "=&r" (wrkrega) /* %4 Output only */ : "r" (c), /* %5 Input */ "0" (s), /* %0 Input/Output */ "1" (count) /* %1 Input/Output */ -- cgit v1.2.3 From 32ed9a0e0ddcf58ef343bcb6ae44ee60d1ee31ce Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 26 Apr 2016 19:29:33 +0300 Subject: ARC: support generic per-device coherent dma mem Signed-off-by: Alexey Brodkin Cc: linux-kernel@vger.kernel.org Signed-off-by: Vineet Gupta --- arch/arc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 12d0284a46e5..28d47f8eb934 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -37,6 +37,7 @@ config ARC select OF_EARLY_FLATTREE select PERF_USE_VMALLOC select HAVE_DEBUG_STACKOVERFLOW + select HAVE_GENERIC_DMA_COHERENT config MIGHT_HAVE_PCI bool -- cgit v1.2.3 From 1b10cb21d888c021bedbe678f7c26aee1bf04ffa Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 26 Apr 2016 19:29:34 +0300 Subject: ARC: add support for reserved memory defined by device tree Enable reserved memory initialization from device tree. Signed-off-by: Alexey Brodkin Cc: Grant Likely Cc: Marek Szyprowski Cc: linux-kernel@vger.kernel.org Signed-off-by: Vineet Gupta --- arch/arc/Kconfig | 1 + arch/arc/mm/init.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 28d47f8eb934..ec4791ea6911 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -35,6 +35,7 @@ config ARC select NO_BOOTMEM select OF select OF_EARLY_FLATTREE + select OF_RESERVED_MEM select PERF_USE_VMALLOC select HAVE_DEBUG_STACKOVERFLOW select HAVE_GENERIC_DMA_COHERENT diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c index 7d2c4fbf4f22..5487d0b97400 100644 --- a/arch/arc/mm/init.c +++ b/arch/arc/mm/init.c @@ -13,6 +13,7 @@ #ifdef CONFIG_BLK_DEV_INITRD #include #endif +#include #include #include #include @@ -136,6 +137,9 @@ void __init setup_arch_memory(void) memblock_reserve(__pa(initrd_start), initrd_end - initrd_start); #endif + early_init_fdt_reserve_self(); + early_init_fdt_scan_reserved_mem(); + memblock_dump_all(); /*----------------- node/zones setup --------------------------*/ -- cgit v1.2.3 From 56fc350224f16901db709cd8cba86bac751aa2a2 Mon Sep 17 00:00:00 2001 From: Flora Cui Date: Wed, 20 Apr 2016 10:23:47 +0800 Subject: drm/ttm: fix kref count mess in ttm_bo_move_to_lru_tail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following scenario: 1. Page table bo allocated in vram and linked to man->lru. tbo->list_kref.refcount=2 2. Page table bo is swapped out and removed from man->lru. tbo->list_kref.refcount=1 3. Command submission from userspace. Page table bo is moved to vram. ttm_bo_move_to_lru_tail() link it to man->lru and don't increase the kref count. Reviewed-by: Thomas Hellstrom Signed-off-by: Flora Cui Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/ttm/ttm_bo.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 4cbf26555093..e3daafa1be13 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -230,22 +230,13 @@ EXPORT_SYMBOL(ttm_bo_del_sub_from_lru); void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo) { - struct ttm_bo_device *bdev = bo->bdev; - struct ttm_mem_type_manager *man; + int put_count = 0; lockdep_assert_held(&bo->resv->lock.base); - if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) { - list_del_init(&bo->swap); - list_del_init(&bo->lru); - - } else { - if (bo->ttm && !(bo->ttm->page_flags & TTM_PAGE_FLAG_SG)) - list_move_tail(&bo->swap, &bo->glob->swap_lru); - - man = &bdev->man[bo->mem.mem_type]; - list_move_tail(&bo->lru, &man->lru); - } + put_count = ttm_bo_del_from_lru(bo); + ttm_bo_list_ref_sub(bo, put_count, true); + ttm_bo_add_to_lru(bo); } EXPORT_SYMBOL(ttm_bo_move_to_lru_tail); -- cgit v1.2.3 From 5d5b7803c49bbb01bdf4c6e95e8314d0515b9484 Mon Sep 17 00:00:00 2001 From: Vitaly Prosyak Date: Thu, 14 Apr 2016 13:34:03 -0400 Subject: drm/radeon: fix vertical bars appear on monitor (v2) When crtc/timing is disabled on boot the dig block should be stopped in order ignore timing from crtc, reset the steering fifo otherwise we get display corruption or hung in dp sst mode. v2: agd: fix coding style Signed-off-by: Vitaly Prosyak Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen.c | 154 ++++++++++++++++++++++++++++++++- drivers/gpu/drm/radeon/evergreen_reg.h | 46 ++++++++++ 2 files changed, 199 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 76c4bdf21b20..34f7a29d9366 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2608,10 +2608,152 @@ static void evergreen_agp_enable(struct radeon_device *rdev) WREG32(VM_CONTEXT1_CNTL, 0); } +static const unsigned ni_dig_offsets[] = +{ + NI_DIG0_REGISTER_OFFSET, + NI_DIG1_REGISTER_OFFSET, + NI_DIG2_REGISTER_OFFSET, + NI_DIG3_REGISTER_OFFSET, + NI_DIG4_REGISTER_OFFSET, + NI_DIG5_REGISTER_OFFSET +}; + +static const unsigned ni_tx_offsets[] = +{ + NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1, + NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1, + NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1, + NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1, + NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1, + NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 +}; + +static const unsigned evergreen_dp_offsets[] = +{ + EVERGREEN_DP0_REGISTER_OFFSET, + EVERGREEN_DP1_REGISTER_OFFSET, + EVERGREEN_DP2_REGISTER_OFFSET, + EVERGREEN_DP3_REGISTER_OFFSET, + EVERGREEN_DP4_REGISTER_OFFSET, + EVERGREEN_DP5_REGISTER_OFFSET +}; + + +/* + * Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc + * We go from crtc to connector and it is not relible since it + * should be an opposite direction .If crtc is enable then + * find the dig_fe which selects this crtc and insure that it enable. + * if such dig_fe is found then find dig_be which selects found dig_be and + * insure that it enable and in DP_SST mode. + * if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing + * from dp symbols clocks . + */ +static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev, + unsigned crtc_id, unsigned *ret_dig_fe) +{ + unsigned i; + unsigned dig_fe; + unsigned dig_be; + unsigned dig_en_be; + unsigned uniphy_pll; + unsigned digs_fe_selected; + unsigned dig_be_mode; + unsigned dig_fe_mask; + bool is_enabled = false; + bool found_crtc = false; + + /* loop through all running dig_fe to find selected crtc */ + for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { + dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]); + if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON && + crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) { + /* found running pipe */ + found_crtc = true; + dig_fe_mask = 1 << i; + dig_fe = i; + break; + } + } + + if (found_crtc) { + /* loop through all running dig_be to find selected dig_fe */ + for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { + dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]); + /* if dig_fe_selected by dig_be? */ + digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be); + dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be); + if (dig_fe_mask & digs_fe_selected && + /* if dig_be in sst mode? */ + dig_be_mode == NI_DIG_BE_DPSST) { + dig_en_be = RREG32(NI_DIG_BE_EN_CNTL + + ni_dig_offsets[i]); + uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 + + ni_tx_offsets[i]); + /* dig_be enable and tx is running */ + if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE && + dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON && + uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) { + is_enabled = true; + *ret_dig_fe = dig_fe; + break; + } + } + } + } + + return is_enabled; +} + +/* + * Blank dig when in dp sst mode + * Dig ignores crtc timing + */ +static void evergreen_blank_dp_output(struct radeon_device *rdev, + unsigned dig_fe) +{ + unsigned stream_ctrl; + unsigned fifo_ctrl; + unsigned counter = 0; + + if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) { + DRM_ERROR("invalid dig_fe %d\n", dig_fe); + return; + } + + stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + + evergreen_dp_offsets[dig_fe]); + if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) { + DRM_ERROR("dig %d , should be enable\n", dig_fe); + return; + } + + stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE; + WREG32(EVERGREEN_DP_VID_STREAM_CNTL + + evergreen_dp_offsets[dig_fe], stream_ctrl); + + stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + + evergreen_dp_offsets[dig_fe]); + while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) { + msleep(1); + counter++; + stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + + evergreen_dp_offsets[dig_fe]); + } + if (counter >= 32 ) + DRM_ERROR("counter exceeds %d\n", counter); + + fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]); + fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET; + WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl); + +} + void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) { u32 crtc_enabled, tmp, frame_count, blackout; int i, j; + unsigned dig_fe; if (!ASIC_IS_NODCE(rdev)) { save->vga_render_control = RREG32(VGA_RENDER_CONTROL); @@ -2651,7 +2793,17 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav break; udelay(1); } - + /*we should disable dig if it drives dp sst*/ + /*but we are in radeon_device_init and the topology is unknown*/ + /*and it is available after radeon_modeset_init*/ + /*the following method radeon_atom_encoder_dpms_dig*/ + /*does the job if we initialize it properly*/ + /*for now we do it this manually*/ + /**/ + if (ASIC_IS_DCE5(rdev) && + evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe)) + evergreen_blank_dp_output(rdev, dig_fe); + /*we could remove 6 lines below*/ /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index aa939dfed3a3..b436badf9efa 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h @@ -250,8 +250,43 @@ /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ #define EVERGREEN_HDMI_BASE 0x7030 +/*DIG block*/ +#define NI_DIG0_REGISTER_OFFSET (0x7000 - 0x7000) +#define NI_DIG1_REGISTER_OFFSET (0x7C00 - 0x7000) +#define NI_DIG2_REGISTER_OFFSET (0x10800 - 0x7000) +#define NI_DIG3_REGISTER_OFFSET (0x11400 - 0x7000) +#define NI_DIG4_REGISTER_OFFSET (0x12000 - 0x7000) +#define NI_DIG5_REGISTER_OFFSET (0x12C00 - 0x7000) + + +#define NI_DIG_FE_CNTL 0x7000 +# define NI_DIG_FE_CNTL_SOURCE_SELECT(x) ((x) & 0x3) +# define NI_DIG_FE_CNTL_SYMCLK_FE_ON (1<<24) + + +#define NI_DIG_BE_CNTL 0x7140 +# define NI_DIG_BE_CNTL_FE_SOURCE_SELECT(x) (((x) >> 8 ) & 0x3F) +# define NI_DIG_FE_CNTL_MODE(x) (((x) >> 16) & 0x7 ) + +#define NI_DIG_BE_EN_CNTL 0x7144 +# define NI_DIG_BE_EN_CNTL_ENABLE (1 << 0) +# define NI_DIG_BE_EN_CNTL_SYMBCLK_ON (1 << 8) +# define NI_DIG_BE_DPSST 0 /* Display Port block */ +#define EVERGREEN_DP0_REGISTER_OFFSET (0x730C - 0x730C) +#define EVERGREEN_DP1_REGISTER_OFFSET (0x7F0C - 0x730C) +#define EVERGREEN_DP2_REGISTER_OFFSET (0x10B0C - 0x730C) +#define EVERGREEN_DP3_REGISTER_OFFSET (0x1170C - 0x730C) +#define EVERGREEN_DP4_REGISTER_OFFSET (0x1230C - 0x730C) +#define EVERGREEN_DP5_REGISTER_OFFSET (0x12F0C - 0x730C) + + +#define EVERGREEN_DP_VID_STREAM_CNTL 0x730C +# define EVERGREEN_DP_VID_STREAM_CNTL_ENABLE (1 << 0) +# define EVERGREEN_DP_VID_STREAM_STATUS (1 <<16) +#define EVERGREEN_DP_STEER_FIFO 0x7310 +# define EVERGREEN_DP_STEER_FIFO_RESET (1 << 0) #define EVERGREEN_DP_SEC_CNTL 0x7280 # define EVERGREEN_DP_SEC_STREAM_ENABLE (1 << 0) # define EVERGREEN_DP_SEC_ASP_ENABLE (1 << 4) @@ -266,4 +301,15 @@ # define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x) (((x) & 0xf) << 24) # define EVERGREEN_DP_SEC_SS_EN (1 << 28) +/*DCIO_UNIPHY block*/ +#define NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1 (0x6600 -0x6600) +#define NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1 (0x6640 -0x6600) +#define NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1 (0x6680 - 0x6600) +#define NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1 (0x66C0 - 0x6600) +#define NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1 (0x6700 - 0x6600) +#define NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 (0x6740 - 0x6600) + +#define NI_DCIO_UNIPHY0_PLL_CONTROL1 0x6618 +# define NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE (1 << 0) + #endif -- cgit v1.2.3 From e9bef455af8eb0e837e179aab8988ae2649fd8d3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 25 Apr 2016 13:12:18 -0400 Subject: Revert "drm/amdgpu: disable runtime pm on PX laptops without dGPU power control" This reverts commit bedf2a65c1aa8fb29ba8527fd00c0f68ec1f55f1. See the radeon revert for an extended description. Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 +------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 0020a0ea43ff..fa948dcbdd5d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -63,10 +63,6 @@ bool amdgpu_has_atpx(void) { return amdgpu_atpx_priv.atpx_detected; } -bool amdgpu_has_atpx_dgpu_power_cntl(void) { - return amdgpu_atpx_priv.atpx.functions.power_cntl; -} - /** * amdgpu_atpx_call - call an ATPX method * @@ -146,6 +142,10 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas */ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) { + /* make sure required functions are enabled */ + /* dGPU power control is required */ + atpx->functions.power_cntl = true; + if (atpx->functions.px_params) { union acpi_object *info; struct atpx_px_params output; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 612117478b57..2139da773da6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -62,12 +62,6 @@ static const char *amdgpu_asic_name[] = { "LAST", }; -#if defined(CONFIG_VGA_SWITCHEROO) -bool amdgpu_has_atpx_dgpu_power_cntl(void); -#else -static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; } -#endif - bool amdgpu_device_is_px(struct drm_device *dev) { struct amdgpu_device *adev = dev->dev_private; @@ -1485,7 +1479,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, if (amdgpu_runtime_pm == 1) runtime = true; - if (amdgpu_device_is_px(ddev) && amdgpu_has_atpx_dgpu_power_cntl()) + if (amdgpu_device_is_px(ddev)) runtime = true; vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime); if (runtime) -- cgit v1.2.3 From c8791a13d28161a1fa1138112dfe1f986a1358cf Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 25 Apr 2016 13:14:47 -0400 Subject: drm/amdgpu: print a message if ATPX dGPU power control is missing It will help identify problematic boards. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index fa948dcbdd5d..35a1248aaa77 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -144,7 +144,10 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) { /* make sure required functions are enabled */ /* dGPU power control is required */ - atpx->functions.power_cntl = true; + if (atpx->functions.power_cntl == false) { + printk("ATPX dGPU power cntl not present, forcing\n"); + atpx->functions.power_cntl = true; + } if (atpx->functions.px_params) { union acpi_object *info; -- cgit v1.2.3 From afc4542105f2b5a3bc6f0f3530d7ccbc94ca90fb Mon Sep 17 00:00:00 2001 From: Flora Cui Date: Mon, 25 Apr 2016 16:06:17 +0800 Subject: drm/amdgpu: disable vm interrupts with vm_fault_stop=2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit V2: disable all vm interrupts in late_init() Signed-off-by: Flora Cui Reviewed-by: Ken Wang Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 5 ++++- drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 05b0353d3880..a4a2e6cc61bb 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -910,7 +910,10 @@ static int gmc_v7_0_late_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); + if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) + return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); + else + return 0; } static int gmc_v7_0_sw_init(void *handle) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 02deb3229405..7a9db2c72c89 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -870,7 +870,10 @@ static int gmc_v8_0_late_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); + if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) + return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); + else + return 0; } #define mmMC_SEQ_MISC0_FIJI 0xA71 -- cgit v1.2.3 From 1fa72e29e14d97fbda15437c648d7cc4eb00bff8 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 25 Apr 2016 02:30:49 -0400 Subject: bnxt_en: Don't fallback to INTA on VF. Only MSI-X can be used on a VF. The driver should fail initialization if it cannot successfully enable MSI-X. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 12a009d720cd..e787debab851 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -4309,7 +4309,7 @@ static int bnxt_setup_int_mode(struct bnxt *bp) if (bp->flags & BNXT_FLAG_MSIX_CAP) rc = bnxt_setup_msix(bp); - if (!(bp->flags & BNXT_FLAG_USING_MSIX)) { + if (!(bp->flags & BNXT_FLAG_USING_MSIX) && BNXT_PF(bp)) { /* fallback to INTA */ rc = bnxt_setup_inta(bp); } -- cgit v1.2.3 From 2839f28bd5bf8fd2ab4a1ea3a5589c8f94364cbb Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 25 Apr 2016 02:30:50 -0400 Subject: bnxt_en: Limit RX BD pages to be no bigger than 32K. The RX BD length field of this device is 16-bit, so the largest buffer size is 65535. For LRO and GRO, we allocate native CPU pages for the aggregation ring buffers. It won't work if the native CPU page size is 64K or bigger. We fix this by defining BNXT_RX_PAGE_SIZE to be native CPU page size up to 32K. Replace PAGE_SIZE with BNXT_RX_PAGE_SIZE in all appropriate places related to the rx aggregation ring logic. The next patch will add additional logic to divide the page into 32K chunks for aggrgation ring buffers if PAGE_SIZE is bigger than BNXT_RX_PAGE_SIZE. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 18 +++++++++--------- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 9 +++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index e787debab851..28480f6c6a08 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -586,7 +586,7 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, if (!page) return -ENOMEM; - mapping = dma_map_page(&pdev->dev, page, 0, PAGE_SIZE, + mapping = dma_map_page(&pdev->dev, page, 0, BNXT_RX_PAGE_SIZE, PCI_DMA_FROMDEVICE); if (dma_mapping_error(&pdev->dev, mapping)) { __free_page(page); @@ -740,7 +740,7 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi, return NULL; } - dma_unmap_page(&pdev->dev, mapping, PAGE_SIZE, + dma_unmap_page(&pdev->dev, mapping, BNXT_RX_PAGE_SIZE, PCI_DMA_FROMDEVICE); skb->data_len += frag_len; @@ -1584,7 +1584,7 @@ static void bnxt_free_rx_skbs(struct bnxt *bp) dma_unmap_page(&pdev->dev, dma_unmap_addr(rx_agg_buf, mapping), - PAGE_SIZE, PCI_DMA_FROMDEVICE); + BNXT_RX_PAGE_SIZE, PCI_DMA_FROMDEVICE); rx_agg_buf->page = NULL; __clear_bit(j, rxr->rx_agg_bmap); @@ -1973,7 +1973,7 @@ static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr) if (!(bp->flags & BNXT_FLAG_AGG_RINGS)) return 0; - type = ((u32)PAGE_SIZE << RX_BD_LEN_SHIFT) | + type = ((u32)BNXT_RX_PAGE_SIZE << RX_BD_LEN_SHIFT) | RX_BD_TYPE_RX_AGG_BD | RX_BD_FLAGS_SOP; bnxt_init_rxbd_pages(ring, type); @@ -2164,7 +2164,7 @@ void bnxt_set_ring_params(struct bnxt *bp) bp->rx_agg_nr_pages = 0; if (bp->flags & BNXT_FLAG_TPA) - agg_factor = 4; + agg_factor = min_t(u32, 4, 65536 / BNXT_RX_PAGE_SIZE); bp->flags &= ~BNXT_FLAG_JUMBO; if (rx_space > PAGE_SIZE) { @@ -3020,12 +3020,12 @@ static int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, u16 vnic_id, u32 tpa_flags) /* Number of segs are log2 units, and first packet is not * included as part of this units. */ - if (mss <= PAGE_SIZE) { - n = PAGE_SIZE / mss; + if (mss <= BNXT_RX_PAGE_SIZE) { + n = BNXT_RX_PAGE_SIZE / mss; nsegs = (MAX_SKB_FRAGS - 1) * n; } else { - n = mss / PAGE_SIZE; - if (mss & (PAGE_SIZE - 1)) + n = mss / BNXT_RX_PAGE_SIZE; + if (mss & (BNXT_RX_PAGE_SIZE - 1)) n++; nsegs = (MAX_SKB_FRAGS - n) / n; } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 709b95b8fcba..0cf1e2a73179 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -407,6 +407,15 @@ struct rx_tpa_end_cmp_ext { #define BNXT_PAGE_SIZE (1 << BNXT_PAGE_SHIFT) +/* The RXBD length is 16-bit so we can only support page sizes < 64K */ +#if (PAGE_SHIFT > 15) +#define BNXT_RX_PAGE_SHIFT 15 +#else +#define BNXT_RX_PAGE_SHIFT PAGE_SHIFT +#endif + +#define BNXT_RX_PAGE_SIZE (1 << BNXT_RX_PAGE_SHIFT) + #define BNXT_MIN_PKT_SIZE 45 #define BNXT_NUM_TESTS(bp) 0 -- cgit v1.2.3 From 89d0a06c516339c0a2b3d02677f5d6310b3319fb Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 25 Apr 2016 02:30:51 -0400 Subject: bnxt_en: Divide a page into 32K buffers for the aggregation ring if necessary. If PAGE_SIZE is bigger than BNXT_RX_PAGE_SIZE, that means the native CPU page is bigger than the maximum length of the RX BD. Divide the page into multiple 32K buffers for the aggregation ring. Add an offset field in the bnxt_sw_rx_agg_bd struct to keep track of the page offset of each buffer. Since each page can be referenced by multiple buffer entries, call get_page() as needed to get the proper reference count. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 35 ++++++++++++++++++++++++++----- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 4 ++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 28480f6c6a08..72eb29ed0359 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -581,12 +581,30 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, struct page *page; dma_addr_t mapping; u16 sw_prod = rxr->rx_sw_agg_prod; + unsigned int offset = 0; - page = alloc_page(gfp); - if (!page) - return -ENOMEM; + if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) { + page = rxr->rx_page; + if (!page) { + page = alloc_page(gfp); + if (!page) + return -ENOMEM; + rxr->rx_page = page; + rxr->rx_page_offset = 0; + } + offset = rxr->rx_page_offset; + rxr->rx_page_offset += BNXT_RX_PAGE_SIZE; + if (rxr->rx_page_offset == PAGE_SIZE) + rxr->rx_page = NULL; + else + get_page(page); + } else { + page = alloc_page(gfp); + if (!page) + return -ENOMEM; + } - mapping = dma_map_page(&pdev->dev, page, 0, BNXT_RX_PAGE_SIZE, + mapping = dma_map_page(&pdev->dev, page, offset, BNXT_RX_PAGE_SIZE, PCI_DMA_FROMDEVICE); if (dma_mapping_error(&pdev->dev, mapping)) { __free_page(page); @@ -601,6 +619,7 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, rxr->rx_sw_agg_prod = NEXT_RX_AGG(sw_prod); rx_agg_buf->page = page; + rx_agg_buf->offset = offset; rx_agg_buf->mapping = mapping; rxbd->rx_bd_haddr = cpu_to_le64(mapping); rxbd->rx_bd_opaque = sw_prod; @@ -642,6 +661,7 @@ static void bnxt_reuse_rx_agg_bufs(struct bnxt_napi *bnapi, u16 cp_cons, page = cons_rx_buf->page; cons_rx_buf->page = NULL; prod_rx_buf->page = page; + prod_rx_buf->offset = cons_rx_buf->offset; prod_rx_buf->mapping = cons_rx_buf->mapping; @@ -709,7 +729,8 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi, RX_AGG_CMP_LEN) >> RX_AGG_CMP_LEN_SHIFT; cons_rx_buf = &rxr->rx_agg_ring[cons]; - skb_fill_page_desc(skb, i, cons_rx_buf->page, 0, frag_len); + skb_fill_page_desc(skb, i, cons_rx_buf->page, + cons_rx_buf->offset, frag_len); __clear_bit(cons, rxr->rx_agg_bmap); /* It is possible for bnxt_alloc_rx_page() to allocate @@ -1591,6 +1612,10 @@ static void bnxt_free_rx_skbs(struct bnxt *bp) __free_page(page); } + if (rxr->rx_page) { + __free_page(rxr->rx_page); + rxr->rx_page = NULL; + } } } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 0cf1e2a73179..8b823ff558ff 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -515,6 +515,7 @@ struct bnxt_sw_rx_bd { struct bnxt_sw_rx_agg_bd { struct page *page; + unsigned int offset; dma_addr_t mapping; }; @@ -595,6 +596,9 @@ struct bnxt_rx_ring_info { unsigned long *rx_agg_bmap; u16 rx_agg_bmap_size; + struct page *rx_page; + unsigned int rx_page_offset; + dma_addr_t rx_desc_mapping[MAX_RX_PAGES]; dma_addr_t rx_agg_desc_mapping[MAX_RX_AGG_PAGES]; -- cgit v1.2.3 From 49fa5230462f9f2c4e97c81356473a6bdf06c422 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Apr 2016 17:27:37 -0400 Subject: sparc64: Fix bootup regressions on some Kconfig combinations. The system call tracing bug fix mentioned in the Fixes tag below increased the amount of assembler code in the sequence of assembler files included by head_64.S This caused to total set of code to exceed 0x4000 bytes in size, which overflows the expression in head_64.S that works to place swapper_tsb at address 0x408000. When this is violated, the TSB is not properly aligned, and also the trap table is not aligned properly either. All of this together results in failed boots. So, do two things: 1) Simplify some code by using ba,a instead of ba/nop to get those bytes back. 2) Add a linker script assertion to make sure that if this happens again the build will fail. Fixes: 1a40b95374f6 ("sparc: Fix system call tracing register handling.") Reported-by: Meelis Roos Reported-by: Joerg Abraham Signed-off-by: David S. Miller --- arch/sparc/kernel/cherrs.S | 14 +++++--------- arch/sparc/kernel/fpu_traps.S | 11 +++++------ arch/sparc/kernel/head_64.S | 24 ++++++++---------------- arch/sparc/kernel/misctrap.S | 12 ++++-------- arch/sparc/kernel/spiterrs.S | 18 ++++++------------ arch/sparc/kernel/utrap.S | 3 +-- arch/sparc/kernel/vmlinux.lds.S | 4 ++++ arch/sparc/kernel/winfixup.S | 3 +-- 8 files changed, 34 insertions(+), 55 deletions(-) diff --git a/arch/sparc/kernel/cherrs.S b/arch/sparc/kernel/cherrs.S index 4ee1ad420862..655628def68e 100644 --- a/arch/sparc/kernel/cherrs.S +++ b/arch/sparc/kernel/cherrs.S @@ -214,8 +214,7 @@ do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ subcc %g1, %g2, %g1 ! Next cacheline bge,pt %icc, 1b nop - ba,pt %xcc, dcpe_icpe_tl1_common - nop + ba,a,pt %xcc, dcpe_icpe_tl1_common do_dcpe_tl1_fatal: sethi %hi(1f), %g7 @@ -224,8 +223,7 @@ do_dcpe_tl1_fatal: mov 0x2, %o0 call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_dcpe_tl1,.-do_dcpe_tl1 .globl do_icpe_tl1 @@ -259,8 +257,7 @@ do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ subcc %g1, %g2, %g1 bge,pt %icc, 1b nop - ba,pt %xcc, dcpe_icpe_tl1_common - nop + ba,a,pt %xcc, dcpe_icpe_tl1_common do_icpe_tl1_fatal: sethi %hi(1f), %g7 @@ -269,8 +266,7 @@ do_icpe_tl1_fatal: mov 0x3, %o0 call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_icpe_tl1,.-do_icpe_tl1 .type dcpe_icpe_tl1_common,#function @@ -456,7 +452,7 @@ __cheetah_log_error: cmp %g2, 0x63 be c_cee nop - ba,pt %xcc, c_deferred + ba,a,pt %xcc, c_deferred .size __cheetah_log_error,.-__cheetah_log_error /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc diff --git a/arch/sparc/kernel/fpu_traps.S b/arch/sparc/kernel/fpu_traps.S index a6864826a4bd..336d2750fe78 100644 --- a/arch/sparc/kernel/fpu_traps.S +++ b/arch/sparc/kernel/fpu_traps.S @@ -100,8 +100,8 @@ do_fpdis: fmuld %f0, %f2, %f26 faddd %f0, %f2, %f28 fmuld %f0, %f2, %f30 - b,pt %xcc, fpdis_exit - nop + ba,a,pt %xcc, fpdis_exit + 2: andcc %g5, FPRS_DU, %g0 bne,pt %icc, 3f fzero %f32 @@ -144,8 +144,8 @@ do_fpdis: fmuld %f32, %f34, %f58 faddd %f32, %f34, %f60 fmuld %f32, %f34, %f62 - ba,pt %xcc, fpdis_exit - nop + ba,a,pt %xcc, fpdis_exit + 3: mov SECONDARY_CONTEXT, %g3 add %g6, TI_FPREGS, %g1 @@ -197,8 +197,7 @@ fpdis_exit2: fp_other_bounce: call do_fpother add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size fp_other_bounce,.-fp_other_bounce .align 32 diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 5b4f5c363674..a076b4249e62 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -466,9 +466,8 @@ sun4v_chip_type: subcc %g3, 1, %g3 bne,pt %xcc, 41b add %g1, 1, %g1 - mov SUN4V_CHIP_SPARC64X, %g4 ba,pt %xcc, 5f - nop + mov SUN4V_CHIP_SPARC64X, %g4 49: mov SUN4V_CHIP_UNKNOWN, %g4 @@ -553,8 +552,7 @@ sun4u_init: stxa %g0, [%g7] ASI_DMMU membar #Sync - ba,pt %xcc, sun4u_continue - nop + ba,a,pt %xcc, sun4u_continue sun4v_init: /* Set ctx 0 */ @@ -565,14 +563,12 @@ sun4v_init: mov SECONDARY_CONTEXT, %g7 stxa %g0, [%g7] ASI_MMU membar #Sync - ba,pt %xcc, niagara_tlb_fixup - nop + ba,a,pt %xcc, niagara_tlb_fixup sun4u_continue: BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup) - ba,pt %xcc, spitfire_tlb_fixup - nop + ba,a,pt %xcc, spitfire_tlb_fixup niagara_tlb_fixup: mov 3, %g2 /* Set TLB type to hypervisor. */ @@ -647,8 +643,7 @@ niagara_patch: call hypervisor_patch_cachetlbops nop - ba,pt %xcc, tlb_fixup_done - nop + ba,a,pt %xcc, tlb_fixup_done cheetah_tlb_fixup: mov 2, %g2 /* Set TLB type to cheetah+. */ @@ -667,8 +662,7 @@ cheetah_tlb_fixup: call cheetah_patch_cachetlbops nop - ba,pt %xcc, tlb_fixup_done - nop + ba,a,pt %xcc, tlb_fixup_done spitfire_tlb_fixup: /* Set TLB type to spitfire. */ @@ -782,8 +776,7 @@ setup_trap_table: call %o1 add %sp, (2047 + 128), %o0 - ba,pt %xcc, 2f - nop + ba,a,pt %xcc, 2f 1: sethi %hi(sparc64_ttable_tl0), %o0 set prom_set_trap_table_name, %g2 @@ -822,8 +815,7 @@ setup_trap_table: BRANCH_IF_ANY_CHEETAH(o2, o3, 1f) - ba,pt %xcc, 2f - nop + ba,a,pt %xcc, 2f /* Disable STICK_INT interrupts. */ 1: diff --git a/arch/sparc/kernel/misctrap.S b/arch/sparc/kernel/misctrap.S index 753b4f031bfb..34b4933900bf 100644 --- a/arch/sparc/kernel/misctrap.S +++ b/arch/sparc/kernel/misctrap.S @@ -18,8 +18,7 @@ __do_privact: 109: or %g7, %lo(109b), %g7 call do_privact add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __do_privact,.-__do_privact .type do_mna,#function @@ -46,8 +45,7 @@ do_mna: mov %l5, %o2 call mem_address_unaligned add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_mna,.-do_mna .type do_lddfmna,#function @@ -65,8 +63,7 @@ do_lddfmna: mov %l5, %o2 call handle_lddfmna add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_lddfmna,.-do_lddfmna .type do_stdfmna,#function @@ -84,8 +81,7 @@ do_stdfmna: mov %l5, %o2 call handle_stdfmna add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_stdfmna,.-do_stdfmna .type breakpoint_trap,#function diff --git a/arch/sparc/kernel/spiterrs.S b/arch/sparc/kernel/spiterrs.S index c357e40ffd01..4a73009f66a5 100644 --- a/arch/sparc/kernel/spiterrs.S +++ b/arch/sparc/kernel/spiterrs.S @@ -85,8 +85,7 @@ __spitfire_cee_trap_continue: ba,pt %xcc, etraptl1 rd %pc, %g7 - ba,pt %xcc, 2f - nop + ba,a,pt %xcc, 2f 1: ba,pt %xcc, etrap_irq rd %pc, %g7 @@ -100,8 +99,7 @@ __spitfire_cee_trap_continue: mov %l5, %o2 call spitfire_access_error add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_access_error,.-__spitfire_access_error /* This is the trap handler entry point for ECC correctable @@ -179,8 +177,7 @@ __spitfire_data_access_exception_tl1: mov %l5, %o2 call spitfire_data_access_exception_tl1 add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1 .type __spitfire_data_access_exception,#function @@ -200,8 +197,7 @@ __spitfire_data_access_exception: mov %l5, %o2 call spitfire_data_access_exception add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_data_access_exception,.-__spitfire_data_access_exception .type __spitfire_insn_access_exception_tl1,#function @@ -220,8 +216,7 @@ __spitfire_insn_access_exception_tl1: mov %l5, %o2 call spitfire_insn_access_exception_tl1 add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1 .type __spitfire_insn_access_exception,#function @@ -240,6 +235,5 @@ __spitfire_insn_access_exception: mov %l5, %o2 call spitfire_insn_access_exception add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception diff --git a/arch/sparc/kernel/utrap.S b/arch/sparc/kernel/utrap.S index b7f0f3f3a909..c731e8023d3e 100644 --- a/arch/sparc/kernel/utrap.S +++ b/arch/sparc/kernel/utrap.S @@ -11,8 +11,7 @@ utrap_trap: /* %g3=handler,%g4=level */ mov %l4, %o1 call bad_trap add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap invoke_utrap: sllx %g3, 3, %g3 diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index aadd321aa05d..7d02b1fef025 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -33,6 +33,10 @@ ENTRY(_start) jiffies = jiffies_64; #endif +#ifdef CONFIG_SPARC64 +ASSERT((swapper_tsb == 0x0000000000408000), "Error: sparc64 early assembler too large") +#endif + SECTIONS { #ifdef CONFIG_SPARC64 diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S index 1e67ce958369..855019a8590e 100644 --- a/arch/sparc/kernel/winfixup.S +++ b/arch/sparc/kernel/winfixup.S @@ -32,8 +32,7 @@ fill_fixup: rd %pc, %g7 call do_sparc64_fault add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap /* Be very careful about usage of the trap globals here. * You cannot touch %g5 as that has the fault information. -- cgit v1.2.3 From 0224a4a30b57385a60065aa598181868881d8fc6 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 27 Apr 2016 14:04:20 +0300 Subject: device property: Avoid potential dereferences of invalid pointers Since fwnode may hold ERR_PTR(-ENODEV) or it may be NULL, the fwnode type checks is_of_node(), is_acpi_node() and is is_pset_node() need to consider it. Using IS_ERR_OR_NULL() to check it. Fixes: 0d67e0fa1664 (device property: fix for a case of use-after-free) Reported-by: Dan Carpenter Signed-off-by: Heikki Krogerus [ rjw: Subject & changelog ] Signed-off-by: Rafael J. Wysocki --- drivers/base/property.c | 2 +- include/acpi/acpi_bus.h | 4 ++-- include/linux/of.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index 9b1a65debd49..7f692accdc90 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -21,7 +21,7 @@ static inline bool is_pset_node(struct fwnode_handle *fwnode) { - return fwnode && fwnode->type == FWNODE_PDATA; + return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_PDATA; } static inline struct property_set *to_pset_node(struct fwnode_handle *fwnode) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 14362a84c78e..3a932501d690 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -394,13 +394,13 @@ struct acpi_data_node { static inline bool is_acpi_node(struct fwnode_handle *fwnode) { - return fwnode && (fwnode->type == FWNODE_ACPI + return !IS_ERR_OR_NULL(fwnode) && (fwnode->type == FWNODE_ACPI || fwnode->type == FWNODE_ACPI_DATA); } static inline bool is_acpi_device_node(struct fwnode_handle *fwnode) { - return fwnode && fwnode->type == FWNODE_ACPI; + return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_ACPI; } static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode) diff --git a/include/linux/of.h b/include/linux/of.h index 7fcb681baadf..31758036787c 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -133,7 +133,7 @@ void of_core_init(void); static inline bool is_of_node(struct fwnode_handle *fwnode) { - return fwnode && fwnode->type == FWNODE_OF; + return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_OF; } static inline struct device_node *to_of_node(struct fwnode_handle *fwnode) -- cgit v1.2.3 From 5616f36713ea77f57ae908bf2fef641364403c9f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 20 Apr 2016 13:34:31 +0000 Subject: ARM: SoCFPGA: Fix secondary CPU startup in thumb2 kernel The secondary CPU starts up in ARM mode. When the kernel is compiled in thumb2 mode we have to explicitly compile the secondary startup trampoline in ARM mode, otherwise the CPU will go to Nirvana. Signed-off-by: Sascha Hauer Reported-by: Steffen Trumtrar Suggested-by: Ard Biesheuvel Cc: stable@vger.kernel.org Signed-off-by: Dinh Nguyen Signed-off-by: Kevin Hilman --- arch/arm/mach-socfpga/headsmp.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-socfpga/headsmp.S b/arch/arm/mach-socfpga/headsmp.S index 5d94b7a2fb10..c160fa3007e9 100644 --- a/arch/arm/mach-socfpga/headsmp.S +++ b/arch/arm/mach-socfpga/headsmp.S @@ -13,6 +13,7 @@ #include .arch armv7-a + .arm ENTRY(secondary_trampoline) /* CPU1 will always fetch from 0x0 when it is brought out of reset. -- cgit v1.2.3 From 82dc4afd7e65455464f0fc2fe6976efde54fe451 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Wed, 27 Apr 2016 14:36:05 -0700 Subject: misc: mic: Fix for double fetch security bug in VOP driver The MIC VOP driver does two successive reads from user space to read a variable length data structure. Kernel memory corruption can result if the data structure changes between the two reads. This patch disallows the chance of this happening. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=116651 Reported by: Pengfei Wang Reviewed-by: Sudeep Dutt Signed-off-by: Ashutosh Dixit Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mic/vop/vop_vringh.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/misc/mic/vop/vop_vringh.c b/drivers/misc/mic/vop/vop_vringh.c index e94c7fb6712a..88e45234d527 100644 --- a/drivers/misc/mic/vop/vop_vringh.c +++ b/drivers/misc/mic/vop/vop_vringh.c @@ -945,6 +945,11 @@ static long vop_ioctl(struct file *f, unsigned int cmd, unsigned long arg) ret = -EFAULT; goto free_ret; } + /* Ensure desc has not changed between the two reads */ + if (memcmp(&dd, dd_config, sizeof(dd))) { + ret = -EINVAL; + goto free_ret; + } mutex_lock(&vdev->vdev_mutex); mutex_lock(&vi->vop_mutex); ret = vop_virtio_add_device(vdev, dd_config); -- cgit v1.2.3 From 5fdfc48bb0da2aa8a912024a6ecca06486eb9141 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 29 Mar 2016 19:23:32 +0800 Subject: thermal: hisilicon: increase temperature resolution When calculate temperature, old code firstly do division and then convert to "millicelsius" unit. This will lose resolution and only can read back temperature with "Celsius" unit. So firstly scale step value to "millicelsius" and then do division, so finally we can increase resolution for temperature value. Also refine the calculation from temperature value to step value. Signed-off-by: Leo Yan Signed-off-by: Eduardo Valentin --- drivers/thermal/hisi_thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index 36d07295f8e3..5e820b541506 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -68,12 +68,12 @@ static inline int _step_to_temp(int step) * Every step equals (1 * 200) / 255 celsius, and finally * need convert to millicelsius. */ - return (HISI_TEMP_BASE + (step * 200 / 255)) * 1000; + return (HISI_TEMP_BASE * 1000 + (step * 200000 / 255)); } static inline long _temp_to_step(long temp) { - return ((temp / 1000 - HISI_TEMP_BASE) * 255 / 200); + return ((temp - HISI_TEMP_BASE * 1000) * 255) / 200000; } static long hisi_thermal_get_sensor_temp(struct hisi_thermal_data *data, -- cgit v1.2.3 From 15333e3af1de37b1b214b28c85fe9a7b257fb92c Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 29 Mar 2016 19:24:15 +0800 Subject: thermal: use %d to print S32 parameters Power allocator's parameters are S32 type, so use %d to print them. Acked-by: Javi Merino Signed-off-by: Leo Yan Signed-off-by: Eduardo Valentin --- drivers/thermal/thermal_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index f1db49625555..5133cd1e10b7 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -959,7 +959,7 @@ static DEVICE_ATTR(sustainable_power, S_IWUSR | S_IRUGO, sustainable_power_show, struct thermal_zone_device *tz = to_thermal_zone(dev); \ \ if (tz->tzp) \ - return sprintf(buf, "%u\n", tz->tzp->name); \ + return sprintf(buf, "%d\n", tz->tzp->name); \ else \ return -EIO; \ } \ -- cgit v1.2.3 From 1bdb8970392a68489b469c3a330a1adb5ef61beb Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 27 Apr 2016 14:22:32 -0600 Subject: x86/apic: Handle zero vector gracefully in clear_vector_irq() If x86_vector_alloc_irq() fails x86_vector_free_irqs() is invoked to cleanup the already allocated vectors. This subsequently calls clear_vector_irq(). The failed irq has no vector assigned, which triggers the BUG_ON(!vector) in clear_vector_irq(). We cannot suppress the call to x86_vector_free_irqs() for the failed interrupt, because the other data related to this irq must be cleaned up as well. So calling clear_vector_irq() with vector == 0 is legitimate. Remove the BUG_ON and return if vector is zero, [ tglx: Massaged changelog ] Fixes: b5dc8e6c21e7 "x86/irq: Use hierarchical irqdomain to manage CPU interrupt vectors" Signed-off-by: Keith Busch Cc: stable@vger.kernel.org Signed-off-by: Thomas Gleixner --- arch/x86/kernel/apic/vector.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index ad59d70bcb1a..ef495511f019 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -256,7 +256,8 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data) struct irq_desc *desc; int cpu, vector; - BUG_ON(!data->cfg.vector); + if (!data->cfg.vector) + return; vector = data->cfg.vector; for_each_cpu_and(cpu, data->domain, cpu_online_mask) -- cgit v1.2.3 From 811c6688774613a78bfa020f64b570b73f6974c8 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Fri, 15 Apr 2016 16:22:16 +0200 Subject: rbd: fix rbd map vs notify races A while ago, commit 9875201e1049 ("rbd: fix use-after free of rbd_dev->disk") fixed rbd unmap vs notify race by introducing an exported wrapper for flushing notifies and sticking it into do_rbd_remove(). A similar problem exists on the rbd map path, though: the watch is registered in rbd_dev_image_probe(), while the disk is set up quite a few steps later, in rbd_dev_device_setup(). Nothing prevents a notify from coming in and crashing on a NULL rbd_dev->disk: BUG: unable to handle kernel NULL pointer dereference at 0000000000000050 Call Trace: [] rbd_watch_cb+0x34/0x180 [rbd] [] do_event_work+0x40/0xb0 [libceph] [] process_one_work+0x17b/0x470 [] worker_thread+0x11b/0x400 [] ? rescuer_thread+0x400/0x400 [] kthread+0xcf/0xe0 [] ? finish_task_switch+0x53/0x170 [] ? kthread_create_on_node+0x140/0x140 [] ret_from_fork+0x58/0x90 [] ? kthread_create_on_node+0x140/0x140 RIP [] rbd_dev_refresh+0xfa/0x180 [rbd] If an error occurs during rbd map, we have to error out, potentially tearing down a watch. Just like on rbd unmap, notifies have to be flushed, otherwise rbd_watch_cb() may end up trying to read in the image header after rbd_dev_image_release() has run: Assertion failure in rbd_dev_header_info() at line 4722: rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); Call Trace: [] ? rbd_parent_request_create+0x150/0x150 [] rbd_dev_refresh+0x59/0x390 [] rbd_watch_cb+0x69/0x290 [] do_event_work+0x10f/0x1c0 [] process_one_work+0x689/0x1a80 [] ? process_one_work+0x5e7/0x1a80 [] ? finish_task_switch+0x225/0x640 [] ? pwq_dec_nr_in_flight+0x2b0/0x2b0 [] worker_thread+0xd9/0x1320 [] ? process_one_work+0x1a80/0x1a80 [] kthread+0x21d/0x2e0 [] ? kthread_stop+0x550/0x550 [] ret_from_fork+0x22/0x40 [] ? kthread_stop+0x550/0x550 RIP [] rbd_dev_header_info+0xa19/0x1e30 To fix this, a) check if RBD_DEV_FLAG_EXISTS is set before calling revalidate_disk(), b) move ceph_osdc_flush_notifies() call into rbd_dev_header_unwatch_sync() to cover rbd map error paths and c) turn header read-in into a critical section. The latter also happens to take care of rbd map foo@bar vs rbd snap rm foo@bar race. Fixes: http://tracker.ceph.com/issues/15490 Signed-off-by: Ilya Dryomov Reviewed-by: Josh Durgin --- drivers/block/rbd.c | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 94a1843b0426..25d22da47f6e 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -538,7 +538,6 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, u8 *order, u64 *snap_size); static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, u64 *snap_features); -static u64 rbd_snap_id_by_name(struct rbd_device *rbd_dev, const char *name); static int rbd_open(struct block_device *bdev, fmode_t mode) { @@ -3127,9 +3126,6 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data) struct rbd_device *rbd_dev = (struct rbd_device *)data; int ret; - if (!rbd_dev) - return; - dout("%s: \"%s\" notify_id %llu opcode %u\n", __func__, rbd_dev->header_name, (unsigned long long)notify_id, (unsigned int)opcode); @@ -3263,6 +3259,9 @@ static void rbd_dev_header_unwatch_sync(struct rbd_device *rbd_dev) ceph_osdc_cancel_event(rbd_dev->watch_event); rbd_dev->watch_event = NULL; + + dout("%s flushing notifies\n", __func__); + ceph_osdc_flush_notifies(&rbd_dev->rbd_client->client->osdc); } /* @@ -3642,21 +3641,14 @@ static void rbd_exists_validate(struct rbd_device *rbd_dev) static void rbd_dev_update_size(struct rbd_device *rbd_dev) { sector_t size; - bool removing; /* - * Don't hold the lock while doing disk operations, - * or lock ordering will conflict with the bdev mutex via: - * rbd_add() -> blkdev_get() -> rbd_open() + * If EXISTS is not set, rbd_dev->disk may be NULL, so don't + * try to update its size. If REMOVING is set, updating size + * is just useless work since the device can't be opened. */ - spin_lock_irq(&rbd_dev->lock); - removing = test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags); - spin_unlock_irq(&rbd_dev->lock); - /* - * If the device is being removed, rbd_dev->disk has - * been destroyed, so don't try to update its size - */ - if (!removing) { + if (test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags) && + !test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) { size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; dout("setting size to %llu sectors", (unsigned long long)size); set_capacity(rbd_dev->disk, size); @@ -5187,6 +5179,10 @@ out_err: return ret; } +/* + * rbd_dev->header_rwsem must be locked for write and will be unlocked + * upon return. + */ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) { int ret; @@ -5195,7 +5191,7 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) ret = rbd_dev_id_get(rbd_dev); if (ret) - return ret; + goto err_out_unlock; BUILD_BUG_ON(DEV_NAME_LEN < sizeof (RBD_DRV_NAME) + MAX_INT_FORMAT_WIDTH); @@ -5236,8 +5232,9 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) /* Everything's ready. Announce the disk to the world. */ set_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); - add_disk(rbd_dev->disk); + up_write(&rbd_dev->header_rwsem); + add_disk(rbd_dev->disk); pr_info("%s: added with size 0x%llx\n", rbd_dev->disk->disk_name, (unsigned long long) rbd_dev->mapping.size); @@ -5252,6 +5249,8 @@ err_out_blkdev: unregister_blkdev(rbd_dev->major, rbd_dev->name); err_out_id: rbd_dev_id_put(rbd_dev); +err_out_unlock: + up_write(&rbd_dev->header_rwsem); return ret; } @@ -5442,6 +5441,7 @@ static ssize_t do_rbd_add(struct bus_type *bus, spec = NULL; /* rbd_dev now owns this */ rbd_opts = NULL; /* rbd_dev now owns this */ + down_write(&rbd_dev->header_rwsem); rc = rbd_dev_image_probe(rbd_dev, 0); if (rc < 0) goto err_out_rbd_dev; @@ -5471,6 +5471,7 @@ out: return rc; err_out_rbd_dev: + up_write(&rbd_dev->header_rwsem); rbd_dev_destroy(rbd_dev); err_out_client: rbd_put_client(rbdc); @@ -5577,12 +5578,6 @@ static ssize_t do_rbd_remove(struct bus_type *bus, return ret; rbd_dev_header_unwatch_sync(rbd_dev); - /* - * flush remaining watch callbacks - these must be complete - * before the osd_client is shutdown - */ - dout("%s: flushing notifies", __func__); - ceph_osdc_flush_notifies(&rbd_dev->rbd_client->client->osdc); /* * Don't free anything from rbd_dev->disk until after all -- cgit v1.2.3 From d3767f0faeda5abdf205f947ae912d48dc70fa06 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Wed, 13 Apr 2016 14:15:50 +0200 Subject: rbd: report unsupported features to syslog ... instead of just returning an error. Signed-off-by: Ilya Dryomov Reviewed-by: Josh Durgin --- drivers/block/rbd.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 25d22da47f6e..0ede6d7e2568 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -4183,7 +4183,7 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, __le64 features; __le64 incompat; } __attribute__ ((packed)) features_buf = { 0 }; - u64 incompat; + u64 unsup; int ret; ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, @@ -4196,9 +4196,12 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, if (ret < sizeof (features_buf)) return -ERANGE; - incompat = le64_to_cpu(features_buf.incompat); - if (incompat & ~RBD_FEATURES_SUPPORTED) + unsup = le64_to_cpu(features_buf.incompat) & ~RBD_FEATURES_SUPPORTED; + if (unsup) { + rbd_warn(rbd_dev, "image uses unsupported features: 0x%llx", + unsup); return -ENXIO; + } *snap_features = le64_to_cpu(features_buf.features); -- cgit v1.2.3 From 0a25556f84d5f79e68e9502bb1f32a43377ab2bf Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Wed, 27 Apr 2016 11:35:31 +0200 Subject: perf/x86/amd: Set the size of event map array to PERF_COUNT_HW_MAX The entry for PERF_COUNT_HW_REF_CPU_CYCLES is not used on AMD, but is referenced by filter_events() which expects undefined events to have a value of 0. Found via KASAN: UBSAN: Undefined behaviour in arch/x86/events/amd/core.c:132:30 index 9 is out of range for type 'u64 [9]' UBSAN: Undefined behaviour in arch/x86/events/amd/core.c:132:9 load of address ffffffff81c021c8 with insufficient space for an object of type 'const u64' Signed-off-by: Adam Borowski Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: Jiri Olsa Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: http://lkml.kernel.org/r/1461749731-30979-1-git-send-email-kilobyte@angband.pl Signed-off-by: Ingo Molnar --- arch/x86/events/amd/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 86a9bec18dab..bd3e8421b57c 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -115,7 +115,7 @@ static __initconst const u64 amd_hw_cache_event_ids /* * AMD Performance Monitor K7 and later. */ -static const u64 amd_perfmon_event_map[] = +static const u64 amd_perfmon_event_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, -- cgit v1.2.3 From 2548d546d40c0014efdde88a53bf7896e917dcce Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 21 Apr 2016 18:03:15 +0200 Subject: nohz/full, sched/rt: Fix missed tick-reenabling bug in sched_can_stop_tick() Chris Metcalf reported a that sched_can_stop_tick() sometimes fails to re-enable the tick. His observed problem is that rq->cfs.nr_running can be 1 even though there are multiple runnable CFS tasks. This happens in the cgroup case, in which case cfs.nr_running is the number of runnable entities for that level. If there is a single runnable cgroup (which can have an arbitrary number of runnable child entries itself) rq->cfs.nr_running will be 1. However, looking at that function I think there's more problems with it. It seems to assume that if there's FIFO tasks, those will run. This is incorrect. The FIFO task can have a lower prio than an RR task, in which case the RR task will run. So the whole fifo_nr_running test seems misplaced, it should go after the rr_nr_running tests. That is, only if !rr_nr_running, can we use fifo_nr_running like this. Reported-by: Chris Metcalf Tested-by: Chris Metcalf Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Christoph Lameter Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Luiz Capitulino Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Rik van Riel Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: Viresh Kumar Cc: Wanpeng Li Fixes: 76d92ac305f2 ("sched: Migrate sched to use new tick dependency mask model") Link: http://lkml.kernel.org/r/20160421160315.GK24771@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar --- kernel/sched/core.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 8b489fcac37b..d1f7149f8704 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -596,17 +596,8 @@ bool sched_can_stop_tick(struct rq *rq) return false; /* - * FIFO realtime policy runs the highest priority task (after DEADLINE). - * Other runnable tasks are of a lower priority. The scheduler tick - * isn't needed. - */ - fifo_nr_running = rq->rt.rt_nr_running - rq->rt.rr_nr_running; - if (fifo_nr_running) - return true; - - /* - * Round-robin realtime tasks time slice with other tasks at the same - * realtime priority. + * If there are more than one RR tasks, we need the tick to effect the + * actual RR behaviour. */ if (rq->rt.rr_nr_running) { if (rq->rt.rr_nr_running == 1) @@ -615,8 +606,20 @@ bool sched_can_stop_tick(struct rq *rq) return false; } - /* Normal multitasking need periodic preemption checks */ - if (rq->cfs.nr_running > 1) + /* + * If there's no RR tasks, but FIFO tasks, we can skip the tick, no + * forced preemption between FIFO tasks. + */ + fifo_nr_running = rq->rt.rt_nr_running - rq->rt.rr_nr_running; + if (fifo_nr_running) + return true; + + /* + * If there are no DL,RR/FIFO tasks, there must only be CFS tasks left; + * if there's more than one we need the tick for involuntary + * preemption. + */ + if (rq->nr_running > 1) return false; return true; -- cgit v1.2.3 From 79c9ce57eb2d5f1497546a3946b4ae21b6fdc438 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 26 Apr 2016 11:36:53 +0200 Subject: perf/core: Fix perf_event_open() vs. execve() race Jann reported that the ptrace_may_access() check in find_lively_task_by_vpid() is racy against exec(). Specifically: perf_event_open() execve() ptrace_may_access() commit_creds() ... if (get_dumpable() != SUID_DUMP_USER) perf_event_exit_task(); perf_install_in_context() would result in installing a counter across the creds boundary. Fix this by wrapping lots of perf_event_open() in cred_guard_mutex. This should be fine as perf_event_exit_task() is already called with cred_guard_mutex held, so all perf locks already nest inside it. Reported-by: Jann Horn Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Signed-off-by: Ingo Molnar --- kernel/events/core.c | 52 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 2c78b6f47339..4e2ebf6f2f1f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1106,6 +1106,7 @@ static void put_ctx(struct perf_event_context *ctx) * function. * * Lock order: + * cred_guard_mutex * task_struct::perf_event_mutex * perf_event_context::mutex * perf_event::child_mutex; @@ -3421,7 +3422,6 @@ static struct task_struct * find_lively_task_by_vpid(pid_t vpid) { struct task_struct *task; - int err; rcu_read_lock(); if (!vpid) @@ -3435,16 +3435,7 @@ find_lively_task_by_vpid(pid_t vpid) if (!task) return ERR_PTR(-ESRCH); - /* Reuse ptrace permission checks for now. */ - err = -EACCES; - if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) - goto errout; - return task; -errout: - put_task_struct(task); - return ERR_PTR(err); - } /* @@ -8414,6 +8405,24 @@ SYSCALL_DEFINE5(perf_event_open, get_online_cpus(); + if (task) { + err = mutex_lock_interruptible(&task->signal->cred_guard_mutex); + if (err) + goto err_cpus; + + /* + * Reuse ptrace permission checks for now. + * + * We must hold cred_guard_mutex across this and any potential + * perf_install_in_context() call for this new event to + * serialize against exec() altering our credentials (and the + * perf_event_exit_task() that could imply). + */ + err = -EACCES; + if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) + goto err_cred; + } + if (flags & PERF_FLAG_PID_CGROUP) cgroup_fd = pid; @@ -8421,7 +8430,7 @@ SYSCALL_DEFINE5(perf_event_open, NULL, NULL, cgroup_fd); if (IS_ERR(event)) { err = PTR_ERR(event); - goto err_cpus; + goto err_cred; } if (is_sampling_event(event)) { @@ -8480,11 +8489,6 @@ SYSCALL_DEFINE5(perf_event_open, goto err_context; } - if (task) { - put_task_struct(task); - task = NULL; - } - /* * Look up the group leader (we will attach this event to it): */ @@ -8582,6 +8586,11 @@ SYSCALL_DEFINE5(perf_event_open, WARN_ON_ONCE(ctx->parent_ctx); + /* + * This is the point on no return; we cannot fail hereafter. This is + * where we start modifying current state. + */ + if (move_group) { /* * See perf_event_ctx_lock() for comments on the details @@ -8653,6 +8662,11 @@ SYSCALL_DEFINE5(perf_event_open, mutex_unlock(&gctx->mutex); mutex_unlock(&ctx->mutex); + if (task) { + mutex_unlock(&task->signal->cred_guard_mutex); + put_task_struct(task); + } + put_online_cpus(); mutex_lock(¤t->perf_event_mutex); @@ -8685,6 +8699,9 @@ err_alloc: */ if (!event_file) free_event(event); +err_cred: + if (task) + mutex_unlock(&task->signal->cred_guard_mutex); err_cpus: put_online_cpus(); err_task: @@ -8969,6 +8986,9 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn) /* * When a child task exits, feed back event values to parent events. + * + * Can be called with cred_guard_mutex held when called from + * install_exec_creds(). */ void perf_event_exit_task(struct task_struct *child) { -- cgit v1.2.3 From 1c5ac21a0e9bab7fc45d0ba9e11623e9ad99d02e Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Tue, 29 Mar 2016 17:43:10 +0300 Subject: perf/x86/intel/pt: Don't die on VMXON Some versions of Intel PT do not support tracing across VMXON, more specifically, VMXON will clear TraceEn control bit and any attempt to set it before VMXOFF will throw a #GP, which in the current state of things will crash the kernel. Namely: $ perf record -e intel_pt// kvm -nographic on such a machine will kill it. To avoid this, notify the intel_pt driver before VMXON and after VMXOFF so that it knows when not to enable itself. Signed-off-by: Alexander Shishkin Signed-off-by: Peter Zijlstra (Intel) Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: Gleb Natapov Cc: Jiri Olsa Cc: Paolo Bonzini Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: hpa@zytor.com Link: http://lkml.kernel.org/r/87oa9dwrfk.fsf@ashishki-desk.ger.corp.intel.com Signed-off-by: Ingo Molnar --- arch/x86/events/intel/pt.c | 75 +++++++++++++++++++++++++++++++++------ arch/x86/events/intel/pt.h | 3 ++ arch/x86/include/asm/perf_event.h | 4 +++ arch/x86/kvm/vmx.c | 4 +++ 4 files changed, 75 insertions(+), 11 deletions(-) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 6af7cf71d6b2..09a77dbc73c9 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -136,9 +136,21 @@ static int __init pt_pmu_hw_init(void) struct dev_ext_attribute *de_attrs; struct attribute **attrs; size_t size; + u64 reg; int ret; long i; + if (boot_cpu_has(X86_FEATURE_VMX)) { + /* + * Intel SDM, 36.5 "Tracing post-VMXON" says that + * "IA32_VMX_MISC[bit 14]" being 1 means PT can trace + * post-VMXON. + */ + rdmsrl(MSR_IA32_VMX_MISC, reg); + if (reg & BIT(14)) + pt_pmu.vmx = true; + } + attrs = NULL; for (i = 0; i < PT_CPUID_LEAVES; i++) { @@ -269,20 +281,23 @@ static void pt_config(struct perf_event *event) reg |= (event->attr.config & PT_CONFIG_MASK); + event->hw.config = reg; wrmsrl(MSR_IA32_RTIT_CTL, reg); } -static void pt_config_start(bool start) +static void pt_config_stop(struct perf_event *event) { - u64 ctl; + u64 ctl = READ_ONCE(event->hw.config); + + /* may be already stopped by a PMI */ + if (!(ctl & RTIT_CTL_TRACEEN)) + return; - rdmsrl(MSR_IA32_RTIT_CTL, ctl); - if (start) - ctl |= RTIT_CTL_TRACEEN; - else - ctl &= ~RTIT_CTL_TRACEEN; + ctl &= ~RTIT_CTL_TRACEEN; wrmsrl(MSR_IA32_RTIT_CTL, ctl); + WRITE_ONCE(event->hw.config, ctl); + /* * A wrmsr that disables trace generation serializes other PT * registers and causes all data packets to be written to memory, @@ -291,8 +306,7 @@ static void pt_config_start(bool start) * The below WMB, separating data store and aux_head store matches * the consumer's RMB that separates aux_head load and data load. */ - if (!start) - wmb(); + wmb(); } static void pt_config_buffer(void *buf, unsigned int topa_idx, @@ -942,11 +956,17 @@ void intel_pt_interrupt(void) if (!ACCESS_ONCE(pt->handle_nmi)) return; - pt_config_start(false); + /* + * If VMX is on and PT does not support it, don't touch anything. + */ + if (READ_ONCE(pt->vmx_on)) + return; if (!event) return; + pt_config_stop(event); + buf = perf_get_aux(&pt->handle); if (!buf) return; @@ -983,6 +1003,35 @@ void intel_pt_interrupt(void) } } +void intel_pt_handle_vmx(int on) +{ + struct pt *pt = this_cpu_ptr(&pt_ctx); + struct perf_event *event; + unsigned long flags; + + /* PT plays nice with VMX, do nothing */ + if (pt_pmu.vmx) + return; + + /* + * VMXON will clear RTIT_CTL.TraceEn; we need to make + * sure to not try to set it while VMX is on. Disable + * interrupts to avoid racing with pmu callbacks; + * concurrent PMI should be handled fine. + */ + local_irq_save(flags); + WRITE_ONCE(pt->vmx_on, on); + + if (on) { + /* prevent pt_config_stop() from writing RTIT_CTL */ + event = pt->handle.event; + if (event) + event->hw.config = 0; + } + local_irq_restore(flags); +} +EXPORT_SYMBOL_GPL(intel_pt_handle_vmx); + /* * PMU callbacks */ @@ -992,6 +1041,9 @@ static void pt_event_start(struct perf_event *event, int mode) struct pt *pt = this_cpu_ptr(&pt_ctx); struct pt_buffer *buf = perf_get_aux(&pt->handle); + if (READ_ONCE(pt->vmx_on)) + return; + if (!buf || pt_buffer_is_full(buf, pt)) { event->hw.state = PERF_HES_STOPPED; return; @@ -1014,7 +1066,8 @@ static void pt_event_stop(struct perf_event *event, int mode) * see comment in intel_pt_interrupt(). */ ACCESS_ONCE(pt->handle_nmi) = 0; - pt_config_start(false); + + pt_config_stop(event); if (event->hw.state == PERF_HES_STOPPED) return; diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h index 336878a5d205..3abb5f5cccc8 100644 --- a/arch/x86/events/intel/pt.h +++ b/arch/x86/events/intel/pt.h @@ -65,6 +65,7 @@ enum pt_capabilities { struct pt_pmu { struct pmu pmu; u32 caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES]; + bool vmx; }; /** @@ -107,10 +108,12 @@ struct pt_buffer { * struct pt - per-cpu pt context * @handle: perf output handle * @handle_nmi: do handle PT PMI on this cpu, there's an active event + * @vmx_on: 1 if VMX is ON on this cpu */ struct pt { struct perf_output_handle handle; int handle_nmi; + int vmx_on; }; #endif /* __INTEL_PT_H__ */ diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 5a2ed3ed2f26..f353061bba1d 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -285,6 +285,10 @@ static inline void perf_events_lapic_init(void) { } static inline void perf_check_microcode(void) { } #endif +#ifdef CONFIG_CPU_SUP_INTEL + extern void intel_pt_handle_vmx(int on); +#endif + #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) extern void amd_pmu_enable_virt(void); extern void amd_pmu_disable_virt(void); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ee1c8a93871c..133679d520af 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3103,6 +3103,8 @@ static __init int vmx_disabled_by_bios(void) static void kvm_cpu_vmxon(u64 addr) { + intel_pt_handle_vmx(1); + asm volatile (ASM_VMX_VMXON_RAX : : "a"(&addr), "m"(addr) : "memory", "cc"); @@ -3172,6 +3174,8 @@ static void vmclear_local_loaded_vmcss(void) static void kvm_cpu_vmxoff(void) { asm volatile (__ex(ASM_VMX_VMXOFF) : : : "cc"); + + intel_pt_handle_vmx(0); } static void hardware_disable(void) -- cgit v1.2.3 From cf3beb7c90a8efa16a06b26634cddddc92bb819c Mon Sep 17 00:00:00 2001 From: Kan Liang Date: Thu, 21 Apr 2016 02:30:10 -0700 Subject: perf/x86/intel: Fix incorrect lbr_sel_mask value This patch fixes a bug which was introduced by: b16a5b52eb90 ("perf/x86: Add option to disable reading branch flags/cycles") In this patch, lbr_sel_mask is used to mask the lbr_select. But LBR_SEL_MASK doesn't include the bit for LBR_CALL_STACK. So LBR call stack will never be set in lbr_select. This patch corrects the LBR_SEL_MASK by including all valid bits in LBR_SELECT. Also, the LBR_CALL_STACK bit is different as other bit in LBR_SELECT. It does not operate in suppress mode, so it needs to be specially handled in intel_pmu_setup_hw_lbr_filter. Signed-off-by: Kan Liang Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: http://lkml.kernel.org/r/1461231010-4399-1-git-send-email-kan.liang@intel.com Signed-off-by: Ingo Molnar --- arch/x86/events/intel/lbr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index 6c3b7c1780c9..1ca5d1e7d4f2 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -63,7 +63,7 @@ static enum { #define LBR_PLM (LBR_KERNEL | LBR_USER) -#define LBR_SEL_MASK 0x1ff /* valid bits in LBR_SELECT */ +#define LBR_SEL_MASK 0x3ff /* valid bits in LBR_SELECT */ #define LBR_NOT_SUPP -1 /* LBR filter not supported */ #define LBR_IGN 0 /* ignored */ @@ -610,8 +610,10 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event) * The first 9 bits (LBR_SEL_MASK) in LBR_SELECT operate * in suppress mode. So LBR_SELECT should be set to * (~mask & LBR_SEL_MASK) | (mask & ~LBR_SEL_MASK) + * But the 10th bit LBR_CALL_STACK does not operate + * in suppress mode. */ - reg->config = mask ^ x86_pmu.lbr_sel_mask; + reg->config = mask ^ (x86_pmu.lbr_sel_mask & ~LBR_CALL_STACK); if ((br_type & PERF_SAMPLE_BRANCH_NO_CYCLES) && (br_type & PERF_SAMPLE_BRANCH_NO_FLAGS) && -- cgit v1.2.3 From 2963070a0f8184fe40be11927344e3fcc7e18e7c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 26 Apr 2016 23:37:26 +0800 Subject: mmc: sunxi: Disable eMMC HS-DDR (MMC_CAP_1_8V_DDR) for Allwinner A80 eMMC HS-DDR no longer works on the A80, despite it working when support for this developed. Disable it for now. Signed-off-by: Chen-Yu Tsai Signed-off-by: Ulf Hansson --- drivers/mmc/host/sunxi-mmc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index 8372a413848c..7fc8b7aa83f0 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c @@ -1129,6 +1129,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev) MMC_CAP_1_8V_DDR | MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; + /* TODO MMC DDR is not working on A80 */ + if (of_device_is_compatible(pdev->dev.of_node, + "allwinner,sun9i-a80-mmc")) + mmc->caps &= ~MMC_CAP_1_8V_DDR; + ret = mmc_of_parse(mmc); if (ret) goto error_free_dma; -- cgit v1.2.3 From 625fe4f8ffc1b915248558481bb94249f6bd411c Mon Sep 17 00:00:00 2001 From: James Morse Date: Tue, 26 Apr 2016 12:15:01 +0100 Subject: ARM: cpuidle: Pass on arm_cpuidle_suspend()'s return value arm_cpuidle_suspend() may return -EOPNOTSUPP, or any value returned by the cpu_ops/cpuidle_ops suspend call. arm_enter_idle_state() doesn't update 'ret' with this value, meaning we always signal success to cpuidle_enter_state(), causing it to update the usage counters as if we succeeded. Fixes: 191de17aa3c1 ("ARM64: cpuidle: Replace cpu_suspend by the common ARM/ARM64 function") Signed-off-by: James Morse Acked-by: Lorenzo Pieralisi Acked-by: Daniel Lezcano Cc: 4.1+ # 4.1+ Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle-arm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c index 545069d5fdfb..e342565e8715 100644 --- a/drivers/cpuidle/cpuidle-arm.c +++ b/drivers/cpuidle/cpuidle-arm.c @@ -50,7 +50,7 @@ static int arm_enter_idle_state(struct cpuidle_device *dev, * call the CPU ops suspend protocol with idle index as a * parameter. */ - arm_cpuidle_suspend(idx); + ret = arm_cpuidle_suspend(idx); cpu_pm_exit(); } -- cgit v1.2.3 From 2482bc31ca8096241b8fa97610ef23154ce55f45 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Wed, 27 Apr 2016 17:18:59 +0100 Subject: cpufreq: st: enable selective initialization based on the platform The sti-cpufreq does unconditional registration of the cpufreq-dt driver which causes issue on an multi-platform build. For example, on Vexpress TC2 platform, we get the following error on boot: cpu cpu0: OPP-v2 not supported cpu cpu0: Not doing voltage scaling cpu: dev_pm_opp_of_cpumask_add_table: couldn't find opp table for cpu:0, -19 cpu cpu0: dev_pm_opp_get_max_volt_latency: Invalid regulator (-6) ... arm_big_little: bL_cpufreq_register: Failed registering platform driver: vexpress-spc, err: -17 The actual driver fails to initialise as cpufreq-dt is probed successfully, which is incorrect. This issue can happen to any platform not using cpufreq-dt in a multi-platform build. This patch adds a check to do selective initialization of the driver. Fixes: ab0ea257fc58 (cpufreq: st: Provide runtime initialised driver for ST's platforms) Signed-off-by: Sudeep Holla Acked-by: Viresh Kumar Acked-by: Lee Jones Cc: 4.5+ # 4.5+ Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/sti-cpufreq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/cpufreq/sti-cpufreq.c b/drivers/cpufreq/sti-cpufreq.c index a9c659f58974..04042038ec4b 100644 --- a/drivers/cpufreq/sti-cpufreq.c +++ b/drivers/cpufreq/sti-cpufreq.c @@ -259,6 +259,10 @@ static int sti_cpufreq_init(void) { int ret; + if ((!of_machine_is_compatible("st,stih407")) && + (!of_machine_is_compatible("st,stih410"))) + return -ENODEV; + ddata.cpu = get_cpu_device(0); if (!ddata.cpu) { dev_err(ddata.cpu, "Failed to get device for CPU0\n"); -- cgit v1.2.3 From 986ef95ecdd3eb6fa29433e68faa94c7624083be Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Thu, 31 Mar 2016 19:03:25 +0300 Subject: IB/mlx5: Expose correct max_sge_rd limit mlx5 devices (Connect-IB, ConnectX-4, ConnectX-4-LX) has a limitation where rdma read work queue entries cannot exceed 512 bytes. A rdma_read wqe needs to fit in 512 bytes: - wqe control segment (16 bytes) - rdma segment (16 bytes) - scatter elements (16 bytes each) So max_sge_rd should be: (512 - 16 - 16) / 16 = 30. Cc: linux-stable@vger.kernel.org Reported-by: Christoph Hellwig Tested-by: Christoph Hellwig Signed-off-by: Sagi Grimberg Signed-off-by: Leon Romanovsky Signed-off-by: Doug Ledford --- drivers/infiniband/hw/mlx5/main.c | 2 +- include/linux/mlx5/device.h | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 5acf346e048e..049754f6e638 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -530,7 +530,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, sizeof(struct mlx5_wqe_ctrl_seg)) / sizeof(struct mlx5_wqe_data_seg); props->max_sge = min(max_rq_sg, max_sq_sg); - props->max_sge_rd = props->max_sge; + props->max_sge_rd = MLX5_MAX_SGE_RD; props->max_cq = 1 << MLX5_CAP_GEN(mdev, log_max_cq); props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_cq_sz)) - 1; props->max_mr = 1 << MLX5_CAP_GEN(mdev, log_max_mkey); diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h index 8156e3c9239c..b3575f392492 100644 --- a/include/linux/mlx5/device.h +++ b/include/linux/mlx5/device.h @@ -392,6 +392,17 @@ enum { MLX5_CAP_OFF_CMDIF_CSUM = 46, }; +enum { + /* + * Max wqe size for rdma read is 512 bytes, so this + * limits our max_sge_rd as the wqe needs to fit: + * - ctrl segment (16 bytes) + * - rdma segment (16 bytes) + * - scatter elements (16 bytes each) + */ + MLX5_MAX_SGE_RD = (512 - 16 - 16) / 16 +}; + struct mlx5_inbox_hdr { __be16 opcode; u8 rsvd[4]; -- cgit v1.2.3 From e7d2c25d94bf4bb6f73d185e5514414a15a56f46 Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Sun, 3 Apr 2016 15:03:12 +0300 Subject: MAINTAINERS: Update iser/isert maintainer contact info Signed-off-by: Sagi Grimberg Acked-by: Nicholas Bellinger Signed-off-by: Doug Ledford --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1c32f8a3d6c4..03413249f89b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6027,7 +6027,7 @@ F: include/scsi/*iscsi* ISCSI EXTENSIONS FOR RDMA (ISER) INITIATOR M: Or Gerlitz -M: Sagi Grimberg +M: Sagi Grimberg M: Roi Dayan L: linux-rdma@vger.kernel.org S: Supported @@ -6037,7 +6037,7 @@ Q: http://patchwork.kernel.org/project/linux-rdma/list/ F: drivers/infiniband/ulp/iser/ ISCSI EXTENSIONS FOR RDMA (ISER) TARGET -M: Sagi Grimberg +M: Sagi Grimberg T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master L: linux-rdma@vger.kernel.org L: target-devel@vger.kernel.org -- cgit v1.2.3 From f19bd643dbded8672bfeffe9e51322464e4a9239 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Tue, 12 Apr 2016 10:45:57 -0700 Subject: IB/hfi1: Prevent NULL pointer deferences in caching code There is a potential kernel crash when the MMU notifier calls the invalidation routines in the hfi1 pinned page caching code for sdma. The invalidation routine could call the remove callback for the node, which in turn ends up dereferencing the current task_struct to get a pointer to the mm_struct. However, the mm_struct pointer could be NULL resulting in the following backtrace: BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8 IP: [] sdma_rb_remove+0xaa/0x100 [hfi1] 15 task: ffff88085e66e080 ti: ffff88085c244000 task.ti: ffff88085c244000 RIP: 0010:[] [] sdma_rb_remove+0xaa/0x100 [hfi1] RSP: 0000:ffff88085c245878 EFLAGS: 00010002 RAX: 0000000000000000 RBX: ffff88105b9bbd40 RCX: ffffea003931a830 RDX: 0000000000000004 RSI: ffff88105754a9c0 RDI: ffff88105754a9c0 RBP: ffff88085c245890 R08: ffff88105b9bbd70 R09: 00000000fffffffb R10: ffff88105b9bbd58 R11: 0000000000000013 R12: ffff88105754a9c0 R13: 0000000000000001 R14: 0000000000000001 R15: ffff88105b9bbd40 FS: 0000000000000000(0000) GS:ffff88107ef40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000000000a8 CR3: 0000000001a0b000 CR4: 00000000001407e0 Stack: ffff88105b9bbd40 ffff88080ec481a8 ffff88080ec481b8 ffff88085c2458c0 ffffffffa03fa00e ffff88080ec48190 ffff88080ed9cd00 0000000001024000 0000000000000000 ffff88085c245920 ffffffffa03fa0e7 0000000000000282 Call Trace: [] __mmu_rb_remove.isra.5+0x5e/0x70 [hfi1] [] mmu_notifier_mem_invalidate+0xc7/0xf0 [hfi1] [] mmu_notifier_page+0x13/0x20 [hfi1] [] __mmu_notifier_invalidate_page+0x50/0x70 [] try_to_unmap_one+0x20b/0x470 [] try_to_unmap_anon+0xa7/0x120 [] try_to_unmap+0x4d/0x60 [] shrink_page_list+0x2eb/0x9d0 [] shrink_inactive_list+0x243/0x490 [] shrink_lruvec+0x4c1/0x640 [] shrink_zone+0x31/0x100 [] kswapd_shrink_zone.constprop.62+0xef/0x1c0 [] kswapd+0x403/0x7e0 [] ? shrink_all_memory+0xf0/0xf0 [] kthread+0xc0/0xd0 [] ? insert_kthread_work+0x40/0x40 [] ret_from_fork+0x7c/0xb0 [] ? insert_kthread_work+0x40/0x40 To correct this, the mm_struct passed to us by the MMU notifier is used (which is what should have been done to begin with). This avoids the broken derefences and ensures that the correct mm_struct is used. Reviewed-by: Dennis Dalessandro Reviewed-by: Dean Luick Signed-off-by: Mitko Haralanov Signed-off-by: Doug Ledford --- drivers/staging/rdma/hfi1/mmu_rb.c | 24 ++++++++++++++---------- drivers/staging/rdma/hfi1/mmu_rb.h | 3 ++- drivers/staging/rdma/hfi1/user_exp_rcv.c | 9 +++++---- drivers/staging/rdma/hfi1/user_sdma.c | 24 ++++++++++++++++-------- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/drivers/staging/rdma/hfi1/mmu_rb.c b/drivers/staging/rdma/hfi1/mmu_rb.c index c7ad0164ea9a..eac4d041d351 100644 --- a/drivers/staging/rdma/hfi1/mmu_rb.c +++ b/drivers/staging/rdma/hfi1/mmu_rb.c @@ -71,6 +71,7 @@ static inline void mmu_notifier_range_start(struct mmu_notifier *, struct mm_struct *, unsigned long, unsigned long); static void mmu_notifier_mem_invalidate(struct mmu_notifier *, + struct mm_struct *, unsigned long, unsigned long); static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *, unsigned long, unsigned long); @@ -137,7 +138,7 @@ void hfi1_mmu_rb_unregister(struct rb_root *root) rbnode = rb_entry(node, struct mmu_rb_node, node); rb_erase(node, root); if (handler->ops->remove) - handler->ops->remove(root, rbnode, false); + handler->ops->remove(root, rbnode, NULL); } } @@ -201,14 +202,14 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, } static void __mmu_rb_remove(struct mmu_rb_handler *handler, - struct mmu_rb_node *node, bool arg) + struct mmu_rb_node *node, struct mm_struct *mm) { /* Validity of handler and node pointers has been checked by caller. */ hfi1_cdbg(MMU, "Removing node addr 0x%llx, len %u", node->addr, node->len); __mmu_int_rb_remove(node, handler->root); if (handler->ops->remove) - handler->ops->remove(handler->root, node, arg); + handler->ops->remove(handler->root, node, mm); } struct mmu_rb_node *hfi1_mmu_rb_search(struct rb_root *root, unsigned long addr, @@ -237,7 +238,7 @@ void hfi1_mmu_rb_remove(struct rb_root *root, struct mmu_rb_node *node) return; spin_lock_irqsave(&handler->lock, flags); - __mmu_rb_remove(handler, node, false); + __mmu_rb_remove(handler, node, NULL); spin_unlock_irqrestore(&handler->lock, flags); } @@ -260,7 +261,7 @@ unlock: static inline void mmu_notifier_page(struct mmu_notifier *mn, struct mm_struct *mm, unsigned long addr) { - mmu_notifier_mem_invalidate(mn, addr, addr + PAGE_SIZE); + mmu_notifier_mem_invalidate(mn, mm, addr, addr + PAGE_SIZE); } static inline void mmu_notifier_range_start(struct mmu_notifier *mn, @@ -268,25 +269,28 @@ static inline void mmu_notifier_range_start(struct mmu_notifier *mn, unsigned long start, unsigned long end) { - mmu_notifier_mem_invalidate(mn, start, end); + mmu_notifier_mem_invalidate(mn, mm, start, end); } static void mmu_notifier_mem_invalidate(struct mmu_notifier *mn, + struct mm_struct *mm, unsigned long start, unsigned long end) { struct mmu_rb_handler *handler = container_of(mn, struct mmu_rb_handler, mn); struct rb_root *root = handler->root; - struct mmu_rb_node *node; + struct mmu_rb_node *node, *ptr = NULL; unsigned long flags; spin_lock_irqsave(&handler->lock, flags); - for (node = __mmu_int_rb_iter_first(root, start, end - 1); node; - node = __mmu_int_rb_iter_next(node, start, end - 1)) { + for (node = __mmu_int_rb_iter_first(root, start, end - 1); + node; node = ptr) { + /* Guard against node removal. */ + ptr = __mmu_int_rb_iter_next(node, start, end - 1); hfi1_cdbg(MMU, "Invalidating node addr 0x%llx, len %u", node->addr, node->len); if (handler->ops->invalidate(root, node)) - __mmu_rb_remove(handler, node, true); + __mmu_rb_remove(handler, node, mm); } spin_unlock_irqrestore(&handler->lock, flags); } diff --git a/drivers/staging/rdma/hfi1/mmu_rb.h b/drivers/staging/rdma/hfi1/mmu_rb.h index f8523fdb8a18..19a306e83c7d 100644 --- a/drivers/staging/rdma/hfi1/mmu_rb.h +++ b/drivers/staging/rdma/hfi1/mmu_rb.h @@ -59,7 +59,8 @@ struct mmu_rb_node { struct mmu_rb_ops { bool (*filter)(struct mmu_rb_node *, unsigned long, unsigned long); int (*insert)(struct rb_root *, struct mmu_rb_node *); - void (*remove)(struct rb_root *, struct mmu_rb_node *, bool); + void (*remove)(struct rb_root *, struct mmu_rb_node *, + struct mm_struct *); int (*invalidate)(struct rb_root *, struct mmu_rb_node *); }; diff --git a/drivers/staging/rdma/hfi1/user_exp_rcv.c b/drivers/staging/rdma/hfi1/user_exp_rcv.c index 0861e095df8d..5b72849bbd71 100644 --- a/drivers/staging/rdma/hfi1/user_exp_rcv.c +++ b/drivers/staging/rdma/hfi1/user_exp_rcv.c @@ -87,7 +87,8 @@ static u32 find_phys_blocks(struct page **, unsigned, struct tid_pageset *); static int set_rcvarray_entry(struct file *, unsigned long, u32, struct tid_group *, struct page **, unsigned); static int mmu_rb_insert(struct rb_root *, struct mmu_rb_node *); -static void mmu_rb_remove(struct rb_root *, struct mmu_rb_node *, bool); +static void mmu_rb_remove(struct rb_root *, struct mmu_rb_node *, + struct mm_struct *); static int mmu_rb_invalidate(struct rb_root *, struct mmu_rb_node *); static int program_rcvarray(struct file *, unsigned long, struct tid_group *, struct tid_pageset *, unsigned, u16, struct page **, @@ -899,7 +900,7 @@ static int unprogram_rcvarray(struct file *fp, u32 tidinfo, if (!node || node->rcventry != (uctxt->expected_base + rcventry)) return -EBADF; if (HFI1_CAP_IS_USET(TID_UNMAP)) - mmu_rb_remove(&fd->tid_rb_root, &node->mmu, false); + mmu_rb_remove(&fd->tid_rb_root, &node->mmu, NULL); else hfi1_mmu_rb_remove(&fd->tid_rb_root, &node->mmu); @@ -965,7 +966,7 @@ static void unlock_exp_tids(struct hfi1_ctxtdata *uctxt, continue; if (HFI1_CAP_IS_USET(TID_UNMAP)) mmu_rb_remove(&fd->tid_rb_root, - &node->mmu, false); + &node->mmu, NULL); else hfi1_mmu_rb_remove(&fd->tid_rb_root, &node->mmu); @@ -1032,7 +1033,7 @@ static int mmu_rb_insert(struct rb_root *root, struct mmu_rb_node *node) } static void mmu_rb_remove(struct rb_root *root, struct mmu_rb_node *node, - bool notifier) + struct mm_struct *mm) { struct hfi1_filedata *fdata = container_of(root, struct hfi1_filedata, tid_rb_root); diff --git a/drivers/staging/rdma/hfi1/user_sdma.c b/drivers/staging/rdma/hfi1/user_sdma.c index ab6b6a42000f..e08c74fe4c6b 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.c +++ b/drivers/staging/rdma/hfi1/user_sdma.c @@ -299,7 +299,8 @@ static int defer_packet_queue( static void activate_packet_queue(struct iowait *, int); static bool sdma_rb_filter(struct mmu_rb_node *, unsigned long, unsigned long); static int sdma_rb_insert(struct rb_root *, struct mmu_rb_node *); -static void sdma_rb_remove(struct rb_root *, struct mmu_rb_node *, bool); +static void sdma_rb_remove(struct rb_root *, struct mmu_rb_node *, + struct mm_struct *); static int sdma_rb_invalidate(struct rb_root *, struct mmu_rb_node *); static struct mmu_rb_ops sdma_rb_ops = { @@ -1063,8 +1064,10 @@ static int pin_vector_pages(struct user_sdma_request *req, rb_node = hfi1_mmu_rb_search(&pq->sdma_rb_root, (unsigned long)iovec->iov.iov_base, iovec->iov.iov_len); - if (rb_node) + if (rb_node && !IS_ERR(rb_node)) node = container_of(rb_node, struct sdma_mmu_node, rb); + else + rb_node = NULL; if (!node) { node = kzalloc(sizeof(*node), GFP_KERNEL); @@ -1502,7 +1505,7 @@ static void user_sdma_free_request(struct user_sdma_request *req, bool unpin) &req->pq->sdma_rb_root, (unsigned long)req->iovs[i].iov.iov_base, req->iovs[i].iov.iov_len); - if (!mnode) + if (!mnode || IS_ERR(mnode)) continue; node = container_of(mnode, struct sdma_mmu_node, rb); @@ -1547,7 +1550,7 @@ static int sdma_rb_insert(struct rb_root *root, struct mmu_rb_node *mnode) } static void sdma_rb_remove(struct rb_root *root, struct mmu_rb_node *mnode, - bool notifier) + struct mm_struct *mm) { struct sdma_mmu_node *node = container_of(mnode, struct sdma_mmu_node, rb); @@ -1557,14 +1560,19 @@ static void sdma_rb_remove(struct rb_root *root, struct mmu_rb_node *mnode, node->pq->n_locked -= node->npages; spin_unlock(&node->pq->evict_lock); - unpin_vector_pages(notifier ? NULL : current->mm, node->pages, - node->npages); + /* + * If mm is set, we are being called by the MMU notifier and we + * should not pass a mm_struct to unpin_vector_page(). This is to + * prevent a deadlock when hfi1_release_user_pages() attempts to + * take the mmap_sem, which the MMU notifier has already taken. + */ + unpin_vector_pages(mm ? NULL : current->mm, node->pages, node->npages); /* * If called by the MMU notifier, we have to adjust the pinned * page count ourselves. */ - if (notifier) - current->mm->pinned_vm -= node->npages; + if (mm) + mm->pinned_vm -= node->npages; kfree(node); } -- cgit v1.2.3 From de82bdff62a9078a6e4f1452e2f2604686e51e49 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Tue, 12 Apr 2016 10:46:03 -0700 Subject: IB/hfi1: Fix deadlock caused by locking with wrong scope The locking around the interval RB tree is designed to prevent access to the tree while it's being modified. The locking in its current form is too overzealous, which is causing a deadlock in certain cases with the following backtrace: Kernel panic - not syncing: Watchdog detected hard LOCKUP on cpu 0 CPU: 0 PID: 5836 Comm: IMB-MPI1 Tainted: G O 3.12.18-wfr+ #1 0000000000000000 ffff88087f206c50 ffffffff814f1caa ffffffff817b53f0 ffff88087f206cc8 ffffffff814ecd56 0000000000000010 ffff88087f206cd8 ffff88087f206c78 0000000000000000 0000000000000000 0000000000001662 Call Trace: [] dump_stack+0x45/0x56 [] panic+0xc2/0x1cb [] ? restart_watchdog_hrtimer+0x50/0x50 [] watchdog_overflow_callback+0xc2/0xd0 [] __perf_event_overflow+0x8e/0x2b0 [] perf_event_overflow+0x14/0x20 [] intel_pmu_handle_irq+0x1b6/0x390 [] perf_event_nmi_handler+0x2b/0x50 [] nmi_handle.isra.3+0x88/0x180 [] do_nmi+0x169/0x310 [] end_repeat_nmi+0x1e/0x2e [] ? unmap_single+0x30/0x30 [] ? _raw_spin_lock_irqsave+0x2d/0x40 [] ? _raw_spin_lock_irqsave+0x2d/0x40 [] ? _raw_spin_lock_irqsave+0x2d/0x40 <> [] hfi1_mmu_rb_search+0x38/0x70 [hfi1] [] user_sdma_free_request+0xcb/0x120 [hfi1] [] user_sdma_txreq_cb+0x263/0x350 [hfi1] [] ? sdma_txclean+0x27/0x1c0 [hfi1] [] ? user_sdma_send_pkts+0x1710/0x1710 [hfi1] [] sdma_make_progress+0x166/0x480 [hfi1] [] ? ttwu_do_wakeup+0x19/0xd0 [] sdma_engine_interrupt+0x8e/0x100 [hfi1] [] sdma_interrupt+0x5d/0xa0 [hfi1] [] handle_irq_event_percpu+0x47/0x1d0 [] handle_irq_event+0x37/0x60 [] handle_edge_irq+0x6f/0x120 [] handle_irq+0xbf/0x150 [] ? irq_enter+0x17/0x80 [] do_IRQ+0x4d/0xc0 [] common_interrupt+0x6a/0x6a [] ? finish_task_switch+0x54/0xe0 [] __schedule+0x3b6/0x7e0 [] __cond_resched+0x26/0x30 [] _cond_resched+0x3a/0x50 [] down_write+0x12/0x30 [] hfi1_release_user_pages+0x69/0x90 [hfi1] [] sdma_rb_remove+0x9a/0xc0 [hfi1] [] __mmu_rb_remove.isra.5+0x5d/0x70 [hfi1] [] hfi1_mmu_rb_remove+0x56/0x70 [hfi1] [] hfi1_user_sdma_process_request+0x74b/0x1160 [hfi1] [] hfi1_aio_write+0xc3/0x100 [hfi1] [] do_sync_readv_writev+0x4c/0x80 [] do_readv_writev+0xbb/0x230 [] ? fsnotify+0x241/0x320 [] ? finish_task_switch+0x54/0xe0 [] vfs_writev+0x35/0x60 [] SyS_writev+0x49/0xc0 [] ? __audit_syscall_exit+0x1f6/0x2a0 [] system_call_fastpath+0x16/0x1b As evident from the backtrace above, the process was being put to sleep while holding the lock. Limiting the scope of the lock only to the RB tree operation fixes the above error allowing for proper locking and the process being put to sleep when needed. Reviewed-by: Dennis Dalessandro Reviewed-by: Dean Luick Signed-off-by: Mitko Haralanov Signed-off-by: Doug Ledford --- drivers/staging/rdma/hfi1/mmu_rb.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rdma/hfi1/mmu_rb.c b/drivers/staging/rdma/hfi1/mmu_rb.c index eac4d041d351..b3f0682a36c9 100644 --- a/drivers/staging/rdma/hfi1/mmu_rb.c +++ b/drivers/staging/rdma/hfi1/mmu_rb.c @@ -177,7 +177,7 @@ unlock: return ret; } -/* Caller must host handler lock */ +/* Caller must hold handler lock */ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, unsigned long addr, unsigned long len) @@ -201,13 +201,19 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, return node; } +/* Caller must *not* hold handler lock. */ static void __mmu_rb_remove(struct mmu_rb_handler *handler, struct mmu_rb_node *node, struct mm_struct *mm) { + unsigned long flags; + /* Validity of handler and node pointers has been checked by caller. */ hfi1_cdbg(MMU, "Removing node addr 0x%llx, len %u", node->addr, node->len); + spin_lock_irqsave(&handler->lock, flags); __mmu_int_rb_remove(node, handler->root); + spin_unlock_irqrestore(&handler->lock, flags); + if (handler->ops->remove) handler->ops->remove(handler->root, node, mm); } @@ -232,14 +238,11 @@ struct mmu_rb_node *hfi1_mmu_rb_search(struct rb_root *root, unsigned long addr, void hfi1_mmu_rb_remove(struct rb_root *root, struct mmu_rb_node *node) { struct mmu_rb_handler *handler = find_mmu_handler(root); - unsigned long flags; if (!handler || !node) return; - spin_lock_irqsave(&handler->lock, flags); __mmu_rb_remove(handler, node, NULL); - spin_unlock_irqrestore(&handler->lock, flags); } static struct mmu_rb_handler *find_mmu_handler(struct rb_root *root) @@ -289,8 +292,11 @@ static void mmu_notifier_mem_invalidate(struct mmu_notifier *mn, ptr = __mmu_int_rb_iter_next(node, start, end - 1); hfi1_cdbg(MMU, "Invalidating node addr 0x%llx, len %u", node->addr, node->len); - if (handler->ops->invalidate(root, node)) + if (handler->ops->invalidate(root, node)) { + spin_unlock_irqrestore(&handler->lock, flags); __mmu_rb_remove(handler, node, mm); + spin_lock_irqsave(&handler->lock, flags); + } } spin_unlock_irqrestore(&handler->lock, flags); } -- cgit v1.2.3 From 849e3e9398608c26a7c54bf9fbf3288f7ced6bfb Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Tue, 12 Apr 2016 10:46:16 -0700 Subject: IB/hfi1: Prevent unpinning of wrong pages The routine used by the SDMA cache to handle already cached nodes can extend an already existing node. In its error handling code, the routine will unpin pages when not all pages of the buffer extension were pinned. There was a bug in that part of the routine, which would mistakenly unpin pages from the original set rather than the newly pinned pages. This commit fixes that bug by offsetting the page array to the proper place pointing at the beginning of the newly pinned pages. Reviewed-by: Dean Luick Signed-off-by: Mitko Haralanov Signed-off-by: Doug Ledford --- drivers/staging/rdma/hfi1/user_sdma.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rdma/hfi1/user_sdma.c b/drivers/staging/rdma/hfi1/user_sdma.c index e08c74fe4c6b..d53a659548e0 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.c +++ b/drivers/staging/rdma/hfi1/user_sdma.c @@ -278,7 +278,8 @@ static inline void pq_update(struct hfi1_user_sdma_pkt_q *); static void user_sdma_free_request(struct user_sdma_request *, bool); static int pin_vector_pages(struct user_sdma_request *, struct user_sdma_iovec *); -static void unpin_vector_pages(struct mm_struct *, struct page **, unsigned); +static void unpin_vector_pages(struct mm_struct *, struct page **, unsigned, + unsigned); static int check_header_template(struct user_sdma_request *, struct hfi1_pkt_header *, u32, u32); static int set_txreq_header(struct user_sdma_request *, @@ -1110,7 +1111,8 @@ retry: goto bail; } if (pinned != npages) { - unpin_vector_pages(current->mm, pages, pinned); + unpin_vector_pages(current->mm, pages, node->npages, + pinned); ret = -EFAULT; goto bail; } @@ -1150,9 +1152,9 @@ bail: } static void unpin_vector_pages(struct mm_struct *mm, struct page **pages, - unsigned npages) + unsigned start, unsigned npages) { - hfi1_release_user_pages(mm, pages, npages, 0); + hfi1_release_user_pages(mm, pages + start, npages, 0); kfree(pages); } @@ -1566,7 +1568,8 @@ static void sdma_rb_remove(struct rb_root *root, struct mmu_rb_node *mnode, * prevent a deadlock when hfi1_release_user_pages() attempts to * take the mmap_sem, which the MMU notifier has already taken. */ - unpin_vector_pages(mm ? NULL : current->mm, node->pages, node->npages); + unpin_vector_pages(mm ? NULL : current->mm, node->pages, 0, + node->npages); /* * If called by the MMU notifier, we have to adjust the pinned * page count ourselves. -- cgit v1.2.3 From e6d2e0176e1f3c1e1534851b66c0b972f03ff069 Mon Sep 17 00:00:00 2001 From: Jubin John Date: Tue, 12 Apr 2016 10:47:00 -0700 Subject: IB/rdmavt: Fix send scheduling call_send is used to determine whether to send immediately or schedule a send for later. The current logic in rdmavt is inverted and has a negative impact on the latency of the hfi1 and qib drivers. Fix this regression by correctly calling send immediately when call_send is set. Reviewed-by: Dennis Dalessandro Reviewed-by: Mike Marciniszyn Signed-off-by: Jubin John Signed-off-by: Doug Ledford --- drivers/infiniband/sw/rdmavt/qp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index bd82a6948dc8..a9e3bcc522c4 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c @@ -1637,9 +1637,9 @@ bail: spin_unlock_irqrestore(&qp->s_hlock, flags); if (nreq) { if (call_send) - rdi->driver_f.schedule_send_no_lock(qp); - else rdi->driver_f.do_send(qp); + else + rdi->driver_f.schedule_send_no_lock(qp); } return err; } -- cgit v1.2.3 From b9b06cb6fedab10665a2d527464b45f332d17465 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Wed, 20 Apr 2016 06:05:30 -0700 Subject: IB/hfi1: Fix missing lock/unlock in verbs drain callback The iowait_sdma_drained() callback lacked locking to protect the qp s_flags field. This causes the s_flags to be out of sync on multiple CPUs, potentially corrupting the s_flags. Fixes: a545f5308b6c ("staging/rdma/hfi: fix CQ completion order issue") Reviewed-by: Sebastian Sanchez Signed-off-by: Mike Marciniszyn Reviewed-by: Leon Romanovsky Signed-off-by: Doug Ledford --- drivers/staging/rdma/hfi1/qp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/rdma/hfi1/qp.c b/drivers/staging/rdma/hfi1/qp.c index 29a5ad28019b..dc9119e1b458 100644 --- a/drivers/staging/rdma/hfi1/qp.c +++ b/drivers/staging/rdma/hfi1/qp.c @@ -519,10 +519,12 @@ static void iowait_sdma_drained(struct iowait *wait) * do the flush work until that QP's * sdma work has finished. */ + spin_lock(&qp->s_lock); if (qp->s_flags & RVT_S_WAIT_DMA) { qp->s_flags &= ~RVT_S_WAIT_DMA; hfi1_schedule_send(qp); } + spin_unlock(&qp->s_lock); } /** -- cgit v1.2.3 From 94158442eb0c66bbb0b733999e108fa26a7673ef Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Wed, 20 Apr 2016 06:05:36 -0700 Subject: IB/hfi1: Don't attempt to free resources if initialization failed Attempting to free resources which have not been allocated and initialized properly led to the following kernel backtrace: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] unlock_exp_tids.isra.8+0x2e/0x120 [hfi1] PGD 852a43067 PUD 85d4a6067 PMD 0 Oops: 0000 [#1] SMP CPU: 0 PID: 2831 Comm: osu_bw Tainted: G IO 3.12.18-wfr+ #1 task: ffff88085b15b540 ti: ffff8808588fe000 task.ti: ffff8808588fe000 RIP: 0010:[] [] unlock_exp_tids.isra.8+0x2e/0x120 [hfi1] RSP: 0018:ffff8808588ffde0 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff880858a31800 RCX: 0000000000000000 RDX: ffff88085d971bc0 RSI: ffff880858a318f8 RDI: ffff880858a318c0 RBP: ffff8808588ffe20 R08: 0000000000000000 R09: 0000000000000000 R10: ffff88087ffd6f40 R11: 0000000001100348 R12: ffff880852900000 R13: ffff880858a318c0 R14: 0000000000000000 R15: ffff88085d971be8 FS: 00007f4674e83740(0000) GS:ffff88087f400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000085c377000 CR4: 00000000001407f0 Stack: ffffffffa0941a71 ffff880858a318f8 ffff88085d971bc0 ffff880858a31800 ffff880852900000 ffff880858a31800 00000000003ffff7 ffff88085d971bc0 ffff8808588ffe60 ffffffffa09663fc ffff8808588ffe60 ffff880858a31800 Call Trace: [] ? find_mmu_handler+0x51/0x70 [hfi1] [] hfi1_user_exp_rcv_free+0x6c/0x120 [hfi1] [] hfi1_file_close+0x1a9/0x340 [hfi1] [] __fput+0xe9/0x270 [] ____fput+0xe/0x10 [] task_work_run+0xa7/0xe0 [] do_notify_resume+0x59/0x80 [] int_signal+0x12/0x17 This commit re-arranges the context initialization code in a way that would allow for context event flags to be used to determine whether the context has been successfully initialized. In turn, this can be used to skip the resource de-allocation if they were never allocated in the first place. Fixes: 3abb33ac6521 ("staging/hfi1: Add TID cache receive init and free funcs") Reviewed-by: Dennis Dalessandro Signed-off-by: Mitko Haralanov Reviewed-by: Leon Romanovsky --- drivers/staging/rdma/hfi1/file_ops.c | 60 ++++++++++++++------------------ drivers/staging/rdma/hfi1/user_exp_rcv.c | 2 ++ 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index 8396dc5fb6c1..ec6c2269d739 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -791,15 +791,16 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) spin_unlock_irqrestore(&dd->uctxt_lock, flags); dd->rcd[uctxt->ctxt] = NULL; + + hfi1_user_exp_rcv_free(fdata); + hfi1_clear_ctxt_pkey(dd, uctxt->ctxt); + uctxt->rcvwait_to = 0; uctxt->piowait_to = 0; uctxt->rcvnowait = 0; uctxt->pionowait = 0; uctxt->event_flags = 0; - hfi1_user_exp_rcv_free(fdata); - hfi1_clear_ctxt_pkey(dd, uctxt->ctxt); - hfi1_stats.sps_ctxts--; if (++dd->freectxts == dd->num_user_contexts) aspm_enable_all(dd); @@ -1127,27 +1128,13 @@ bail: static int user_init(struct file *fp) { - int ret; unsigned int rcvctrl_ops = 0; struct hfi1_filedata *fd = fp->private_data; struct hfi1_ctxtdata *uctxt = fd->uctxt; /* make sure that the context has already been setup */ - if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) { - ret = -EFAULT; - goto done; - } - - /* - * Subctxts don't need to initialize anything since master - * has done it. - */ - if (fd->subctxt) { - ret = wait_event_interruptible(uctxt->wait, !test_bit( - HFI1_CTXT_MASTER_UNINIT, - &uctxt->event_flags)); - goto expected; - } + if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) + return -EFAULT; /* initialize poll variables... */ uctxt->urgent = 0; @@ -1202,19 +1189,7 @@ static int user_init(struct file *fp) wake_up(&uctxt->wait); } -expected: - /* - * Expected receive has to be setup for all processes (including - * shared contexts). However, it has to be done after the master - * context has been fully configured as it depends on the - * eager/expected split of the RcvArray entries. - * Setting it up here ensures that the subcontexts will be waiting - * (due to the above wait_event_interruptible() until the master - * is setup. - */ - ret = hfi1_user_exp_rcv_init(fp); -done: - return ret; + return 0; } static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len) @@ -1261,7 +1236,7 @@ static int setup_ctxt(struct file *fp) int ret = 0; /* - * Context should be set up only once (including allocation and + * Context should be set up only once, including allocation and * programming of eager buffers. This is done if context sharing * is not requested or by the master process. */ @@ -1282,8 +1257,27 @@ static int setup_ctxt(struct file *fp) if (ret) goto done; } + } else { + ret = wait_event_interruptible(uctxt->wait, !test_bit( + HFI1_CTXT_MASTER_UNINIT, + &uctxt->event_flags)); + if (ret) + goto done; } + ret = hfi1_user_sdma_alloc_queues(uctxt, fp); + if (ret) + goto done; + /* + * Expected receive has to be setup for all processes (including + * shared contexts). However, it has to be done after the master + * context has been fully configured as it depends on the + * eager/expected split of the RcvArray entries. + * Setting it up here ensures that the subcontexts will be waiting + * (due to the above wait_event_interruptible() until the master + * is setup. + */ + ret = hfi1_user_exp_rcv_init(fp); if (ret) goto done; diff --git a/drivers/staging/rdma/hfi1/user_exp_rcv.c b/drivers/staging/rdma/hfi1/user_exp_rcv.c index 5b72849bbd71..8bd56d5c783d 100644 --- a/drivers/staging/rdma/hfi1/user_exp_rcv.c +++ b/drivers/staging/rdma/hfi1/user_exp_rcv.c @@ -255,6 +255,8 @@ int hfi1_user_exp_rcv_free(struct hfi1_filedata *fd) struct hfi1_ctxtdata *uctxt = fd->uctxt; struct tid_group *grp, *gptr; + if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) + return 0; /* * The notifier would have been removed when the process'es mm * was freed. -- cgit v1.2.3 From 7723d8c2445c4dfa91f8df42703b56f8ade59af7 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Fri, 22 Apr 2016 11:17:03 -0700 Subject: IB/hfi1: Use kernel default llseek for ui device The ui device llseek had a mistake with SEEK_END and did not fully follow seek semantics. Correct all this by using a kernel supplied function for fixed size devices. Cc: Al Viro Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Doug Ledford --- drivers/staging/rdma/hfi1/file_ops.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index ec6c2269d739..541529589736 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -1559,29 +1559,8 @@ static loff_t ui_lseek(struct file *filp, loff_t offset, int whence) { struct hfi1_devdata *dd = filp->private_data; - switch (whence) { - case SEEK_SET: - break; - case SEEK_CUR: - offset += filp->f_pos; - break; - case SEEK_END: - offset = ((dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE) - - offset; - break; - default: - return -EINVAL; - } - - if (offset < 0) - return -EINVAL; - - if (offset >= (dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE) - return -EINVAL; - - filp->f_pos = offset; - - return filp->f_pos; + return fixed_size_llseek(filp, offset, whence, + (dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE); } /* NOTE: assumes unsigned long is 8 bytes */ -- cgit v1.2.3 From e6bd18f57aad1a2d1ef40e646d03ed0f2515c9e3 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Sun, 10 Apr 2016 19:13:13 -0600 Subject: IB/security: Restrict use of the write() interface The drivers/infiniband stack uses write() as a replacement for bi-directional ioctl(). This is not safe. There are ways to trigger write calls that result in the return structure that is normally written to user space being shunted off to user specified kernel memory instead. For the immediate repair, detect and deny suspicious accesses to the write API. For long term, update the user space libraries and the kernel API to something that doesn't present the same security vulnerabilities (likely a structured ioctl() interface). The impacted uAPI interfaces are generally only available if hardware from drivers/infiniband is installed in the system. Reported-by: Jann Horn Signed-off-by: Linus Torvalds Signed-off-by: Jason Gunthorpe [ Expanded check to all known write() entry points ] Cc: stable@vger.kernel.org Signed-off-by: Doug Ledford --- drivers/infiniband/core/ucm.c | 4 ++++ drivers/infiniband/core/ucma.c | 3 +++ drivers/infiniband/core/uverbs_main.c | 5 +++++ drivers/infiniband/hw/qib/qib_file_ops.c | 5 +++++ drivers/staging/rdma/hfi1/TODO | 2 +- drivers/staging/rdma/hfi1/file_ops.c | 6 ++++++ include/rdma/ib.h | 16 ++++++++++++++++ 7 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 4a9aa0433b07..7713ef089c3c 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -48,6 +48,7 @@ #include +#include #include #include #include @@ -1103,6 +1104,9 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf, struct ib_ucm_cmd_hdr hdr; ssize_t result; + if (WARN_ON_ONCE(!ib_safe_file_access(filp))) + return -EACCES; + if (len < sizeof(hdr)) return -EINVAL; diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index dd3bcceadfde..c0f3826abb30 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -1574,6 +1574,9 @@ static ssize_t ucma_write(struct file *filp, const char __user *buf, struct rdma_ucm_cmd_hdr hdr; ssize_t ret; + if (WARN_ON_ONCE(!ib_safe_file_access(filp))) + return -EACCES; + if (len < sizeof(hdr)) return -EINVAL; diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 28ba2cc81535..31f422a70623 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -48,6 +48,8 @@ #include +#include + #include "uverbs.h" MODULE_AUTHOR("Roland Dreier"); @@ -709,6 +711,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, int srcu_key; ssize_t ret; + if (WARN_ON_ONCE(!ib_safe_file_access(filp))) + return -EACCES; + if (count < sizeof hdr) return -EINVAL; diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index e449e394963f..24f4a782e0f4 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c @@ -45,6 +45,8 @@ #include #include +#include + #include "qib.h" #include "qib_common.h" #include "qib_user_sdma.h" @@ -2067,6 +2069,9 @@ static ssize_t qib_write(struct file *fp, const char __user *data, ssize_t ret = 0; void *dest; + if (WARN_ON_ONCE(!ib_safe_file_access(fp))) + return -EACCES; + if (count < sizeof(cmd.type)) { ret = -EINVAL; goto bail; diff --git a/drivers/staging/rdma/hfi1/TODO b/drivers/staging/rdma/hfi1/TODO index 05de0dad8762..4c6f1d7d2eaf 100644 --- a/drivers/staging/rdma/hfi1/TODO +++ b/drivers/staging/rdma/hfi1/TODO @@ -3,4 +3,4 @@ July, 2015 - Remove unneeded file entries in sysfs - Remove software processing of IB protocol and place in library for use by qib, ipath (if still present), hfi1, and eventually soft-roce - +- Replace incorrect uAPI diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c index 541529589736..c1c5bf82addb 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/staging/rdma/hfi1/file_ops.c @@ -49,6 +49,8 @@ #include #include +#include + #include "hfi.h" #include "pio.h" #include "device.h" @@ -190,6 +192,10 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, int uctxt_required = 1; int must_be_root = 0; + /* FIXME: This interface cannot continue out of staging */ + if (WARN_ON_ONCE(!ib_safe_file_access(fp))) + return -EACCES; + if (count < sizeof(cmd)) { ret = -EINVAL; goto bail; diff --git a/include/rdma/ib.h b/include/rdma/ib.h index cf8f9e700e48..a6b93706b0fc 100644 --- a/include/rdma/ib.h +++ b/include/rdma/ib.h @@ -34,6 +34,7 @@ #define _RDMA_IB_H #include +#include struct ib_addr { union { @@ -86,4 +87,19 @@ struct sockaddr_ib { __u64 sib_scope_id; }; +/* + * The IB interfaces that use write() as bi-directional ioctl() are + * fundamentally unsafe, since there are lots of ways to trigger "write()" + * calls from various contexts with elevated privileges. That includes the + * traditional suid executable error message writes, but also various kernel + * interfaces that can write to file descriptors. + * + * This function provides protection for the legacy API by restricting the + * calling context. + */ +static inline bool ib_safe_file_access(struct file *filp) +{ + return filp->f_cred == current_cred() && segment_eq(get_fs(), USER_DS); +} + #endif /* _RDMA_IB_H */ -- cgit v1.2.3 From 1883598d4201361a6d2ce785095695f58071ee11 Mon Sep 17 00:00:00 2001 From: Charmaine Lee Date: Tue, 12 Apr 2016 08:14:23 -0700 Subject: drm/vmwgfx: Enable SVGA_3D_CMD_DX_SET_PREDICATION Fixes piglit tests nv_conditional_render-* crashes. Signed-off-by: Charmaine Lee Reviewed-by: Brian Paul Reviewed-by: Sinclair Yeh --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 723ba16c6084..541b34077de2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -3305,7 +3305,7 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_READBACK_QUERY, &vmw_cmd_invalid, true, false, true), - VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_invalid, + VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_dx_cid_check, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_VIEWPORTS, &vmw_cmd_dx_cid_check, true, false, true), -- cgit v1.2.3 From e02e58843153ce80a9fe7588def89b2638d40e64 Mon Sep 17 00:00:00 2001 From: Charmaine Lee Date: Tue, 12 Apr 2016 08:19:08 -0700 Subject: drm/vmwgfx: use vmw_cmd_dx_cid_check for query commands. Instead of calling vmw_cmd_ok, call vmw_cmd_dx_cid_check to validate the context id for query commands. Signed-off-by: Charmaine Lee Reviewed-by: Sinclair Yeh --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 541b34077de2..1a1a87cbf109 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -3293,15 +3293,15 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { &vmw_cmd_dx_cid_check, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_QUERY, &vmw_cmd_dx_define_query, true, false, true), - VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_ok, + VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_dx_cid_check, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_QUERY, &vmw_cmd_dx_bind_query, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_QUERY_OFFSET, - &vmw_cmd_ok, true, false, true), - VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_ok, + &vmw_cmd_dx_cid_check, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_dx_cid_check, true, false, true), - VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_ok, + VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_dx_cid_check, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_READBACK_QUERY, &vmw_cmd_invalid, true, false, true), -- cgit v1.2.3 From 7851496a32319237456919575e5f4ba62f74cc7d Mon Sep 17 00:00:00 2001 From: Sinclair Yeh Date: Thu, 21 Apr 2016 11:29:31 -0700 Subject: drm/vmwgfx: Fix order of operation mode->hdisplay * (var->bits_per_pixel + 7) gets evaluated before the division, potentially making the pitch larger than it should be. Since the original intention is to do a div-round-up, just use the macro instead. Signed-off-by: Sinclair Yeh Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 3b1faf7862a5..679a4cb98ee3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -573,9 +573,9 @@ static int vmw_fb_set_par(struct fb_info *info) mode = old_mode; old_mode = NULL; } else if (!vmw_kms_validate_mode_vram(vmw_priv, - mode->hdisplay * - (var->bits_per_pixel + 7) / 8, - mode->vdisplay)) { + mode->hdisplay * + DIV_ROUND_UP(var->bits_per_pixel, 8), + mode->vdisplay)) { drm_mode_destroy(vmw_priv->dev, mode); return -EINVAL; } -- cgit v1.2.3 From edb9a1b8942b32762b1179039debf2172ad9cc32 Mon Sep 17 00:00:00 2001 From: Eric Engestrom Date: Mon, 25 Apr 2016 07:36:56 +0100 Subject: Documentation: networking: fix spelling mistakes Signed-off-by: Eric Engestrom Signed-off-by: David S. Miller --- Documentation/networking/altera_tse.txt | 6 +++--- Documentation/networking/ipvlan.txt | 6 +++--- Documentation/networking/pktgen.txt | 6 +++--- Documentation/networking/vrf.txt | 2 +- Documentation/networking/xfrm_sync.txt | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Documentation/networking/altera_tse.txt b/Documentation/networking/altera_tse.txt index 3f24df8c6e65..50b8589d12fd 100644 --- a/Documentation/networking/altera_tse.txt +++ b/Documentation/networking/altera_tse.txt @@ -6,7 +6,7 @@ This is the driver for the Altera Triple-Speed Ethernet (TSE) controllers using the SGDMA and MSGDMA soft DMA IP components. The driver uses the platform bus to obtain component resources. The designs used to test this driver were built for a Cyclone(R) V SOC FPGA board, a Cyclone(R) V FPGA board, -and tested with ARM and NIOS processor hosts seperately. The anticipated use +and tested with ARM and NIOS processor hosts separately. The anticipated use cases are simple communications between an embedded system and an external peer for status and simple configuration of the embedded system. @@ -65,14 +65,14 @@ Driver parameters can be also passed in command line by using: 4.1) Transmit process When the driver's transmit routine is called by the kernel, it sets up a transmit descriptor by calling the underlying DMA transmit routine (SGDMA or -MSGDMA), and initites a transmit operation. Once the transmit is complete, an +MSGDMA), and initiates a transmit operation. Once the transmit is complete, an interrupt is driven by the transmit DMA logic. The driver handles the transmit completion in the context of the interrupt handling chain by recycling resource required to send and track the requested transmit operation. 4.2) Receive process The driver will post receive buffers to the receive DMA logic during driver -intialization. Receive buffers may or may not be queued depending upon the +initialization. Receive buffers may or may not be queued depending upon the underlying DMA logic (MSGDMA is able queue receive buffers, SGDMA is not able to queue receive buffers to the SGDMA receive logic). When a packet is received, the DMA logic generates an interrupt. The driver handles a receive diff --git a/Documentation/networking/ipvlan.txt b/Documentation/networking/ipvlan.txt index cf996394e466..14422f8fcdc4 100644 --- a/Documentation/networking/ipvlan.txt +++ b/Documentation/networking/ipvlan.txt @@ -8,7 +8,7 @@ Initial Release: This is conceptually very similar to the macvlan driver with one major exception of using L3 for mux-ing /demux-ing among slaves. This property makes the master device share the L2 with it's slave devices. I have developed this -driver in conjuntion with network namespaces and not sure if there is use case +driver in conjunction with network namespaces and not sure if there is use case outside of it. @@ -42,7 +42,7 @@ out. In this mode the slaves will RX/TX multicast and broadcast (if applicable) as well. 4.2 L3 mode: - In this mode TX processing upto L3 happens on the stack instance attached + In this mode TX processing up to L3 happens on the stack instance attached to the slave device and packets are switched to the stack instance of the master device for the L2 processing and routing from that instance will be used before packets are queued on the outbound device. In this mode the slaves @@ -56,7 +56,7 @@ situations defines your use case then you can choose to use ipvlan - (a) The Linux host that is connected to the external switch / router has policy configured that allows only one mac per port. (b) No of virtual devices created on a master exceed the mac capacity and -puts the NIC in promiscous mode and degraded performance is a concern. +puts the NIC in promiscuous mode and degraded performance is a concern. (c) If the slave device is to be put into the hostile / untrusted network namespace where L2 on the slave could be changed / misused. diff --git a/Documentation/networking/pktgen.txt b/Documentation/networking/pktgen.txt index f4be85e96005..2c4e3354e128 100644 --- a/Documentation/networking/pktgen.txt +++ b/Documentation/networking/pktgen.txt @@ -67,12 +67,12 @@ The two basic thread commands are: * add_device DEVICE@NAME -- adds a single device * rem_device_all -- remove all associated devices -When adding a device to a thread, a corrosponding procfile is created +When adding a device to a thread, a corresponding procfile is created which is used for configuring this device. Thus, device names need to be unique. To support adding the same device to multiple threads, which is useful -with multi queue NICs, a the device naming scheme is extended with "@": +with multi queue NICs, the device naming scheme is extended with "@": device@something The part after "@" can be anything, but it is custom to use the thread @@ -221,7 +221,7 @@ Sample scripts A collection of tutorial scripts and helpers for pktgen is in the samples/pktgen directory. The helper parameters.sh file support easy -and consistant parameter parsing across the sample scripts. +and consistent parameter parsing across the sample scripts. Usage example and help: ./pktgen_sample01_simple.sh -i eth4 -m 00:1B:21:3C:9D:F8 -d 192.168.8.2 diff --git a/Documentation/networking/vrf.txt b/Documentation/networking/vrf.txt index d52aa10cfe91..5da679c573d2 100644 --- a/Documentation/networking/vrf.txt +++ b/Documentation/networking/vrf.txt @@ -41,7 +41,7 @@ using an rx_handler which gives the impression that packets flow through the VRF device. Similarly on egress routing rules are used to send packets to the VRF device driver before getting sent out the actual interface. This allows tcpdump on a VRF device to capture all packets into and out of the -VRF as a whole.[1] Similiarly, netfilter [2] and tc rules can be applied +VRF as a whole.[1] Similarly, netfilter [2] and tc rules can be applied using the VRF device to specify rules that apply to the VRF domain as a whole. [1] Packets in the forwarded state do not flow through the device, so those diff --git a/Documentation/networking/xfrm_sync.txt b/Documentation/networking/xfrm_sync.txt index d7aac9dedeb4..8d88e0f2ec49 100644 --- a/Documentation/networking/xfrm_sync.txt +++ b/Documentation/networking/xfrm_sync.txt @@ -4,7 +4,7 @@ Krisztian and others and additional patches from Jamal . The end goal for syncing is to be able to insert attributes + generate -events so that the an SA can be safely moved from one machine to another +events so that the SA can be safely moved from one machine to another for HA purposes. The idea is to synchronize the SA so that the takeover machine can do the processing of the SA as accurate as possible if it has access to it. @@ -13,7 +13,7 @@ We already have the ability to generate SA add/del/upd events. These patches add ability to sync and have accurate lifetime byte (to ensure proper decay of SAs) and replay counters to avoid replay attacks with as minimal loss at failover time. -This way a backup stays as closely uptodate as an active member. +This way a backup stays as closely up-to-date as an active member. Because the above items change for every packet the SA receives, it is possible for a lot of the events to be generated. @@ -163,7 +163,7 @@ If you have an SA that is getting hit by traffic in bursts such that there is a period where the timer threshold expires with no packets seen, then an odd behavior is seen as follows: The first packet arrival after a timer expiry will trigger a timeout -aevent; i.e we dont wait for a timeout period or a packet threshold +event; i.e we don't wait for a timeout period or a packet threshold to be reached. This is done for simplicity and efficiency reasons. -JHS -- cgit v1.2.3 From 4be2b49e2820eeaf6436bf7c6d0099c86b6cd237 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 25 Apr 2016 10:59:19 +0200 Subject: myri10ge: fix sleeping with bh disabled napi_disable() can not be called with bh disabled, move locking just around myri10ge_ss_lock_napi() . Patches fixes following bug: [ 114.278378] BUG: sleeping function called from invalid context at net/core/dev.c:4383 [ 114.313712] Call Trace: [ 114.314943] [] dump_stack+0x19/0x1b [ 114.317673] [] __might_sleep+0x173/0x230 [ 114.320566] [] napi_disable+0x27/0x90 [ 114.323254] [] myri10ge_close+0xbf/0x3f0 [myri10ge] Signed-off-by: Stanislaw Gruszka Acked-by: Hyong-Youb Kim Signed-off-by: David S. Miller --- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 270c9eeb7ab6..6d1a956e3f77 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -2668,9 +2668,9 @@ static int myri10ge_close(struct net_device *dev) del_timer_sync(&mgp->watchdog_timer); mgp->running = MYRI10GE_ETH_STOPPING; - local_bh_disable(); /* myri10ge_ss_lock_napi needs bh disabled */ for (i = 0; i < mgp->num_slices; i++) { napi_disable(&mgp->ss[i].napi); + local_bh_disable(); /* myri10ge_ss_lock_napi needs this */ /* Lock the slice to prevent the busy_poll handler from * accessing it. Later when we bring the NIC up, myri10ge_open * resets the slice including this lock. @@ -2679,8 +2679,8 @@ static int myri10ge_close(struct net_device *dev) pr_info("Slice %d locked\n", i); mdelay(1); } + local_bh_enable(); } - local_bh_enable(); netif_carrier_off(dev); netif_tx_stop_all_queues(dev); -- cgit v1.2.3 From dcb4123cbec0294eee1815cfaa1e9b4a8fddb06a Mon Sep 17 00:00:00 2001 From: Jon Cooper Date: Mon, 25 Apr 2016 16:51:00 +0100 Subject: sfc: disable RSS when unsupported When certain firmware variants are selected (via the sfboot utility) the SFC7000 and SFC8000 series NICs don't support RSS. The driver still tries (and fails) to insert filters with the RSS flag, and the NIC fails to pass traffic. When the firmware reports RSS_LIMITED suppress allocating a default RSS context. The absence of an RSS context is picked up in filter insertion and RSS flags are discarded. Signed-off-by: Bert Kenward Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/ef10.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 98d33d462c6c..1681084cc96f 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -1920,6 +1920,10 @@ static int efx_ef10_alloc_rss_context(struct efx_nic *efx, u32 *context, return 0; } + if (nic_data->datapath_caps & + 1 << MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_LBN) + return -EOPNOTSUPP; + MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID, nic_data->vport_id); MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_TYPE, alloc_type); @@ -2923,9 +2927,16 @@ static void efx_ef10_filter_push_prep(struct efx_nic *efx, bool replacing) { struct efx_ef10_nic_data *nic_data = efx->nic_data; + u32 flags = spec->flags; memset(inbuf, 0, MC_CMD_FILTER_OP_IN_LEN); + /* Remove RSS flag if we don't have an RSS context. */ + if (flags & EFX_FILTER_FLAG_RX_RSS && + spec->rss_context == EFX_FILTER_RSS_CONTEXT_DEFAULT && + nic_data->rx_rss_context == EFX_EF10_RSS_CONTEXT_INVALID) + flags &= ~EFX_FILTER_FLAG_RX_RSS; + if (replacing) { MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP, MC_CMD_FILTER_OP_IN_OP_REPLACE); @@ -2985,10 +2996,10 @@ static void efx_ef10_filter_push_prep(struct efx_nic *efx, spec->dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP ? 0 : spec->dmaq_id); MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_MODE, - (spec->flags & EFX_FILTER_FLAG_RX_RSS) ? + (flags & EFX_FILTER_FLAG_RX_RSS) ? MC_CMD_FILTER_OP_IN_RX_MODE_RSS : MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE); - if (spec->flags & EFX_FILTER_FLAG_RX_RSS) + if (flags & EFX_FILTER_FLAG_RX_RSS) MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_CONTEXT, spec->rss_context != EFX_FILTER_RSS_CONTEXT_DEFAULT ? -- cgit v1.2.3 From e00f80173bacba88a80ec531f78f04c5ae92d7d1 Mon Sep 17 00:00:00 2001 From: Bert Kenward Date: Mon, 25 Apr 2016 17:42:12 +0100 Subject: MAINTAINERS: net: update sfc maintainers Add myself and Edward Cree as maintainers. Remove Shradha Shah, who is on extended leave. Cc: David S. Miller Cc: Edward Cree Cc: Shradha Shah Signed-off-by: Bert Kenward Acked-by: Edward Cree Signed-off-by: David S. Miller --- MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 849133608da7..17ad61503184 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10014,7 +10014,8 @@ F: drivers/infiniband/hw/ocrdma/ SFC NETWORK DRIVER M: Solarflare linux maintainers -M: Shradha Shah +M: Edward Cree +M: Bert Kenward L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/sfc/ -- cgit v1.2.3 From 62522ef3c399996f6c8120bfd14b94280bc9f490 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 25 Apr 2016 19:41:38 +0200 Subject: net: ethernet: davinci_emac: Fix devioctl while in fixed link When configured in fixed link, the DaVinci emac driver sets the priv->phydev to NULL and further ioctl calls to the phy_mii_ioctl() causes the kernel to crash. Cc: Brian Hutchinson Fixes: 1bb6aa56bb38 ("net: davinci_emac: Add support for fixed-link PHY") Signed-off-by: Neil Armstrong Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_emac.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 58d58f002559..f56d66e6ec15 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1512,7 +1512,10 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) /* TODO: Add phy read and write and private statistics get feature */ - return phy_mii_ioctl(priv->phydev, ifrq, cmd); + if (priv->phydev) + return phy_mii_ioctl(priv->phydev, ifrq, cmd); + else + return -EOPNOTSUPP; } static int match_first_device(struct device *dev, void *data) -- cgit v1.2.3 From 7b7483409f09c15f30ac43242ead1ab3061e1f59 Mon Sep 17 00:00:00 2001 From: Marcelo Ricardo Leitner Date: Mon, 25 Apr 2016 15:13:17 -0300 Subject: net: fix net_gso_ok for new GSO types. Fix casting in net_gso_ok. Otherwise the shift on gso_type << NETIF_F_GSO_SHIFT may hit the 32th bit and make it look like a INT_MIN, which is then promoted from signed to uint64 which is 0xffffffff80000000, resulting in wrong behavior when it is and'ed with the feature itself, as in: This test app: #include #include int main(int argc, char **argv) { uint64_t feature1; uint64_t feature2; int gso_type = 1 << 15; feature1 = gso_type << 16; feature2 = (uint64_t)gso_type << 16; printf("%lx %lx\n", feature1, feature2); return 0; } Gives: ffffffff80000000 80000000 So that this: return (features & feature) == feature; Actually works on more bits than expected and invalid ones. Fix is to promote it earlier. Issue noted while rebasing SCTP GSO patch but posting separetely as someone else may experience this meanwhile. Signed-off-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 8395308a2445..b3c46b019ac1 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -4004,7 +4004,7 @@ netdev_features_t netif_skb_features(struct sk_buff *skb); static inline bool net_gso_ok(netdev_features_t features, int gso_type) { - netdev_features_t feature = gso_type << NETIF_F_GSO_SHIFT; + netdev_features_t feature = (netdev_features_t)gso_type << NETIF_F_GSO_SHIFT; /* check flags correspondence */ BUILD_BUG_ON(SKB_GSO_TCPV4 != (NETIF_F_TSO >> NETIF_F_GSO_SHIFT)); -- cgit v1.2.3 From 1d9619d5337df6cf56eb66b6c8213d1317583513 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 25 Apr 2016 23:11:22 +0100 Subject: net: dsa: mv88e6xxx: fix uninitialized error return The error return err is not initialized and there is a possibility that err is not assigned causing mv88e6xxx_port_bridge_join to return a garbage error return status. Fix this by initializing err to 0. Signed-off-by: Colin Ian King Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index a2904029cccc..5e572b3510b9 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2181,7 +2181,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *bridge) { struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int i, err; + int i, err = 0; mutex_lock(&ps->smi_mutex); -- cgit v1.2.3 From 74d79a2e30c476ccc7d45ecf978f38d815287f81 Mon Sep 17 00:00:00 2001 From: Woojung Huh Date: Mon, 25 Apr 2016 22:22:32 +0000 Subject: lan78xx: fix statistics counter error Fix rx_bytes, tx_bytes and tx_frames error in netdev.stats. - rx_bytes counted bytes excluding size of struct ethhdr. - tx_packets didn't count multiple packets in a single urb - tx_bytes included 8 bytes of extra commands. Signed-off-by: Woojung Huh Signed-off-by: David S. Miller --- drivers/net/usb/lan78xx.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index f20890ee03f3..0460b81a8784 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -269,6 +269,7 @@ struct skb_data { /* skb->cb is one of these */ struct lan78xx_net *dev; enum skb_state state; size_t length; + int num_of_packet; }; struct usb_context { @@ -2464,7 +2465,7 @@ static void tx_complete(struct urb *urb) struct lan78xx_net *dev = entry->dev; if (urb->status == 0) { - dev->net->stats.tx_packets++; + dev->net->stats.tx_packets += entry->num_of_packet; dev->net->stats.tx_bytes += entry->length; } else { dev->net->stats.tx_errors++; @@ -2681,10 +2682,11 @@ void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb) return; } - skb->protocol = eth_type_trans(skb, dev->net); dev->net->stats.rx_packets++; dev->net->stats.rx_bytes += skb->len; + skb->protocol = eth_type_trans(skb, dev->net); + netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n", skb->len + sizeof(struct ethhdr), skb->protocol); memset(skb->cb, 0, sizeof(struct skb_data)); @@ -2934,13 +2936,16 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) skb_totallen = 0; pkt_cnt = 0; + count = 0; + length = 0; for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) { if (skb_is_gso(skb)) { if (pkt_cnt) { /* handle previous packets first */ break; } - length = skb->len; + count = 1; + length = skb->len - TX_OVERHEAD; skb2 = skb_dequeue(tqp); goto gso_skb; } @@ -2961,14 +2966,13 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) for (count = pos = 0; count < pkt_cnt; count++) { skb2 = skb_dequeue(tqp); if (skb2) { + length += (skb2->len - TX_OVERHEAD); memcpy(skb->data + pos, skb2->data, skb2->len); pos += roundup(skb2->len, sizeof(u32)); dev_kfree_skb(skb2); } } - length = skb_totallen; - gso_skb: urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { @@ -2980,6 +2984,7 @@ gso_skb: entry->urb = urb; entry->dev = dev; entry->length = length; + entry->num_of_packet = count; spin_lock_irqsave(&dev->txq.lock, flags); ret = usb_autopm_get_interface_async(dev->intf); -- cgit v1.2.3 From 14437e3fa284f465dbbc8611fd4331ca8d60e986 Mon Sep 17 00:00:00 2001 From: Woojung Huh Date: Mon, 25 Apr 2016 22:22:36 +0000 Subject: lan78xx: workaround of forced 100 Full/Half duplex mode error At forced 100 Full & Half duplex mode, chip may fail to set mode correctly when cable is switched between long(~50+m) and short one. As workaround, set to 10 before setting to 100 at forced 100 F/H mode. Signed-off-by: Woojung Huh Signed-off-by: David S. Miller --- drivers/net/usb/lan78xx.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 0460b81a8784..f64778ad9753 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -1804,7 +1804,34 @@ static void lan78xx_remove_mdio(struct lan78xx_net *dev) static void lan78xx_link_status_change(struct net_device *net) { - /* nothing to do */ + struct phy_device *phydev = net->phydev; + int ret, temp; + + /* At forced 100 F/H mode, chip may fail to set mode correctly + * when cable is switched between long(~50+m) and short one. + * As workaround, set to 10 before setting to 100 + * at forced 100 F/H mode. + */ + if (!phydev->autoneg && (phydev->speed == 100)) { + /* disable phy interrupt */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; + ret = phy_write(phydev, LAN88XX_INT_MASK, temp); + + temp = phy_read(phydev, MII_BMCR); + temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); + phy_write(phydev, MII_BMCR, temp); /* set to 10 first */ + temp |= BMCR_SPEED100; + phy_write(phydev, MII_BMCR, temp); /* set to 100 later */ + + /* clear pending interrupt generated while workaround */ + temp = phy_read(phydev, LAN88XX_INT_STS); + + /* enable phy interrupt back */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; + ret = phy_write(phydev, LAN88XX_INT_MASK, temp); + } } static int lan78xx_phy_init(struct lan78xx_net *dev) -- cgit v1.2.3 From eb63efb4f263f1f4c2375731d3a9e2040030bc6a Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Tue, 26 Apr 2016 04:33:43 +0200 Subject: ps3_gelic: fix memcpy parameter The size allocated for target->hwinfo and the number of bytes copied in it should be consistent. Signed-off-by: Christophe JAILLET Signed-off-by: David S. Miller --- drivers/net/ethernet/toshiba/ps3_gelic_wireless.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index 13214a6492ac..743b18266a7c 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -1622,7 +1622,7 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) continue; /* copy hw scan info */ - memcpy(target->hwinfo, scan_info, scan_info->size); + memcpy(target->hwinfo, scan_info, be16_to_cpu(scan_info->size)); target->essid_len = strnlen(scan_info->essid, sizeof(scan_info->essid)); target->rate_len = 0; -- cgit v1.2.3 From a05d7dfc51417f6437ff35e4682fe547fb665286 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 26 Apr 2016 12:44:18 -0500 Subject: net: phy: at803x: only the AT8030 needs a hardware reset on link change Commit 13a56b44 ("at803x: Add support for hardware reset") added a work-around for a hardware bug on the AT8030. However, the work-around was being called for all 803x PHYs, even those that don't need it. Function at803x_link_change_notify() checks to make sure that it only resets the PHY on the 8030, but it makes more sense to not call that function at all if it isn't needed. Signed-off-by: Timur Tabi Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/at803x.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index b3ffaee30858..f279a897a5c7 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c @@ -359,27 +359,25 @@ static void at803x_link_change_notify(struct phy_device *phydev) * in the FIFO. In such cases, the FIFO enters an error mode it * cannot recover from by software. */ - if (phydev->drv->phy_id == ATH8030_PHY_ID) { - if (phydev->state == PHY_NOLINK) { - if (priv->gpiod_reset && !priv->phy_reset) { - struct at803x_context context; - - at803x_context_save(phydev, &context); - - gpiod_set_value(priv->gpiod_reset, 1); - msleep(1); - gpiod_set_value(priv->gpiod_reset, 0); - msleep(1); - - at803x_context_restore(phydev, &context); - - phydev_dbg(phydev, "%s(): phy was reset\n", - __func__); - priv->phy_reset = true; - } - } else { - priv->phy_reset = false; + if (phydev->state == PHY_NOLINK) { + if (priv->gpiod_reset && !priv->phy_reset) { + struct at803x_context context; + + at803x_context_save(phydev, &context); + + gpiod_set_value(priv->gpiod_reset, 1); + msleep(1); + gpiod_set_value(priv->gpiod_reset, 0); + msleep(1); + + at803x_context_restore(phydev, &context); + + phydev_dbg(phydev, "%s(): phy was reset\n", + __func__); + priv->phy_reset = true; } + } else { + priv->phy_reset = false; } } @@ -391,7 +389,6 @@ static struct phy_driver at803x_driver[] = { .phy_id_mask = 0xffffffef, .probe = at803x_probe, .config_init = at803x_config_init, - .link_change_notify = at803x_link_change_notify, .set_wol = at803x_set_wol, .get_wol = at803x_get_wol, .suspend = at803x_suspend, @@ -427,7 +424,6 @@ static struct phy_driver at803x_driver[] = { .phy_id_mask = 0xffffffef, .probe = at803x_probe, .config_init = at803x_config_init, - .link_change_notify = at803x_link_change_notify, .set_wol = at803x_set_wol, .get_wol = at803x_get_wol, .suspend = at803x_suspend, -- cgit v1.2.3 From a64b04d86d14c81f50f68e102f79ef301e3d0a0e Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Wed, 27 Apr 2016 11:29:06 +0200 Subject: gre: do not assign header_ops in collect metadata mode In ipgre mode (i.e. not gretap) with collect metadata flag set, the tunnel is incorrectly assumed to be mGRE in NBMA mode (see commit 6a5f44d7a048c). This is not the case, we're controlling the encapsulation addresses by lwtunnel metadata. And anyway, assigning dev->header_ops in collect metadata mode does not make sense. Although it would be more user firendly to reject requests that specify both the collect metadata flag and a remote/local IP address, this would break current users of gretap or introduce ugly code and differences in handling ipgre and gretap configuration. Keep the current behavior of remote/local IP address being ignored in such case. v3: Back to v1, added explanation paragraph. v2: Reject configuration specifying both remote/local address and collect metadata flag. Fixes: 2e15ea390e6f4 ("ip_gre: Add support to collect tunnel metadata.") Signed-off-by: Jiri Benc Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index af5d1f38217f..d0abde4236af 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -893,7 +893,7 @@ static int ipgre_tunnel_init(struct net_device *dev) netif_keep_dst(dev); dev->addr_len = 4; - if (iph->daddr) { + if (iph->daddr && !tunnel->collect_md) { #ifdef CONFIG_NET_IPGRE_BROADCAST if (ipv4_is_multicast(iph->daddr)) { if (!iph->saddr) @@ -902,8 +902,9 @@ static int ipgre_tunnel_init(struct net_device *dev) dev->header_ops = &ipgre_header_ops; } #endif - } else + } else if (!tunnel->collect_md) { dev->header_ops = &ipgre_header_ops; + } return ip_tunnel_init(dev); } -- cgit v1.2.3 From 2090714e1d6e80979dd6926be22b0de9ca432273 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Wed, 27 Apr 2016 11:29:07 +0200 Subject: gre: build header correctly for collect metadata tunnels In ipgre (i.e. not gretap) + collect metadata mode, the skb was assumed to contain Ethernet header and was encapsulated as ETH_P_TEB. This is not the case, the interface is ARPHRD_IPGRE and the protocol to be used for encapsulation is skb->protocol. Fixes: 2e15ea390e6f4 ("ip_gre: Add support to collect tunnel metadata.") Signed-off-by: Jiri Benc Acked-by: Pravin B Shelar Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index d0abde4236af..f973e0a58993 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -523,7 +523,8 @@ static struct rtable *gre_get_rt(struct sk_buff *skb, return ip_route_output_key(net, fl); } -static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) +static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, + __be16 proto) { struct ip_tunnel_info *tun_info; const struct ip_tunnel_key *key; @@ -575,7 +576,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) } flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY); - build_header(skb, tunnel_hlen, flags, htons(ETH_P_TEB), + build_header(skb, tunnel_hlen, flags, proto, tunnel_id_to_key(tun_info->key.tun_id), 0); df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; @@ -616,7 +617,7 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, const struct iphdr *tnl_params; if (tunnel->collect_md) { - gre_fb_xmit(skb, dev); + gre_fb_xmit(skb, dev, skb->protocol); return NETDEV_TX_OK; } @@ -660,7 +661,7 @@ static netdev_tx_t gre_tap_xmit(struct sk_buff *skb, struct ip_tunnel *tunnel = netdev_priv(dev); if (tunnel->collect_md) { - gre_fb_xmit(skb, dev); + gre_fb_xmit(skb, dev, htons(ETH_P_TEB)); return NETDEV_TX_OK; } -- cgit v1.2.3 From b7302ca05871e50208bc328cbc8199a21f5d876e Mon Sep 17 00:00:00 2001 From: Petko Manolov Date: Wed, 27 Apr 2016 14:24:49 +0300 Subject: pegasus: fixes URB buffer allocation size; usb_fill_bulk_urb() receives buffer length parameter 8 bytes larger than what's allocated by alloc_skb(); This seems to be a problem with older (pegasus usb-1.1) devices, which may silently return more data than the maximal packet length. Reported-by: Lincoln Ramsay Signed-off-by: Petko Manolov Signed-off-by: David S. Miller --- drivers/net/usb/pegasus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index f84080215915..f919e20360c1 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -528,7 +528,7 @@ static void read_bulk_callback(struct urb *urb) goon: usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, usb_rcvbulkpipe(pegasus->usb, 1), - pegasus->rx_skb->data, PEGASUS_MTU + 8, + pegasus->rx_skb->data, PEGASUS_MTU, read_bulk_callback, pegasus); rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); if (rx_status == -ENODEV) @@ -569,7 +569,7 @@ static void rx_fixup(unsigned long data) } usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, usb_rcvbulkpipe(pegasus->usb, 1), - pegasus->rx_skb->data, PEGASUS_MTU + 8, + pegasus->rx_skb->data, PEGASUS_MTU, read_bulk_callback, pegasus); try_again: status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); @@ -823,7 +823,7 @@ static int pegasus_open(struct net_device *net) usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, usb_rcvbulkpipe(pegasus->usb, 1), - pegasus->rx_skb->data, PEGASUS_MTU + 8, + pegasus->rx_skb->data, PEGASUS_MTU, read_bulk_callback, pegasus); if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { if (res == -ENODEV) -- cgit v1.2.3 From 1a8deec09d12c1a2946f131aa171d5e0479333de Mon Sep 17 00:00:00 2001 From: Petko Manolov Date: Wed, 27 Apr 2016 14:24:50 +0300 Subject: pegasus: fixes reported packet length The default Pegasus setup was to append the status and CRC at the end of each received packet. The status bits are used to update various stats, but CRC has been ignored. The new default is to not append CRC at the end of RX packets. Signed-off-by: Petko Manolov Signed-off-by: David S. Miller --- drivers/net/usb/pegasus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index f919e20360c1..82129eef7774 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -411,7 +411,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) int ret; read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart); - data[0] = 0xc9; + data[0] = 0xc8; /* TX & RX enable, append status, no CRC */ data[1] = 0; if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL)) data[1] |= 0x20; /* set full duplex */ @@ -497,7 +497,7 @@ static void read_bulk_callback(struct urb *urb) pkt_len = buf[count - 3] << 8; pkt_len += buf[count - 4]; pkt_len &= 0xfff; - pkt_len -= 8; + pkt_len -= 4; } /* -- cgit v1.2.3 From 946b636f1730c64e05ff7fe8cf7136422fa8ea70 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Wed, 27 Apr 2016 14:08:01 +0200 Subject: gre: reject GUE and FOU in collect metadata mode The collect metadata mode does not support GUE nor FOU. This might be implemented later; until then, we should reject such config. I think this is okay to be changed. It's unlikely anyone has such configuration (as it doesn't work anyway) and we may need a way to distinguish whether it's supported or not by the kernel later. For backwards compatibility with iproute2, it's not possible to just check the attribute presence (iproute2 always includes the attribute), the actual value has to be checked, too. Fixes: 2e15ea390e6f4 ("ip_gre: Add support to collect tunnel metadata.") Signed-off-by: Jiri Benc Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index f973e0a58993..f502d34bcb40 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -948,6 +948,11 @@ static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[]) if (flags & (GRE_VERSION|GRE_ROUTING)) return -EINVAL; + if (data[IFLA_GRE_COLLECT_METADATA] && + data[IFLA_GRE_ENCAP_TYPE] && + nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) + return -EINVAL; + return 0; } -- cgit v1.2.3 From bbdd09ebd7ce87d2122fcc7d97f35a4f8931bc55 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Wed, 27 Apr 2016 16:46:10 +0200 Subject: MAINTAINERS: net: Change maintainer for GRETH 10/100/1G Ethernet MAC device driver Signed-off-by: Andreas Larsson Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 17ad61503184..d82a21c86dde 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4903,7 +4903,7 @@ F: net/ipv4/gre_offload.c F: include/net/gre.h GRETH 10/100/1G Ethernet MAC device driver -M: Kristoffer Glembo +M: Andreas Larsson L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/aeroflex/ -- cgit v1.2.3 From 552165bcf7060b998b4a9b5b86110b6a5e04dfd9 Mon Sep 17 00:00:00 2001 From: David Rivshin Date: Wed, 27 Apr 2016 21:25:25 -0400 Subject: drivers: net: cpsw: fix parsing of phy-handle DT property in dual_emac config Commit 9e42f715264ff158478fa30eaed847f6e131366b ("drivers: net: cpsw: add phy-handle parsing") saved the "phy-handle" phandle into a new cpsw_priv field. However, phy connections are per-slave, so the phy_node field should be in cpsw_slave_data rather than cpsw_priv. This would go unnoticed in a single emac configuration. But in dual_emac mode, the last "phy-handle" property parsed for either slave would be used by both of them, causing them both to refer to the same phy_device. Fixes: 9e42f715264f ("drivers: net: cpsw: add phy-handle parsing") Signed-off-by: David Rivshin Tested-by: Nicolas Chauvet Tested-by: Andrew Goodbody Reviewed-by: Mugunthan V N Reviewed-by: Grygorii Strashko Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 13 ++++++------- drivers/net/ethernet/ti/cpsw.h | 1 + 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index bbb77cd8ad67..ce0b0caee35b 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -367,7 +367,6 @@ struct cpsw_priv { spinlock_t lock; struct platform_device *pdev; struct net_device *ndev; - struct device_node *phy_node; struct napi_struct napi_rx; struct napi_struct napi_tx; struct device *dev; @@ -1148,8 +1147,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); - if (priv->phy_node) - slave->phy = of_phy_connect(priv->ndev, priv->phy_node, + if (slave->data->phy_node) + slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node, &cpsw_adjust_link, 0, slave->data->phy_if); else slave->phy = phy_connect(priv->ndev, slave->data->phy_id, @@ -1940,12 +1939,11 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, slave->port_vlan = data->dual_emac_res_vlan; } -static int cpsw_probe_dt(struct cpsw_priv *priv, +static int cpsw_probe_dt(struct cpsw_platform_data *data, struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct device_node *slave_node; - struct cpsw_platform_data *data = &priv->data; int i = 0, ret; u32 prop; @@ -2033,7 +2031,8 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, if (strcmp(slave_node->name, "slave")) continue; - priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0); + slave_data->phy_node = of_parse_phandle(slave_node, + "phy-handle", 0); parp = of_get_property(slave_node, "phy_id", &lenp); if (of_phy_is_fixed_link(slave_node)) { struct device_node *phy_node; @@ -2275,7 +2274,7 @@ static int cpsw_probe(struct platform_device *pdev) /* Select default pin state */ pinctrl_pm_select_default_state(&pdev->dev); - if (cpsw_probe_dt(priv, pdev)) { + if (cpsw_probe_dt(&priv->data, pdev)) { dev_err(&pdev->dev, "cpsw: platform data missing\n"); ret = -ENODEV; goto clean_runtime_disable_ret; diff --git a/drivers/net/ethernet/ti/cpsw.h b/drivers/net/ethernet/ti/cpsw.h index 442a7038e660..e50afd1b2eda 100644 --- a/drivers/net/ethernet/ti/cpsw.h +++ b/drivers/net/ethernet/ti/cpsw.h @@ -18,6 +18,7 @@ #include struct cpsw_slave_data { + struct device_node *phy_node; char phy_id[MII_BUS_ID_SIZE]; int phy_if; u8 mac_addr[ETH_ALEN]; -- cgit v1.2.3 From d733f7542ad47cf73e033c90cf55158587e1d060 Mon Sep 17 00:00:00 2001 From: David Rivshin Date: Wed, 27 Apr 2016 21:32:31 -0400 Subject: drivers: net: cpsw: fix segfault in case of bad phy-handle If an emac node has a phy-handle property that points to something which is not a phy, then a segmentation fault will occur when the interface is brought up. This is because while phy_connect() will return ERR_PTR() on failure, of_phy_connect() will return NULL. The common error check uses IS_ERR(), and so missed when of_phy_connect() fails. The NULL pointer is then dereferenced. Also, the common error message referenced slave->data->phy_id, which would be empty in the case of phy-handle. Instead, use the name of the device_node as a useful identifier. And in the phy_id case add the error code for completeness. Fixes: 9e42f715264f ("drivers: net: cpsw: add phy-handle parsing") Signed-off-by: David Rivshin Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index ce0b0caee35b..5903448e8ee9 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -1147,25 +1147,34 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); - if (slave->data->phy_node) + if (slave->data->phy_node) { slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node, &cpsw_adjust_link, 0, slave->data->phy_if); - else + if (!slave->phy) { + dev_err(priv->dev, "phy \"%s\" not found on slave %d\n", + slave->data->phy_node->full_name, + slave->slave_num); + return; + } + } else { slave->phy = phy_connect(priv->ndev, slave->data->phy_id, &cpsw_adjust_link, slave->data->phy_if); - if (IS_ERR(slave->phy)) { - dev_err(priv->dev, "phy %s not found on slave %d\n", - slave->data->phy_id, slave->slave_num); - slave->phy = NULL; - } else { - phy_attached_info(slave->phy); + if (IS_ERR(slave->phy)) { + dev_err(priv->dev, + "phy \"%s\" not found on slave %d, err %ld\n", + slave->data->phy_id, slave->slave_num, + PTR_ERR(slave->phy)); + slave->phy = NULL; + return; + } + } - phy_start(slave->phy); + phy_attached_info(slave->phy); - /* Configure GMII_SEL register */ - cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, - slave->slave_num); - } + phy_start(slave->phy); + + /* Configure GMII_SEL register */ + cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, slave->slave_num); } static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) -- cgit v1.2.3 From ae092b5bded24d5dc7dae0e0aef4669c169ce874 Mon Sep 17 00:00:00 2001 From: David Rivshin Date: Wed, 27 Apr 2016 21:38:26 -0400 Subject: drivers: net: cpsw: don't ignore phy-mode if phy-handle is used The phy-mode emac property was only being processed in the phy_id or fixed-link cases. However if phy-handle was specified instead, an error message would complain about the lack of phy_id or fixed-link, and then jump past the of_get_phy_mode(). This would result in the PHY mode defaulting to MII, regardless of what the devicetree specified. Fixes: 9e42f715264f ("drivers: net: cpsw: add phy-handle parsing") Signed-off-by: David Rivshin Tested-by: Nicolas Chauvet Tested-by: Andrew Goodbody Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 5903448e8ee9..712bc6d75f21 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -2043,7 +2043,11 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, slave_data->phy_node = of_parse_phandle(slave_node, "phy-handle", 0); parp = of_get_property(slave_node, "phy_id", &lenp); - if (of_phy_is_fixed_link(slave_node)) { + if (slave_data->phy_node) { + dev_dbg(&pdev->dev, + "slave[%d] using phy-handle=\"%s\"\n", + i, slave_data->phy_node->full_name); + } else if (of_phy_is_fixed_link(slave_node)) { struct device_node *phy_node; struct phy_device *phy_dev; @@ -2080,7 +2084,9 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), PHY_ID_FMT, mdio->name, phyid); } else { - dev_err(&pdev->dev, "No slave[%d] phy_id or fixed-link property\n", i); + dev_err(&pdev->dev, + "No slave[%d] phy_id, phy-handle, or fixed-link property\n", + i); goto no_phy_slave; } slave_data->phy_if = of_get_phy_mode(slave_node); -- cgit v1.2.3 From a5d2cb3b27441fe7432852d4198eadda1d9d19be Mon Sep 17 00:00:00 2001 From: David Rivshin Date: Wed, 27 Apr 2016 21:42:47 -0400 Subject: dt: cpsw: phy-handle, phy_id, and fixed-link are mutually exclusive The phy-handle, phy_id, and fixed-link properties are mutually exclusive, and only one need be specified. Make this clear in the binding doc. Also mark the phy_id property as deprecated, as phy-handle should be used instead. Signed-off-by: David Rivshin Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/cpsw.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt index 28a4781ab6d7..0ae06491b430 100644 --- a/Documentation/devicetree/bindings/net/cpsw.txt +++ b/Documentation/devicetree/bindings/net/cpsw.txt @@ -45,13 +45,13 @@ Required properties: Optional properties: - dual_emac_res_vlan : Specifies VID to be used to segregate the ports - mac-address : See ethernet.txt file in the same directory -- phy_id : Specifies slave phy id +- phy_id : Specifies slave phy id (deprecated, use phy-handle) - phy-handle : See ethernet.txt file in the same directory Slave sub-nodes: - fixed-link : See fixed-link.txt file in the same directory - Either the property phy_id, or the sub-node - fixed-link can be specified + +Note: Exactly one of phy_id, phy-handle, or fixed-link must be specified. Note: "ti,hwmods" field is used to fetch the base address and irq resources from TI, omap hwmod data base during device registration. -- cgit v1.2.3 From 06cd6d6eda4bedbb826ed36e4c89734ea364ec4b Mon Sep 17 00:00:00 2001 From: David Rivshin Date: Wed, 27 Apr 2016 21:45:45 -0400 Subject: drivers: net: cpsw: use of_phy_connect() in fixed-link case If a fixed-link DT subnode is used, the phy_device was looked up so that a PHY ID string could be constructed and passed to phy_connect(). This is not necessary, as the device_node can be passed directly to of_phy_connect() instead. This reuses the same codepath as if the phy-handle DT property was used. Signed-off-by: David Rivshin Tested-by: Nicolas Chauvet Tested-by: Andrew Goodbody Reviewed-by: Mugunthan V N Reviewed-by: Grygorii Strashko Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 712bc6d75f21..e2fcdf1eec44 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -2048,22 +2048,13 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, "slave[%d] using phy-handle=\"%s\"\n", i, slave_data->phy_node->full_name); } else if (of_phy_is_fixed_link(slave_node)) { - struct device_node *phy_node; - struct phy_device *phy_dev; - /* In the case of a fixed PHY, the DT node associated * to the PHY is the Ethernet MAC DT node. */ ret = of_phy_register_fixed_link(slave_node); if (ret) return ret; - phy_node = of_node_get(slave_node); - phy_dev = of_phy_find_device(phy_node); - if (!phy_dev) - return -ENODEV; - snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), - PHY_ID_FMT, phy_dev->mdio.bus->id, - phy_dev->mdio.addr); + slave_data->phy_node = of_node_get(slave_node); } else if (parp) { u32 phyid; struct device_node *mdio_node; -- cgit v1.2.3 From 92117d8443bc5afacc8d5ba82e541946310f106e Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Wed, 27 Apr 2016 18:56:20 -0700 Subject: bpf: fix refcnt overflow On a system with >32Gbyte of phyiscal memory and infinite RLIMIT_MEMLOCK, the malicious application may overflow 32-bit bpf program refcnt. It's also possible to overflow map refcnt on 1Tb system. Impose 32k hard limit which means that the same bpf program or map cannot be shared by more than 32k processes. Fixes: 1be7f75d1668 ("bpf: enable non-root eBPF programs") Reported-by: Jann Horn Signed-off-by: Alexei Starovoitov Acked-by: Daniel Borkmann Signed-off-by: David S. Miller --- include/linux/bpf.h | 3 ++- kernel/bpf/inode.c | 7 ++++--- kernel/bpf/syscall.c | 24 ++++++++++++++++++++---- kernel/bpf/verifier.c | 11 +++++++---- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 21ee41b92e8a..f1d5c5acc8dd 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -171,12 +171,13 @@ void bpf_register_prog_type(struct bpf_prog_type_list *tl); void bpf_register_map_type(struct bpf_map_type_list *tl); struct bpf_prog *bpf_prog_get(u32 ufd); +struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog); void bpf_prog_put(struct bpf_prog *prog); void bpf_prog_put_rcu(struct bpf_prog *prog); struct bpf_map *bpf_map_get_with_uref(u32 ufd); struct bpf_map *__bpf_map_get(struct fd f); -void bpf_map_inc(struct bpf_map *map, bool uref); +struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref); void bpf_map_put_with_uref(struct bpf_map *map); void bpf_map_put(struct bpf_map *map); int bpf_map_precharge_memlock(u32 pages); diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index f2ece3c174a5..8f94ca1860cf 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c @@ -31,10 +31,10 @@ static void *bpf_any_get(void *raw, enum bpf_type type) { switch (type) { case BPF_TYPE_PROG: - atomic_inc(&((struct bpf_prog *)raw)->aux->refcnt); + raw = bpf_prog_inc(raw); break; case BPF_TYPE_MAP: - bpf_map_inc(raw, true); + raw = bpf_map_inc(raw, true); break; default: WARN_ON_ONCE(1); @@ -297,7 +297,8 @@ static void *bpf_obj_do_get(const struct filename *pathname, goto out; raw = bpf_any_get(inode->i_private, *type); - touch_atime(&path); + if (!IS_ERR(raw)) + touch_atime(&path); path_put(&path); return raw; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index adc5e4bd74f8..cf5e9f7ad13a 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -218,11 +218,18 @@ struct bpf_map *__bpf_map_get(struct fd f) return f.file->private_data; } -void bpf_map_inc(struct bpf_map *map, bool uref) +/* prog's and map's refcnt limit */ +#define BPF_MAX_REFCNT 32768 + +struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref) { - atomic_inc(&map->refcnt); + if (atomic_inc_return(&map->refcnt) > BPF_MAX_REFCNT) { + atomic_dec(&map->refcnt); + return ERR_PTR(-EBUSY); + } if (uref) atomic_inc(&map->usercnt); + return map; } struct bpf_map *bpf_map_get_with_uref(u32 ufd) @@ -234,7 +241,7 @@ struct bpf_map *bpf_map_get_with_uref(u32 ufd) if (IS_ERR(map)) return map; - bpf_map_inc(map, true); + map = bpf_map_inc(map, true); fdput(f); return map; @@ -658,6 +665,15 @@ static struct bpf_prog *__bpf_prog_get(struct fd f) return f.file->private_data; } +struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog) +{ + if (atomic_inc_return(&prog->aux->refcnt) > BPF_MAX_REFCNT) { + atomic_dec(&prog->aux->refcnt); + return ERR_PTR(-EBUSY); + } + return prog; +} + /* called by sockets/tracing/seccomp before attaching program to an event * pairs with bpf_prog_put() */ @@ -670,7 +686,7 @@ struct bpf_prog *bpf_prog_get(u32 ufd) if (IS_ERR(prog)) return prog; - atomic_inc(&prog->aux->refcnt); + prog = bpf_prog_inc(prog); fdput(f); return prog; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index db2574e7b8b0..89bcaa0966da 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2049,15 +2049,18 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env) return -E2BIG; } - /* remember this map */ - env->used_maps[env->used_map_cnt++] = map; - /* hold the map. If the program is rejected by verifier, * the map will be released by release_maps() or it * will be used by the valid program until it's unloaded * and all maps are released in free_bpf_prog_info() */ - bpf_map_inc(map, false); + map = bpf_map_inc(map, false); + if (IS_ERR(map)) { + fdput(f); + return PTR_ERR(map); + } + env->used_maps[env->used_map_cnt++] = map; + fdput(f); next_insn: insn++; -- cgit v1.2.3 From 6aff67c85c9e5a4bc99e5211c1bac547936626ca Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Wed, 27 Apr 2016 18:56:21 -0700 Subject: bpf: fix check_map_func_compatibility logic The commit 35578d798400 ("bpf: Implement function bpf_perf_event_read() that get the selected hardware PMU conuter") introduced clever way to check bpf_helper<->map_type compatibility. Later on commit a43eec304259 ("bpf: introduce bpf_perf_event_output() helper") adjusted the logic and inadvertently broke it. Get rid of the clever bool compare and go back to two-way check from map and from helper perspective. Fixes: a43eec304259 ("bpf: introduce bpf_perf_event_output() helper") Reported-by: Jann Horn Signed-off-by: Alexei Starovoitov Signed-off-by: Daniel Borkmann Signed-off-by: David S. Miller --- kernel/bpf/verifier.c | 65 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 89bcaa0966da..c5c17a62f509 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -239,16 +239,6 @@ static const char * const reg_type_str[] = { [CONST_IMM] = "imm", }; -static const struct { - int map_type; - int func_id; -} func_limit[] = { - {BPF_MAP_TYPE_PROG_ARRAY, BPF_FUNC_tail_call}, - {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_read}, - {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_output}, - {BPF_MAP_TYPE_STACK_TRACE, BPF_FUNC_get_stackid}, -}; - static void print_verifier_state(struct verifier_env *env) { enum bpf_reg_type t; @@ -921,27 +911,52 @@ static int check_func_arg(struct verifier_env *env, u32 regno, static int check_map_func_compatibility(struct bpf_map *map, int func_id) { - bool bool_map, bool_func; - int i; - if (!map) return 0; - for (i = 0; i < ARRAY_SIZE(func_limit); i++) { - bool_map = (map->map_type == func_limit[i].map_type); - bool_func = (func_id == func_limit[i].func_id); - /* only when map & func pair match it can continue. - * don't allow any other map type to be passed into - * the special func; - */ - if (bool_func && bool_map != bool_func) { - verbose("cannot pass map_type %d into func %d\n", - map->map_type, func_id); - return -EINVAL; - } + /* We need a two way check, first is from map perspective ... */ + switch (map->map_type) { + case BPF_MAP_TYPE_PROG_ARRAY: + if (func_id != BPF_FUNC_tail_call) + goto error; + break; + case BPF_MAP_TYPE_PERF_EVENT_ARRAY: + if (func_id != BPF_FUNC_perf_event_read && + func_id != BPF_FUNC_perf_event_output) + goto error; + break; + case BPF_MAP_TYPE_STACK_TRACE: + if (func_id != BPF_FUNC_get_stackid) + goto error; + break; + default: + break; + } + + /* ... and second from the function itself. */ + switch (func_id) { + case BPF_FUNC_tail_call: + if (map->map_type != BPF_MAP_TYPE_PROG_ARRAY) + goto error; + break; + case BPF_FUNC_perf_event_read: + case BPF_FUNC_perf_event_output: + if (map->map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) + goto error; + break; + case BPF_FUNC_get_stackid: + if (map->map_type != BPF_MAP_TYPE_STACK_TRACE) + goto error; + break; + default: + break; } return 0; +error: + verbose("cannot pass map_type %d into func %d\n", + map->map_type, func_id); + return -EINVAL; } static int check_call(struct verifier_env *env, int func_id) -- cgit v1.2.3 From 569cc39d39385a74b23145496bca2df5ac8b2fb8 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Wed, 27 Apr 2016 18:56:22 -0700 Subject: samples/bpf: fix trace_output example llvm cannot always recognize memset as builtin function and optimize it away, so just delete it. It was a leftover from testing of bpf_perf_event_output() with large data structures. Fixes: 39111695b1b8 ("samples: bpf: add bpf_perf_event_output example") Signed-off-by: Alexei Starovoitov Signed-off-by: David S. Miller --- samples/bpf/trace_output_kern.c | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/bpf/trace_output_kern.c b/samples/bpf/trace_output_kern.c index 8d8d1ec429eb..9b96f4fb8cea 100644 --- a/samples/bpf/trace_output_kern.c +++ b/samples/bpf/trace_output_kern.c @@ -18,7 +18,6 @@ int bpf_prog1(struct pt_regs *ctx) u64 cookie; } data; - memset(&data, 0, sizeof(data)); data.pid = bpf_get_current_pid_tgid(); data.cookie = 0x12345678; -- cgit v1.2.3 From 4c8bb95921e9ac01b9dd0c3abbaf6514ce88af92 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Sun, 24 Apr 2016 22:18:59 +0200 Subject: RDMA/nes: don't leak skb if carrier down Alternatively one could free the skb, OTOH I don't think this test is useful so just remove it. Cc: Signed-off-by: Florian Westphal Signed-off-by: Doug Ledford --- drivers/infiniband/hw/nes/nes_nic.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 3ea9e055fdd3..92914539edc7 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -500,9 +500,6 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) * skb_shinfo(skb)->nr_frags, skb_is_gso(skb)); */ - if (!netif_carrier_ok(netdev)) - return NETDEV_TX_OK; - if (netif_queue_stopped(netdev)) return NETDEV_TX_BUSY; -- cgit v1.2.3 From 8639a847b0e11f8d2daa3eafe15a9609c91fd357 Mon Sep 17 00:00:00 2001 From: Atsushi Kumagai Date: Thu, 28 Apr 2016 16:18:18 -0700 Subject: kexec: update VMCOREINFO for compound_order/dtor makedumpfile refers page.lru.next to get the order of compound pages for page filtering. However, now the order is stored in page.compound_order, hence VMCOREINFO should be updated to export the offset of page.compound_order. The fact is, page.compound_order was introduced already in kernel 4.0, but the offset of it was the same as page.lru.next until kernel 4.3, so this was not actual problem. The above can be said also for page.lru.prev and page.compound_dtor, it's necessary to detect hugetlbfs pages. Further, the content was changed from direct address to the ID which means dtor. The problem is that unnecessary hugepages won't be removed from a dump file in kernels 4.4.x and later. This means that extra disk space would be consumed. It's a problem, but not critical. Signed-off-by: Atsushi Kumagai Acked-by: Dave Young Cc: "Eric W. Biederman" Cc: Vivek Goyal Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/kexec_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 8d34308ea449..cbbb4c724149 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -1415,6 +1415,8 @@ static int __init crash_save_vmcoreinfo_init(void) VMCOREINFO_OFFSET(page, lru); VMCOREINFO_OFFSET(page, _mapcount); VMCOREINFO_OFFSET(page, private); + VMCOREINFO_OFFSET(page, compound_dtor); + VMCOREINFO_OFFSET(page, compound_order); VMCOREINFO_OFFSET(pglist_data, node_zones); VMCOREINFO_OFFSET(pglist_data, nr_zones); #ifdef CONFIG_FLAT_NODE_MEM_MAP @@ -1447,8 +1449,8 @@ static int __init crash_save_vmcoreinfo_init(void) #ifdef CONFIG_X86 VMCOREINFO_NUMBER(KERNEL_IMAGE_SIZE); #endif -#ifdef CONFIG_HUGETLBFS - VMCOREINFO_SYMBOL(free_huge_page); +#ifdef CONFIG_HUGETLB_PAGE + VMCOREINFO_NUMBER(HUGETLB_PAGE_DTOR); #endif arch_crash_save_vmcoreinfo(); -- cgit v1.2.3 From d7f53518f713d3d9bf5ed150f943853fb94e7473 Mon Sep 17 00:00:00 2001 From: Atsushi Kumagai Date: Thu, 28 Apr 2016 16:18:21 -0700 Subject: kexec: export OFFSET(page.compound_head) to find out compound tail page PageAnon() always look at head page to check PAGE_MAPPING_ANON and tail page's page->mapping has just a poisoned data since commit 1c290f642101 ("mm: sanitize page->mapping for tail pages"). If makedumpfile checks page->mapping of a compound tail page to distinguish anonymous page as usual, it must fail in newer kernel. So it's necessary to export OFFSET(page.compound_head) to avoid checking compound tail pages. The problem is that unnecessary hugepages won't be removed from a dump file in kernels 4.5.x and later. This means that extra disk space would be consumed. It's a problem, but not critical. Signed-off-by: Atsushi Kumagai Acked-by: Dave Young Cc: "Eric W. Biederman" Cc: Vivek Goyal Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/kexec_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index cbbb4c724149..1391d3ee3b86 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -1417,6 +1417,7 @@ static int __init crash_save_vmcoreinfo_init(void) VMCOREINFO_OFFSET(page, private); VMCOREINFO_OFFSET(page, compound_dtor); VMCOREINFO_OFFSET(page, compound_order); + VMCOREINFO_OFFSET(page, compound_head); VMCOREINFO_OFFSET(pglist_data, node_zones); VMCOREINFO_OFFSET(pglist_data, nr_zones); #ifdef CONFIG_FLAT_NODE_MEM_MAP -- cgit v1.2.3 From 66ee95d16a7f1b7b4f1dd74a2d81c6e19dc29a14 Mon Sep 17 00:00:00 2001 From: Steve Capper Date: Thu, 28 Apr 2016 16:18:24 -0700 Subject: mm: exclude HugeTLB pages from THP page_mapped() logic HugeTLB pages cannot be split, so we use the compound_mapcount to track rmaps. Currently page_mapped() will check the compound_mapcount, but will also go through the constituent pages of a THP compound page and query the individual _mapcount's too. Unfortunately, page_mapped() does not distinguish between HugeTLB and THP compound pages and assumes that a compound page always needs to have HPAGE_PMD_NR pages querying. For most cases when dealing with HugeTLB this is just inefficient, but for scenarios where the HugeTLB page size is less than the pmd block size (e.g. when using contiguous bit on ARM) this can lead to crashes. This patch adjusts the page_mapped function such that we skip the unnecessary THP reference checks for HugeTLB pages. Fixes: e1534ae95004 ("mm: differentiate page_mapped() from page_mapcount() for compound pages") Signed-off-by: Steve Capper Acked-by: Kirill A. Shutemov Cc: Will Deacon Cc: Catalin Marinas Cc: Michal Hocko Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index a55e5be0894f..79b6c18d0a38 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1031,6 +1031,8 @@ static inline bool page_mapped(struct page *page) page = compound_head(page); if (atomic_read(compound_mapcount_ptr(page)) >= 0) return true; + if (PageHuge(page)) + return false; for (i = 0; i < hpage_nr_pages(page); i++) { if (atomic_read(&page[i]._mapcount) >= 0) return true; -- cgit v1.2.3 From aa88b68c3b1dce8bc3fd54c8a7372a777ff265cd Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Thu, 28 Apr 2016 16:18:27 -0700 Subject: thp: keep huge zero page pinned until tlb flush Andrea has found[1] a race condition on MMU-gather based TLB flush vs split_huge_page() or shrinker which frees huge zero under us (patch 1/2 and 2/2 respectively). With new THP refcounting, we don't need patch 1/2: mmu_gather keeps the page pinned until flush is complete and the pin prevents the page from being split under us. We still need patch 2/2. This is simplified version of Andrea's patch. We don't need fancy encoding. [1] http://lkml.kernel.org/r/1447938052-22165-1-git-send-email-aarcange@redhat.com Signed-off-by: Kirill A. Shutemov Reported-by: Andrea Arcangeli Reviewed-by: Andrea Arcangeli Cc: "Aneesh Kumar K.V" Cc: Mel Gorman Cc: Hugh Dickins Cc: Johannes Weiner Cc: Dave Hansen Cc: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/huge_mm.h | 5 +++++ mm/huge_memory.c | 6 +++--- mm/swap.c | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 7008623e24b1..d7b9e5346fba 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -152,6 +152,7 @@ static inline bool is_huge_zero_pmd(pmd_t pmd) } struct page *get_huge_zero_page(void); +void put_huge_zero_page(void); #else /* CONFIG_TRANSPARENT_HUGEPAGE */ #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; }) @@ -208,6 +209,10 @@ static inline bool is_huge_zero_page(struct page *page) return false; } +static inline void put_huge_zero_page(void) +{ + BUILD_BUG(); +} static inline struct page *follow_devmap_pmd(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmd, int flags) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 86f9f8b82f8e..5346de05f471 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -232,7 +232,7 @@ retry: return READ_ONCE(huge_zero_page); } -static void put_huge_zero_page(void) +void put_huge_zero_page(void) { /* * Counter should never go to zero here. Only shrinker can put @@ -1684,12 +1684,12 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, if (vma_is_dax(vma)) { spin_unlock(ptl); if (is_huge_zero_pmd(orig_pmd)) - put_huge_zero_page(); + tlb_remove_page(tlb, pmd_page(orig_pmd)); } else if (is_huge_zero_pmd(orig_pmd)) { pte_free(tlb->mm, pgtable_trans_huge_withdraw(tlb->mm, pmd)); atomic_long_dec(&tlb->mm->nr_ptes); spin_unlock(ptl); - put_huge_zero_page(); + tlb_remove_page(tlb, pmd_page(orig_pmd)); } else { struct page *page = pmd_page(orig_pmd); page_remove_rmap(page, true); diff --git a/mm/swap.c b/mm/swap.c index a0bc206b4ac6..03aacbcb013f 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -728,6 +728,11 @@ void release_pages(struct page **pages, int nr, bool cold) zone = NULL; } + if (is_huge_zero_page(page)) { + put_huge_zero_page(); + continue; + } + page = compound_head(page); if (!put_page_testzero(page)) continue; -- cgit v1.2.3 From 314e9b75b3f673a61ecbf0bba401830bc7dfe121 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 28 Apr 2016 16:18:30 -0700 Subject: mailmap: fix Krzysztof Kozlowski's misspelled name Patchwork introduced a garbled Polish character in commit 1e3012d0fdc5 ("crypto: s5p-sss - Use memcpy_toio for iomem annotated memory") so fix the mail mapping. Additionally prefer to use kernel.org account for personal work, instead of my gmail address. Signed-off-by: Krzysztof Kozlowski Cc: Herbert Xu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 90c0aefc276d..c45e71f551cd 100644 --- a/.mailmap +++ b/.mailmap @@ -79,6 +79,7 @@ Kay Sievers Kenneth W Chen Konstantin Khlebnikov Koushik +Krzysztof Kozlowski Kuninori Morimoto Leonid I Ananiev Linas Vepstas -- cgit v1.2.3 From 3486b85a29c1741db99d0c522211c82d2b7a56d0 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 28 Apr 2016 16:18:32 -0700 Subject: mm/huge_memory: replace VM_NO_THP VM_BUG_ON with actual VMA check Khugepaged detects own VMAs by checking vm_file and vm_ops but this way it cannot distinguish private /dev/zero mappings from other special mappings like /dev/hpet which has no vm_ops and popultes PTEs in mmap. This fixes false-positive VM_BUG_ON and prevents installing THP where they are not expected. Link: http://lkml.kernel.org/r/CACT4Y+ZmuZMV5CjSFOeXviwQdABAgT7T+StKfTqan9YDtgEi5g@mail.gmail.com Fixes: 78f11a255749 ("mm: thp: fix /dev/zero MAP_PRIVATE and vm_flags cleanups") Signed-off-by: Konstantin Khlebnikov Reported-by: Dmitry Vyukov Acked-by: Vlastimil Babka Acked-by: Kirill A. Shutemov Cc: Dmitry Vyukov Cc: Andrea Arcangeli Cc: stable Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/huge_memory.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 5346de05f471..df67b53ae3c5 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1960,10 +1960,9 @@ int khugepaged_enter_vma_merge(struct vm_area_struct *vma, * page fault if needed. */ return 0; - if (vma->vm_ops) + if (vma->vm_ops || (vm_flags & VM_NO_THP)) /* khugepaged not yet working on file or special mappings */ return 0; - VM_BUG_ON_VMA(vm_flags & VM_NO_THP, vma); hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; hend = vma->vm_end & HPAGE_PMD_MASK; if (hstart < hend) @@ -2352,8 +2351,7 @@ static bool hugepage_vma_check(struct vm_area_struct *vma) return false; if (is_vma_temporary_stack(vma)) return false; - VM_BUG_ON_VMA(vma->vm_flags & VM_NO_THP, vma); - return true; + return !(vma->vm_flags & VM_NO_THP); } static void collapse_huge_page(struct mm_struct *mm, -- cgit v1.2.3 From 28093f9f34cedeaea0f481c58446d9dac6dd620f Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Thu, 28 Apr 2016 16:18:35 -0700 Subject: numa: fix /proc//numa_maps for THP In gather_pte_stats() a THP pmd is cast into a pte, which is wrong because the layouts may differ depending on the architecture. On s390 this will lead to inaccurate numa_maps accounting in /proc because of misguided pte_present() and pte_dirty() checks on the fake pte. On other architectures pte_present() and pte_dirty() may work by chance, but there may be an issue with direct-access (dax) mappings w/o underlying struct pages when HAVE_PTE_SPECIAL is set and THP is available. In vm_normal_page() the fake pte will be checked with pte_special() and because there is no "special" bit in a pmd, this will always return false and the VM_PFNMAP | VM_MIXEDMAP checking will be skipped. On dax mappings w/o struct pages, an invalid struct page pointer would then be returned that can crash the kernel. This patch fixes the numa_maps THP handling by introducing new "_pmd" variants of the can_gather_numa_stats() and vm_normal_page() functions. Signed-off-by: Gerald Schaefer Cc: Naoya Horiguchi Cc: "Kirill A . Shutemov" Cc: Konstantin Khlebnikov Cc: Michal Hocko Cc: Vlastimil Babka Cc: Jerome Marchand Cc: Johannes Weiner Cc: Dave Hansen Cc: Mel Gorman Cc: Dan Williams Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: Michael Holzheu Cc: [4.3+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/task_mmu.c | 33 ++++++++++++++++++++++++++++++--- include/linux/mm.h | 2 ++ mm/memory.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 229cb546bee0..541583510cfb 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1518,6 +1518,32 @@ static struct page *can_gather_numa_stats(pte_t pte, struct vm_area_struct *vma, return page; } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static struct page *can_gather_numa_stats_pmd(pmd_t pmd, + struct vm_area_struct *vma, + unsigned long addr) +{ + struct page *page; + int nid; + + if (!pmd_present(pmd)) + return NULL; + + page = vm_normal_page_pmd(vma, addr, pmd); + if (!page) + return NULL; + + if (PageReserved(page)) + return NULL; + + nid = page_to_nid(page); + if (!node_isset(nid, node_states[N_MEMORY])) + return NULL; + + return page; +} +#endif + static int gather_pte_stats(pmd_t *pmd, unsigned long addr, unsigned long end, struct mm_walk *walk) { @@ -1527,14 +1553,14 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr, pte_t *orig_pte; pte_t *pte; +#ifdef CONFIG_TRANSPARENT_HUGEPAGE ptl = pmd_trans_huge_lock(pmd, vma); if (ptl) { - pte_t huge_pte = *(pte_t *)pmd; struct page *page; - page = can_gather_numa_stats(huge_pte, vma, addr); + page = can_gather_numa_stats_pmd(*pmd, vma, addr); if (page) - gather_stats(page, md, pte_dirty(huge_pte), + gather_stats(page, md, pmd_dirty(*pmd), HPAGE_PMD_SIZE/PAGE_SIZE); spin_unlock(ptl); return 0; @@ -1542,6 +1568,7 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr, if (pmd_trans_unstable(pmd)) return 0; +#endif orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); do { struct page *page = can_gather_numa_stats(*pte, vma, addr); diff --git a/include/linux/mm.h b/include/linux/mm.h index 79b6c18d0a38..864d7221de84 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1140,6 +1140,8 @@ struct zap_details { struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_t pte); +struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, + pmd_t pmd); int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, unsigned long size); diff --git a/mm/memory.c b/mm/memory.c index 93897f23cc11..305537fc8640 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -789,6 +789,46 @@ out: return pfn_to_page(pfn); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, + pmd_t pmd) +{ + unsigned long pfn = pmd_pfn(pmd); + + /* + * There is no pmd_special() but there may be special pmds, e.g. + * in a direct-access (dax) mapping, so let's just replicate the + * !HAVE_PTE_SPECIAL case from vm_normal_page() here. + */ + if (unlikely(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))) { + if (vma->vm_flags & VM_MIXEDMAP) { + if (!pfn_valid(pfn)) + return NULL; + goto out; + } else { + unsigned long off; + off = (addr - vma->vm_start) >> PAGE_SHIFT; + if (pfn == vma->vm_pgoff + off) + return NULL; + if (!is_cow_mapping(vma->vm_flags)) + return NULL; + } + } + + if (is_zero_pfn(pfn)) + return NULL; + if (unlikely(pfn > highest_memmap_pfn)) + return NULL; + + /* + * NOTE! We still have PageReserved() pages in the page tables. + * eg. VDSO mappings can cause them to exist. + */ +out: + return pfn_to_page(pfn); +} +#endif + /* * copy one vm_area from one task to the other. Assumes the page tables * already present in the new task to be cleared in the whole range -- cgit v1.2.3 From 7bf52fb891b64b8d61caf0b82060adb9db761aec Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Thu, 28 Apr 2016 16:18:38 -0700 Subject: mm: vmscan: reclaim highmem zone if buffer_heads is over limit We have been reclaimed highmem zone if buffer_heads is over limit but commit 6b4f7799c6a5 ("mm: vmscan: invoke slab shrinkers from shrink_zone()") changed the behavior so it doesn't reclaim highmem zone although buffer_heads is over the limit. This patch restores the logic. Fixes: 6b4f7799c6a5 ("mm: vmscan: invoke slab shrinkers from shrink_zone()") Signed-off-by: Minchan Kim Cc: Johannes Weiner Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index b934223eaa45..c638b28310fc 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2553,7 +2553,7 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc) sc->gfp_mask |= __GFP_HIGHMEM; for_each_zone_zonelist_nodemask(zone, z, zonelist, - requested_highidx, sc->nodemask) { + gfp_zone(sc->gfp_mask), sc->nodemask) { enum zone_type classzone_idx; if (!populated_zone(zone)) -- cgit v1.2.3 From b06bad17c7435b600a1d7a35b56eff25e1d3dbc0 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Thu, 28 Apr 2016 16:18:41 -0700 Subject: mm: call swap_slot_free_notify() with page lock held Kyeongdon reported below error which is BUG_ON(!PageSwapCache(page)) in page_swap_info. The reason is that page_endio in rw_page unlocks the page if read I/O is completed so we need to hold a PG_lock again to check PageSwapCache. Otherwise, the page can be removed from swapcache. Kernel BUG at c00f9040 [verbose debug info unavailable] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM Modules linked in: CPU: 4 PID: 13446 Comm: RenderThread Tainted: G W 3.10.84-g9f14aec-dirty #73 task: c3b73200 ti: dd192000 task.ti: dd192000 PC is at page_swap_info+0x10/0x2c LR is at swap_slot_free_notify+0x18/0x6c pc : [] lr : [] psr: 400f0113 sp : dd193d78 ip : c2deb1e4 fp : da015180 r10: 00000000 r9 : 000200da r8 : c120fe08 r7 : 00000000 r6 : 00000000 r5 : c249a6c0 r4 : = c249a6c0 r3 : 00000000 r2 : 40080009 r1 : 200f0113 r0 : = c249a6c0 .. .. Call Trace: page_swap_info+0x10/0x2c swap_slot_free_notify+0x18/0x6c swap_readpage+0x90/0x11c read_swap_cache_async+0x134/0x1ac swapin_readahead+0x70/0xb0 handle_pte_fault+0x320/0x6fc handle_mm_fault+0xc0/0xf0 do_page_fault+0x11c/0x36c do_DataAbort+0x34/0x118 Fixes: 3f2b1a04f44933f2 ("zram: revive swap_slot_free_notify") Signed-off-by: Minchan Kim Tested-by: Kyeongdon Kim Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_io.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mm/page_io.c b/mm/page_io.c index cd92e3d67a32..985f23cfa79b 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -353,7 +353,11 @@ int swap_readpage(struct page *page) ret = bdev_read_page(sis->bdev, swap_page_sector(page), page); if (!ret) { - swap_slot_free_notify(page); + if (trylock_page(page)) { + swap_slot_free_notify(page); + unlock_page(page); + } + count_vm_event(PSWPIN); return 0; } -- cgit v1.2.3 From d7e69488bd04de165667f6bc741c1c0ec6042ab9 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Thu, 28 Apr 2016 16:18:44 -0700 Subject: mm/hwpoison: fix wrong num_poisoned_pages accounting Currently, migration code increses num_poisoned_pages on *failed* migration page as well as successfully migrated one at the trial of memory-failure. It will make the stat wrong. As well, it marks the page as PG_HWPoison even if the migration trial failed. It would mean we cannot recover the corrupted page using memory-failure facility. This patches fixes it. Signed-off-by: Minchan Kim Reported-by: Vlastimil Babka Acked-by: Naoya Horiguchi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/migrate.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mm/migrate.c b/mm/migrate.c index 6c822a7b27e0..f9dfb18a4eba 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -975,7 +975,13 @@ out: dec_zone_page_state(page, NR_ISOLATED_ANON + page_is_file_cache(page)); /* Soft-offlined page shouldn't go through lru cache list */ - if (reason == MR_MEMORY_FAILURE) { + if (reason == MR_MEMORY_FAILURE && rc == MIGRATEPAGE_SUCCESS) { + /* + * With this release, we free successfully migrated + * page and set PG_HWPoison on just freed page + * intentionally. Although it's rather weird, it's how + * HWPoison flag works at the moment. + */ put_page(page); if (!test_set_page_hwpoison(page)) num_poisoned_pages_inc(); -- cgit v1.2.3 From eeb68d1d2d48b5bfe9d79d8eac35df576bb79a99 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Thu, 28 Apr 2016 16:18:47 -0700 Subject: .mailmap: add Frank Rowand Set current email address to replace obsolete email addresses. Signed-off-by: Frank Rowand Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- .mailmap | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.mailmap b/.mailmap index c45e71f551cd..c156a8b4d845 100644 --- a/.mailmap +++ b/.mailmap @@ -48,6 +48,9 @@ Felix Kuhling Felix Moeller Filipe Lautert Franck Bui-Huu +Frank Rowand +Frank Rowand +Frank Rowand Frank Zago Greg Kroah-Hartman Greg Kroah-Hartman -- cgit v1.2.3 From fd901c95388b3bd5a6f749ed1d677a672b992298 Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Thu, 28 Apr 2016 16:18:49 -0700 Subject: mm: wake kcompactd before kswapd's short sleep When kswapd goes to sleep it checks if the node is balanced and at first it sleeps only for HZ/10 time, then rechecks if the node is still balanced and nobody has woken it during the initial sleep. Only then it goes fully sleep until an allocation slowpath wakes it up again. For higher-order allocations, waking up kcompactd is done only before the full sleep. This turns out to be an issue in case another high-order allocation fails during the initial sleep. It will wake kswapd up, however kswapd considers the zone balanced from the order-0 perspective, and will just quickly try to sleep again. So if there's a longer stream of high-order allocations hitting the slowpath and waking up kswapd, it might never actually wake up kcompactd, which may be considered a regression from kswapd-based compaction. In the worst case, it might be that a single allocation that cannot direct reclaim/compact itself is waking kswapd in the retry loop and preventing kcompactd from being woken up and unblocking it. This patch makes sure kcompactd is woken up in such situations by simply moving the wakeup before the short initial sleep. More efficient solution would be to wake kcompactd immediately instead of kswapd if the node is already order-0 balanced, but in that case we should also move reset_isolation_suitable() call to kcompactd so it's not adding to the allocator's latency. Since it's late in the 4.6 cycle, let's go with the simpler change for now. Fixes: accf62422b3a ("mm, kswapd: replace kswapd compaction with waking up kcompactd") Signed-off-by: Vlastimil Babka Cc: Andrea Arcangeli Cc: "Kirill A. Shutemov" Cc: Rik van Riel Cc: Joonsoo Kim Cc: Mel Gorman Cc: David Rientjes Cc: Michal Hocko Cc: Johannes Weiner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index c638b28310fc..142cb61f4822 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -3318,6 +3318,20 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, /* Try to sleep for a short interval */ if (prepare_kswapd_sleep(pgdat, order, remaining, balanced_classzone_idx)) { + /* + * Compaction records what page blocks it recently failed to + * isolate pages from and skips them in the future scanning. + * When kswapd is going to sleep, it is reasonable to assume + * that pages and compaction may succeed so reset the cache. + */ + reset_isolation_suitable(pgdat); + + /* + * We have freed the memory, now we should compact it to make + * allocation of the requested order possible. + */ + wakeup_kcompactd(pgdat, order, classzone_idx); + remaining = schedule_timeout(HZ/10); finish_wait(&pgdat->kswapd_wait, &wait); prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); @@ -3341,20 +3355,6 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, */ set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold); - /* - * Compaction records what page blocks it recently failed to - * isolate pages from and skips them in the future scanning. - * When kswapd is going to sleep, it is reasonable to assume - * that pages and compaction may succeed so reset the cache. - */ - reset_isolation_suitable(pgdat); - - /* - * We have freed the memory, now we should compact it to make - * allocation of the requested order possible. - */ - wakeup_kcompactd(pgdat, order, classzone_idx); - if (!kthread_should_stop()) schedule(); -- cgit v1.2.3 From bdab42dfc974d15303afbf259f340f374a453974 Mon Sep 17 00:00:00 2001 From: James Morse Date: Thu, 28 Apr 2016 16:18:52 -0700 Subject: kcov: don't trace the code coverage code Kcov causes the compiler to add a call to __sanitizer_cov_trace_pc() in every basic block. Ftrace patches in a call to _mcount() to each function it has annotated. Letting these mechanisms annotate each other is a bad thing. Break the loop by adding 'notrace' to __sanitizer_cov_trace_pc() so that ftrace won't try to patch this code. This patch lets arm64 with KCOV and STACK_TRACER boot. Signed-off-by: James Morse Acked-by: Dmitry Vyukov Cc: Alexander Potapenko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/kcov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index 3efbee0834a8..78bed7125515 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -43,7 +43,7 @@ struct kcov { * Entry point from instrumented code. * This is called once per basic-block/edge. */ -void __sanitizer_cov_trace_pc(void) +void notrace __sanitizer_cov_trace_pc(void) { struct task_struct *t; enum kcov_mode mode; -- cgit v1.2.3 From 36f05ae8bce904b4c8105363e6227a79d343bda6 Mon Sep 17 00:00:00 2001 From: Andrey Ryabinin Date: Thu, 28 Apr 2016 16:18:55 -0700 Subject: kcov: don't profile branches in kcov Profiling 'if' statements in __sanitizer_cov_trace_pc() leads to unbound recursion and crash: __sanitizer_cov_trace_pc() -> ftrace_likely_update -> __sanitizer_cov_trace_pc() ... Define DISABLE_BRANCH_PROFILING to disable this tracer. Signed-off-by: Andrey Ryabinin Cc: Dmitry Vyukov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/kcov.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/kcov.c b/kernel/kcov.c index 78bed7125515..a02f2dddd1d7 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -1,5 +1,6 @@ #define pr_fmt(fmt) "kcov: " fmt +#define DISABLE_BRANCH_PROFILING #include #include #include -- cgit v1.2.3 From a320817c68e3fa1fc3ddaa709a1ad45cf533693b Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Thu, 28 Apr 2016 16:18:58 -0700 Subject: Ananth has moved The current ID is going away soon... update email address Signed-off-by: Ananth N Mavinakayanahalli Cc: Masami Hiramatsu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 849133608da7..7f72d54f065d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6400,7 +6400,7 @@ F: mm/kmemleak.c F: mm/kmemleak-test.c KPROBES -M: Ananth N Mavinakayanahalli +M: Ananth N Mavinakayanahalli M: Anil S Keshavamurthy M: "David S. Miller" M: Masami Hiramatsu -- cgit v1.2.3 From b73413647ee36406561618f68d0661d49dc47489 Mon Sep 17 00:00:00 2001 From: xuejiufei Date: Thu, 28 Apr 2016 16:19:01 -0700 Subject: ocfs2/dlm: return zero if deref_done message is successfully handled dlm_deref_lockres_done_handler() should return zero if the message is successfully handled. Fixes: 60d663cb5273 ("ocfs2/dlm: add DEREF_DONE message"). Signed-off-by: xuejiufei Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/dlm/dlmmaster.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 9aed6e202201..13719d3f35f8 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2455,6 +2455,8 @@ int dlm_deref_lockres_done_handler(struct o2net_msg *msg, u32 len, void *data, spin_unlock(&dlm->spinlock); + ret = 0; + done: dlm_put(dlm); return ret; -- cgit v1.2.3 From c2e7e00b715d3c65f301bec8559d6af4ef8098ab Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 28 Apr 2016 16:19:03 -0700 Subject: mm/memory-failure: fix race with compound page split/merge get_hwpoison_page() must recheck relation between head and tail pages. n-horiguchi said: without this recheck, the race causes kernel to pin an irrelevant page, and finally makes kernel crash for refcount mismatch. Signed-off-by: Konstantin Khlebnikov Acked-by: Naoya Horiguchi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory-failure.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 78f5f2641b91..ca5acee53b7a 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -888,7 +888,15 @@ int get_hwpoison_page(struct page *page) } } - return get_page_unless_zero(head); + if (get_page_unless_zero(head)) { + if (head == compound_head(page)) + return 1; + + pr_info("MCE: %#lx cannot catch tail\n", page_to_pfn(page)); + put_page(head); + } + + return 0; } EXPORT_SYMBOL_GPL(get_hwpoison_page); -- cgit v1.2.3 From 99f23c2cded85a377325aa9fd374ffa3d55d1088 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Thu, 28 Apr 2016 16:19:06 -0700 Subject: rapidio: fix potential NULL pointer dereference The change fixes improper check for a returned error value by class_create() function, which on error returns ERR_PTR() value, thus the original check always results in a dead code on error path. Signed-off-by: Vladimir Zapolskiy Signed-off-by: Alexandre Bounine Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/devices/rio_mport_cdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 5d4d91846357..96168b819044 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -2669,9 +2669,9 @@ static int __init mport_init(void) /* Create device class needed by udev */ dev_class = class_create(THIS_MODULE, DRV_NAME); - if (!dev_class) { + if (IS_ERR(dev_class)) { rmcd_error("Unable to create " DRV_NAME " class"); - return -EINVAL; + return PTR_ERR(dev_class); } ret = alloc_chrdev_region(&dev_number, 0, RIO_MAX_MPORTS, DRV_NAME); -- cgit v1.2.3 From 33334e25769c6ad69b983379578f42581d99a2f9 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Thu, 28 Apr 2016 16:19:09 -0700 Subject: lib/stackdepot.c: allow the stack trace hash to be zero Do not bail out from depot_save_stack() if the stack trace has zero hash. Initially depot_save_stack() silently dropped stack traces with zero hashes, however there's actually no point in reserving this zero value. Reported-by: Joonsoo Kim Signed-off-by: Alexander Potapenko Acked-by: Andrey Ryabinin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/stackdepot.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/stackdepot.c b/lib/stackdepot.c index 654c9d87e83a..9e0b0315a724 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -210,10 +210,6 @@ depot_stack_handle_t depot_save_stack(struct stack_trace *trace, goto fast_exit; hash = hash_stack(trace->entries, trace->nr_entries); - /* Bad luck, we won't store this stack. */ - if (hash == 0) - goto exit; - bucket = &stack_table[hash & STACK_HASH_MASK]; /* -- cgit v1.2.3 From 7c88a292dfcd6979e839493ef18d04770eb3bad0 Mon Sep 17 00:00:00 2001 From: Xishi Qiu Date: Thu, 28 Apr 2016 16:19:11 -0700 Subject: Documentation/sysctl/vm.txt: update numa_zonelist_order description Commit 3193913ce62c ("mm: page_alloc: default node-ordering on 64-bit NUMA, zone-ordering on 32-bit") changes the default value of numa_zonelist_order. Update the document. Signed-off-by: Xishi Qiu Cc: Mel Gorman Cc: Johannes Weiner Cc: Rik van Riel Cc: David Rientjes Cc: Kamezawa Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/sysctl/vm.txt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index cb0368459da3..34a5fece3121 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -581,15 +581,16 @@ Specify "[Nn]ode" for node order "Zone Order" orders the zonelists by zone type, then by node within each zone. Specify "[Zz]one" for zone order. -Specify "[Dd]efault" to request automatic configuration. Autoconfiguration -will select "node" order in following case. -(1) if the DMA zone does not exist or -(2) if the DMA zone comprises greater than 50% of the available memory or -(3) if any node's DMA zone comprises greater than 70% of its local memory and - the amount of local memory is big enough. - -Otherwise, "zone" order will be selected. Default order is recommended unless -this is causing problems for your system/application. +Specify "[Dd]efault" to request automatic configuration. + +On 32-bit, the Normal zone needs to be preserved for allocations accessible +by the kernel, so "zone" order will be selected. + +On 64-bit, devices that require DMA32/DMA are relatively rare, so "node" +order will be selected. + +Default order is recommended unless this is causing problems for your +system/application. ============================================================== -- cgit v1.2.3 From 2871734e85e920503d49b3a8bc0afbe0773b6036 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Sat, 12 Mar 2016 11:12:59 +0100 Subject: batman-adv: fix DAT candidate selection (must use vid) Now that DAT is VLAN aware, it must use the VID when computing the DHT address of the candidate nodes where an entry is going to be stored/retrieved. Fixes: be1db4f6615b ("batman-adv: make the Distributed ARP Table vlan aware") Signed-off-by: Antonio Quartulli [sven@narfation.org: fix conflicts with current version] Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner --- net/batman-adv/distributed-arp-table.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index e96d7c745b4a..3e6b2624f980 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -568,6 +568,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, * be sent to * @bat_priv: the bat priv with all the soft interface information * @ip_dst: ipv4 to look up in the DHT + * @vid: VLAN identifier * * An originator O is selected if and only if its DHT_ID value is one of three * closest values (from the LEFT, with wrap around if needed) then the hash @@ -576,7 +577,8 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv, * Return: the candidate array of size BATADV_DAT_CANDIDATE_NUM. */ static struct batadv_dat_candidate * -batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) +batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst, + unsigned short vid) { int select; batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key; @@ -592,7 +594,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) return NULL; dat.ip = ip_dst; - dat.vid = 0; + dat.vid = vid; ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat, BATADV_DAT_ADDR_MAX); @@ -612,6 +614,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) * @bat_priv: the bat priv with all the soft interface information * @skb: payload to send * @ip: the DHT key + * @vid: VLAN identifier * @packet_subtype: unicast4addr packet subtype to use * * This function copies the skb with pskb_copy() and is sent as unicast packet @@ -622,7 +625,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) */ static bool batadv_dat_send_data(struct batadv_priv *bat_priv, struct sk_buff *skb, __be32 ip, - int packet_subtype) + unsigned short vid, int packet_subtype) { int i; bool ret = false; @@ -631,7 +634,7 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv, struct sk_buff *tmp_skb; struct batadv_dat_candidate *cand; - cand = batadv_dat_select_candidates(bat_priv, ip); + cand = batadv_dat_select_candidates(bat_priv, ip, vid); if (!cand) goto out; @@ -1022,7 +1025,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, ret = true; } else { /* Send the request to the DHT */ - ret = batadv_dat_send_data(bat_priv, skb, ip_dst, + ret = batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_GET); } out: @@ -1150,8 +1153,8 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv, /* Send the ARP reply to the candidates for both the IP addresses that * the node obtained from the ARP reply */ - batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT); - batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT); + batadv_dat_send_data(bat_priv, skb, ip_src, vid, BATADV_P_DAT_DHT_PUT); + batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_PUT); } /** -- cgit v1.2.3 From b6cf5d499fddbfcffe751e81fb9f1a07d6348026 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 14 Apr 2016 09:37:05 +0800 Subject: batman-adv: B.A.T.M.A.N V - make sure iface is reactivated upon NETDEV_UP event At the moment there is no explicit reactivation of an hard-interface upon NETDEV_UP event. In case of B.A.T.M.A.N. IV the interface is reactivated as soon as the next OGM is scheduled for sending, but this mechanism does not work with B.A.T.M.A.N. V. The latter does not rely on the same scheduling mechanism as its predecessor and for this reason the hard-interface remains deactivated forever after being brought down once. This patch fixes the reactivation mechanism by adding a new routing API which explicitly allows each algorithm to perform any needed operation upon interface re-activation. Such API is optional and is implemented by B.A.T.M.A.N. V only and it just takes care of setting the iface status to ACTIVE Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/bat_v.c | 12 ++++++++++++ net/batman-adv/hard-interface.c | 3 +++ net/batman-adv/types.h | 3 +++ 3 files changed, 18 insertions(+) diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 3315b9a598af..4026f198a734 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -32,10 +32,21 @@ #include "bat_v_elp.h" #include "bat_v_ogm.h" +#include "hard-interface.h" #include "hash.h" #include "originator.h" #include "packet.h" +static void batadv_v_iface_activate(struct batadv_hard_iface *hard_iface) +{ + /* B.A.T.M.A.N. V does not use any queuing mechanism, therefore it can + * set the interface as ACTIVE right away, without any risk of race + * condition + */ + if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED) + hard_iface->if_status = BATADV_IF_ACTIVE; +} + static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) { int ret; @@ -274,6 +285,7 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, static struct batadv_algo_ops batadv_batman_v __read_mostly = { .name = "BATMAN_V", + .bat_iface_activate = batadv_v_iface_activate, .bat_iface_enable = batadv_v_iface_enable, .bat_iface_disable = batadv_v_iface_disable, .bat_iface_update_mac = batadv_v_iface_update_mac, diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index c61d5b0b24d2..0a7deaf2670a 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -407,6 +407,9 @@ batadv_hardif_activate_interface(struct batadv_hard_iface *hard_iface) batadv_update_min_mtu(hard_iface->soft_iface); + if (bat_priv->bat_algo_ops->bat_iface_activate) + bat_priv->bat_algo_ops->bat_iface_activate(hard_iface); + out: if (primary_if) batadv_hardif_put(primary_if); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 9abfb3e73c34..443e9b84e07d 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1250,6 +1250,8 @@ struct batadv_forw_packet { * struct batadv_algo_ops - mesh algorithm callbacks * @list: list node for the batadv_algo_list * @name: name of the algorithm + * @bat_iface_activate: start routing mechanisms when hard-interface is brought + * up * @bat_iface_enable: init routing info when hard-interface is enabled * @bat_iface_disable: de-init routing info when hard-interface is disabled * @bat_iface_update_mac: (re-)init mac addresses of the protocol information @@ -1277,6 +1279,7 @@ struct batadv_forw_packet { struct batadv_algo_ops { struct hlist_node list; char *name; + void (*bat_iface_activate)(struct batadv_hard_iface *hard_iface); int (*bat_iface_enable)(struct batadv_hard_iface *hard_iface); void (*bat_iface_disable)(struct batadv_hard_iface *hard_iface); void (*bat_iface_update_mac)(struct batadv_hard_iface *hard_iface); -- cgit v1.2.3 From a33d970d0b54b09746d5540af8271fad4eb10229 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Fri, 11 Mar 2016 16:44:05 +0100 Subject: batman-adv: Fix reference counting of vlan object for tt_local_entry The batadv_tt_local_entry was specific to a batadv_softif_vlan and held an implicit reference to it. But this reference was never stored in form of a pointer in the tt_local_entry itself. Instead batadv_tt_local_remove, batadv_tt_local_table_free and batadv_tt_local_purge_pending_clients depend on a consistent state of bat_priv->softif_vlan_list and that batadv_softif_vlan_get always returns the batadv_softif_vlan object which it has a reference for. But batadv_softif_vlan_get cannot guarantee that because it is working only with rcu_read_lock on this list. It can therefore happen that an vid is in this list twice or that batadv_softif_vlan_get cannot find the batadv_softif_vlan for an vid due to some other list operations taking place at the same time. Instead add a batadv_softif_vlan pointer directly in batadv_tt_local_entry which will be used for the reference counter decremented on release of batadv_tt_local_entry. Fixes: 35df3b298fc8 ("batman-adv: fix TT VLAN inconsistency on VLAN re-add") Signed-off-by: Sven Eckelmann Acked-by: Antonio Quartulli Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/translation-table.c | 42 ++++---------------------------------- net/batman-adv/types.h | 2 ++ 2 files changed, 6 insertions(+), 38 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 0b43e86328a5..9b4551a86535 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -215,6 +215,8 @@ static void batadv_tt_local_entry_release(struct kref *ref) tt_local_entry = container_of(ref, struct batadv_tt_local_entry, common.refcount); + batadv_softif_vlan_put(tt_local_entry->vlan); + kfree_rcu(tt_local_entry, common.rcu); } @@ -673,6 +675,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, kref_get(&tt_local->common.refcount); tt_local->last_seen = jiffies; tt_local->common.added_at = tt_local->last_seen; + tt_local->vlan = vlan; /* the batman interface mac and multicast addresses should never be * purged @@ -991,7 +994,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) struct batadv_tt_common_entry *tt_common_entry; struct batadv_tt_local_entry *tt_local; struct batadv_hard_iface *primary_if; - struct batadv_softif_vlan *vlan; struct hlist_head *head; unsigned short vid; u32 i; @@ -1027,14 +1029,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) last_seen_msecs = last_seen_msecs % 1000; no_purge = tt_common_entry->flags & np_flag; - - vlan = batadv_softif_vlan_get(bat_priv, vid); - if (!vlan) { - seq_printf(seq, "Cannot retrieve VLAN %d\n", - BATADV_PRINT_VID(vid)); - continue; - } - seq_printf(seq, " * %pM %4i [%c%c%c%c%c%c] %3u.%03u (%#.8x)\n", tt_common_entry->addr, @@ -1052,9 +1046,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) BATADV_TT_CLIENT_ISOLA) ? 'I' : '.'), no_purge ? 0 : last_seen_secs, no_purge ? 0 : last_seen_msecs, - vlan->tt.crc); - - batadv_softif_vlan_put(vlan); + tt_local->vlan->tt.crc); } rcu_read_unlock(); } @@ -1099,7 +1091,6 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, { struct batadv_tt_local_entry *tt_local_entry; u16 flags, curr_flags = BATADV_NO_FLAGS; - struct batadv_softif_vlan *vlan; void *tt_entry_exists; tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid); @@ -1139,14 +1130,6 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr, /* extra call to free the local tt entry */ batadv_tt_local_entry_put(tt_local_entry); - /* decrease the reference held for this vlan */ - vlan = batadv_softif_vlan_get(bat_priv, vid); - if (!vlan) - goto out; - - batadv_softif_vlan_put(vlan); - batadv_softif_vlan_put(vlan); - out: if (tt_local_entry) batadv_tt_local_entry_put(tt_local_entry); @@ -1219,7 +1202,6 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) spinlock_t *list_lock; /* protects write access to the hash lists */ struct batadv_tt_common_entry *tt_common_entry; struct batadv_tt_local_entry *tt_local; - struct batadv_softif_vlan *vlan; struct hlist_node *node_tmp; struct hlist_head *head; u32 i; @@ -1241,14 +1223,6 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) struct batadv_tt_local_entry, common); - /* decrease the reference held for this vlan */ - vlan = batadv_softif_vlan_get(bat_priv, - tt_common_entry->vid); - if (vlan) { - batadv_softif_vlan_put(vlan); - batadv_softif_vlan_put(vlan); - } - batadv_tt_local_entry_put(tt_local); } spin_unlock_bh(list_lock); @@ -3309,7 +3283,6 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) struct batadv_hashtable *hash = bat_priv->tt.local_hash; struct batadv_tt_common_entry *tt_common; struct batadv_tt_local_entry *tt_local; - struct batadv_softif_vlan *vlan; struct hlist_node *node_tmp; struct hlist_head *head; spinlock_t *list_lock; /* protects write access to the hash lists */ @@ -3339,13 +3312,6 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) struct batadv_tt_local_entry, common); - /* decrease the reference held for this vlan */ - vlan = batadv_softif_vlan_get(bat_priv, tt_common->vid); - if (vlan) { - batadv_softif_vlan_put(vlan); - batadv_softif_vlan_put(vlan); - } - batadv_tt_local_entry_put(tt_local); } spin_unlock_bh(list_lock); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 443e9b84e07d..65afd090ab3e 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1073,10 +1073,12 @@ struct batadv_tt_common_entry { * struct batadv_tt_local_entry - translation table local entry data * @common: general translation table data * @last_seen: timestamp used for purging stale tt local entries + * @vlan: soft-interface vlan of the entry */ struct batadv_tt_local_entry { struct batadv_tt_common_entry common; unsigned long last_seen; + struct batadv_softif_vlan *vlan; }; /** -- cgit v1.2.3 From abe59c65225ccd63a5964e2f2a73dd2995b948e7 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Fri, 11 Mar 2016 16:44:06 +0100 Subject: batman-adv: Fix reference counting of hardif_neigh_node object for neigh_node The batadv_neigh_node was specific to a batadv_hardif_neigh_node and held an implicit reference to it. But this reference was never stored in form of a pointer in the batadv_neigh_node itself. Instead batadv_neigh_node_release depends on a consistent state of hard_iface->neigh_list and that batadv_hardif_neigh_get always returns the batadv_hardif_neigh_node object which it has a reference for. But batadv_hardif_neigh_get cannot guarantee that because it is working only with rcu_read_lock on this list. It can therefore happen that a neigh_addr is in this list twice or that batadv_hardif_neigh_get cannot find the batadv_hardif_neigh_node for an neigh_addr due to some other list operations taking place at the same time. Instead add a batadv_hardif_neigh_node pointer directly in batadv_neigh_node which will be used for the reference counter decremented on release of batadv_neigh_node. Fixes: cef63419f7db ("batman-adv: add list of unique single hop neighbors per hard-interface") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Antonio Quartulli --- net/batman-adv/originator.c | 16 +++++----------- net/batman-adv/types.h | 2 ++ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index d52f67a0c057..c355a824713c 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -250,7 +250,6 @@ static void batadv_neigh_node_release(struct kref *ref) { struct hlist_node *node_tmp; struct batadv_neigh_node *neigh_node; - struct batadv_hardif_neigh_node *hardif_neigh; struct batadv_neigh_ifinfo *neigh_ifinfo; struct batadv_algo_ops *bao; @@ -262,13 +261,7 @@ static void batadv_neigh_node_release(struct kref *ref) batadv_neigh_ifinfo_put(neigh_ifinfo); } - hardif_neigh = batadv_hardif_neigh_get(neigh_node->if_incoming, - neigh_node->addr); - if (hardif_neigh) { - /* batadv_hardif_neigh_get() increases refcount too */ - batadv_hardif_neigh_put(hardif_neigh); - batadv_hardif_neigh_put(hardif_neigh); - } + batadv_hardif_neigh_put(neigh_node->hardif_neigh); if (bao->bat_neigh_free) bao->bat_neigh_free(neigh_node); @@ -665,6 +658,10 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, neigh_node->orig_node = orig_node; neigh_node->last_seen = jiffies; + /* increment unique neighbor refcount */ + kref_get(&hardif_neigh->refcount); + neigh_node->hardif_neigh = hardif_neigh; + /* extra reference for return */ kref_init(&neigh_node->refcount); kref_get(&neigh_node->refcount); @@ -673,9 +670,6 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); spin_unlock_bh(&orig_node->neigh_list_lock); - /* increment unique neighbor refcount */ - kref_get(&hardif_neigh->refcount); - batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv, "Creating new neighbor %pM for orig_node %pM on interface %s\n", neigh_addr, orig_node->orig, hard_iface->net_dev->name); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 65afd090ab3e..1e47fbe8bb7b 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -433,6 +433,7 @@ struct batadv_hardif_neigh_node { * @ifinfo_lock: lock protecting private ifinfo members and list * @if_incoming: pointer to incoming hard-interface * @last_seen: when last packet via this neighbor was received + * @hardif_neigh: hardif_neigh of this neighbor * @refcount: number of contexts the object is used * @rcu: struct used for freeing in an RCU-safe manner */ @@ -444,6 +445,7 @@ struct batadv_neigh_node { spinlock_t ifinfo_lock; /* protects ifinfo_list and its members */ struct batadv_hard_iface *if_incoming; unsigned long last_seen; + struct batadv_hardif_neigh_node *hardif_neigh; struct kref refcount; struct rcu_head rcu; }; -- cgit v1.2.3 From c4fc1956fa31003bfbe4f597e359d751568e2954 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Fri, 29 Apr 2016 15:42:25 +0200 Subject: EDAC: i7core, sb_edac: Don't return NOTIFY_BAD from mce_decoder callback Both of these drivers can return NOTIFY_BAD, but this terminates processing other callbacks that were registered later on the chain. Since the driver did nothing to log the error it seems wrong to prevent other interested parties from seeing it. E.g. neither of them had even bothered to check the type of the error to see if it was a memory error before the return NOTIFY_BAD. Signed-off-by: Tony Luck Acked-by: Aristeu Rozanski Acked-by: Mauro Carvalho Chehab Cc: linux-edac Cc: Link: http://lkml.kernel.org/r/72937355dd92318d2630979666063f8a2853495b.1461864507.git.tony.luck@intel.com Signed-off-by: Borislav Petkov --- drivers/edac/i7core_edac.c | 2 +- drivers/edac/sb_edac.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 01087a38da22..792bdae2b91d 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1866,7 +1866,7 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val, i7_dev = get_i7core_dev(mce->socketid); if (!i7_dev) - return NOTIFY_BAD; + return NOTIFY_DONE; mci = i7_dev->mci; pvt = mci->pvt_info; diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 468447aff8eb..8bf745d2da7e 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -3168,7 +3168,7 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val, mci = get_mci_for_node_id(mce->socketid); if (!mci) - return NOTIFY_BAD; + return NOTIFY_DONE; pvt = mci->pvt_info; /* -- cgit v1.2.3 From f27337e16f2d0e52a8d05ea599ed13cd266ac291 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Thu, 28 Apr 2016 11:04:51 +0200 Subject: ip_tunnel: fix preempt warning in ip tunnel creation/updating After the commit e09acddf873b ("ip_tunnel: replace dst_cache with generic implementation"), a preemption debug warning is triggered on ip4 tunnels updating; the dst cache helper needs to be invoked in unpreemptible context. We don't need to load the cache on tunnel update, so this commit fixes the warning replacing the load with a dst cache reset, which is preempt safe. Fixes: e09acddf873b ("ip_tunnel: replace dst_cache with generic implementation") Reported-by: Eric Dumazet Signed-off-by: Paolo Abeni Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/ip_tunnel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 6aad0192443d..a69ed94bda1b 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -326,12 +326,12 @@ static int ip_tunnel_bind_dev(struct net_device *dev) if (!IS_ERR(rt)) { tdev = rt->dst.dev; - dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst, - fl4.saddr); ip_rt_put(rt); } if (dev->type != ARPHRD_ETHER) dev->flags |= IFF_POINTOPOINT; + + dst_cache_reset(&tunnel->dst_cache); } if (!tdev && tunnel->parms.link) -- cgit v1.2.3 From 04b9665b54f7cdc184ea03b0687aaa6d9711646e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 15 Mar 2016 22:34:45 +0100 Subject: ARM: davinci: only use NVMEM when available The davinci platform contains code that calls into the nvmem subsystem, but that might be a loadable module, causing a link error: arch/arm/mach-davinci/built-in.o: In function `davinci_get_mac_addr': :(.text+0x1088): undefined reference to `nvmem_device_read' arch/arm/mach-davinci/built-in.o: In function `read_factory_config': :(.text+0x214c): undefined reference to `nvmem_device_read' Also, when NVMEM is completely disabled, the functions fail with nonobvious error messages. This ensures we only call the API functions when the code is actually reachable from the board file, and otherwise prints a unique log message. Signed-off-by: Arnd Bergmann Fixes: bec3c11bad0e ("misc: at24: replace memory_accessor with nvmem_device_read") Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-mityomapl138.c | 5 +++++ arch/arm/mach-davinci/common.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index d97c588550ad..bc4e63fa9808 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -121,6 +121,11 @@ static void read_factory_config(struct nvmem_device *nvmem, void *context) const char *partnum = NULL; struct davinci_soc_info *soc_info = &davinci_soc_info; + if (!IS_BUILTIN(CONFIG_NVMEM)) { + pr_warn("Factory Config not available without CONFIG_NVMEM\n"); + goto bad_config; + } + ret = nvmem_device_read(nvmem, 0, sizeof(factory_config), &factory_config); if (ret != sizeof(struct factory_config)) { diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index f55ef2ef2f92..742133b7266a 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -33,6 +33,11 @@ void davinci_get_mac_addr(struct nvmem_device *nvmem, void *context) char *mac_addr = davinci_soc_info.emac_pdata->mac_addr; off_t offset = (off_t)context; + if (!IS_BUILTIN(CONFIG_NVMEM)) { + pr_warn("Cannot read MAC addr from EEPROM without CONFIG_NVMEM\n"); + return; + } + /* Read MAC addr from EEPROM */ if (nvmem_device_read(nvmem, offset, ETH_ALEN, mac_addr) == ETH_ALEN) pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr); -- cgit v1.2.3 From b8a0b8e94648179b92191e5cf4fd3c4379b31cc4 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 29 Apr 2016 14:18:03 -0700 Subject: raid5: delete unnecessary warnning If device has R5_LOCKED set, it's legit device has R5_SkipCopy set and page != orig_page. After R5_LOCKED is clear, handle_stripe_clean_event will clear the SkipCopy flag and set page to orig_page. So the warning is unnecessary. Reported-by: Joey Liao Signed-off-by: Shaohua Li --- drivers/md/raid5.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 8ab8b65e1741..e48c262ce032 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3502,8 +3502,6 @@ returnbi: dev = &sh->dev[i]; } else if (test_bit(R5_Discard, &dev->flags)) discard_pending = 1; - WARN_ON(test_bit(R5_SkipCopy, &dev->flags)); - WARN_ON(dev->page != dev->orig_page); } r5l_stripe_write_finished(sh); -- cgit v1.2.3 From 7df89e92a56a3d2c8f84aa76c61471e4a7bc24f9 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 25 Apr 2016 16:01:19 +0300 Subject: gpiolib-acpi: Duplicate con_id string when adding it to the crs lookup list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling gpiod_get() from a module and then unloading the module leads to an oops due to acpi_can_fallback_to_crs() storing the pointer to the passed 'con_id' string onto acpi_crs_lookup_list. The next guy to come along will then try to access the string but the memory may now be gone with the module. Make a copy of the passed string instead, and store the copy on the list. BUG: unable to handle kernel paging request at ffffffffa03e7855 IP: [] strcmp+0x12/0x30 PGD 2a07067 PUD 2a08063 PMD 74720067 PTE 0 Oops: 0000 [#1] PREEMPT SMP Modules linked in: i915(+) drm_kms_helper drm intel_gtt snd_hda_codec snd_hda_core i2c_algo_bit syscopya rea sysfillrect sysimgblt fb_sys_fops agpgart snd_soc_sst_bytcr_rt5640 coretemp hwmon intel_rapl intel_soc_dts_thermal punit_atom_debug snd_soc_rt5640 snd_soc_rl6231 serio snd_intel_sst_acpi snd_intel_sst_core video snd_soc_sst_mfld_platf orm snd_soc_sst_match backlight int3402_thermal processor_thermal_device int3403_thermal int3400_thermal acpi_thermal_r el snd_soc_core intel_soc_dts_iosf int340x_thermal_zone snd_compress i2c_hid hid snd_pcm snd_timer snd soundcore evdev sch_fq_codel efivarfs ipv6 autofs4 [last unloaded: drm] CPU: 2 PID: 3064 Comm: modprobe Tainted: G U W 4.6.0-rc3-ffrd-ipvr+ #302 Hardware name: Intel Corp. VALLEYVIEW C0 PLATFORM/BYT-T FFD8, BIOS BLAKFF81.X64.0088.R10.1403240443 FFD8 _X64_R_2014_13_1_00 03/24/2014 task: ffff8800701cd200 ti: ffff880070034000 task.ti: ffff880070034000 RIP: 0010:[] [] strcmp+0x12/0x30 RSP: 0000:ffff880070037748 EFLAGS: 00010286 RAX: 0000000080000000 RBX: ffff88007a342800 RCX: 0000000000000006 RDX: 0000000000000006 RSI: ffffffffa054f856 RDI: ffffffffa03e7856 RBP: ffff880070037748 R08: 0000000000000000 R09: 0000000000000001 R10: 0000000000000000 R11: 0000000000000000 R12: ffffffffa054f855 R13: ffff88007281cae0 R14: 0000000000000010 R15: ffffffffffffffea FS: 00007faa51447700(0000) GS:ffff880079300000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffa03e7855 CR3: 0000000041eba000 CR4: 00000000001006e0 Stack: ffff880070037770 ffffffff8136ad28 ffffffffa054f855 0000000000000000 ffff88007a0a2098 ffff8800700377e8 ffffffff8136852e ffff88007a342800 00000007700377a0 ffff8800700377a0 ffffffff81412442 70672d6c656e6170 Call Trace: [] acpi_can_fallback_to_crs+0x88/0x100 [] gpiod_get_index+0x25e/0x310 [] ? mipi_dsi_attach+0x22/0x30 [] gpiod_get+0x12/0x20 [] intel_dsi_init+0x421/0x480 [i915] [] intel_modeset_init+0x853/0x16b0 [i915] [] ? intel_setup_gmbus+0x214/0x260 [i915] [] i915_driver_load+0xdc8/0x19b0 [i915] [] ? _raw_spin_unlock_irqrestore+0x43/0x70 [] drm_dev_register+0xab/0xc0 [drm] [] drm_get_pci_dev+0x93/0x1f0 [drm] [] ? _raw_spin_unlock_irqrestore+0x43/0x70 [] i915_pci_probe+0x34/0x50 [i915] [] pci_device_probe+0x91/0x100 [] driver_probe_device+0x20a/0x2d0 [] __driver_attach+0x9e/0xb0 [] ? driver_probe_device+0x2d0/0x2d0 [] bus_for_each_dev+0x69/0xa0 [] driver_attach+0x1e/0x20 [] bus_add_driver+0x1c0/0x240 [] driver_register+0x60/0xe0 [] __pci_register_driver+0x60/0x70 [] drm_pci_init+0xe4/0x110 [drm] [] ? trace_hardirqs_on+0xe/0x10 [] ? 0xffffffffa02f1000 [] i915_init+0x94/0x9b [i915] [] do_one_initcall+0x8b/0x1c0 [] ? rcu_read_lock_sched_held+0x86/0x90 [] ? kmem_cache_alloc_trace+0x1f6/0x270 [] do_init_module+0x60/0x1dc [] load_module+0x1d0d/0x2390 [] ? __symbol_put+0x70/0x70 [] ? kernel_read_file+0x92/0x120 [] SYSC_finit_module+0xa4/0xb0 [] SyS_finit_module+0xe/0x10 [] do_syscall_64+0x63/0x350 [] entry_SYSCALL64_slow_path+0x25/0x25 Code: f7 48 8d 76 01 48 8d 52 01 0f b6 4e ff 84 c9 88 4a ff 75 ed 5d c3 0f 1f 00 55 48 89 e5 eb 04 84 c0 74 18 48 8d 7f 01 48 8d 76 01 <0f> b6 47 ff 3a 46 ff 74 eb 19 c0 83 c8 01 5d c3 31 c0 5d c3 66 RIP [] strcmp+0x12/0x30 RSP CR2: ffffffffa03e7855 v2: Make the copied con_id const Cc: Dmitry Torokhov Cc: Mika Westerberg Cc: Alexandre Courbot Cc: stable@vger.kernel.org Fixes: 10cf4899f8af ("gpiolib: tighten up ACPI legacy gpio lookups") Signed-off-by: Ville Syrjälä Acked-by: Mika Westerberg Reviewed-by: Dmitry Torokhov Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 682070d20f00..2dc52585e3f2 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -977,7 +977,7 @@ bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id) lookup = kmalloc(sizeof(*lookup), GFP_KERNEL); if (lookup) { lookup->adev = adev; - lookup->con_id = con_id; + lookup->con_id = kstrdup(con_id, GFP_KERNEL); list_add_tail(&lookup->node, &acpi_crs_lookup_list); } } -- cgit v1.2.3 From 658922e57b847bb7112aa67f6441b6bbc6554412 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 30 Apr 2016 13:07:06 -0700 Subject: libnvdimm, pfn: fix memmap reservation sizing When configuring a pfn-device instance to allocate the memmap array it needs to account for the fact that vmemmap_populate_hugepages() allocates struct page blocks in HPAGE_SIZE chunks. We need to align the reserved area size to 2MB otherwise arch_add_memory() runs out of memory while establishing the memmap: WARNING: CPU: 0 PID: 496 at arch/x86/mm/init_64.c:704 arch_add_memory+0xe7/0xf0 [..] Call Trace: [] dump_stack+0x85/0xc2 [] __warn+0xcb/0xf0 [] warn_slowpath_null+0x1d/0x20 [] arch_add_memory+0xe7/0xf0 [] devm_memremap_pages+0x287/0x450 [] ? devm_memremap_pages+0x1ea/0x450 [] __wrap_devm_memremap_pages+0x58/0x70 [nfit_test_iomap] [] pmem_attach_disk+0x318/0x420 [nd_pmem] [] nd_pmem_probe+0x6f/0x90 [nd_pmem] [] nvdimm_bus_probe+0x69/0x110 [libnvdimm] [..] ndbus0: nd_pmem.probe(pfn3.0) = -12 nd_pmem: probe of pfn3.0 failed with error -12 libndctl: ndctl_pfn_enable: pfn3.0: failed to enable Reported-by: Namratha Kothapalli Cc: Signed-off-by: Dan Williams --- drivers/nvdimm/pmem.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index f798899338ed..5101f3ab4f29 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -397,10 +397,17 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) */ start += start_pad; npfns = (pmem->size - start_pad - end_trunc - SZ_8K) / SZ_4K; - if (nd_pfn->mode == PFN_MODE_PMEM) - offset = ALIGN(start + SZ_8K + 64 * npfns, nd_pfn->align) + if (nd_pfn->mode == PFN_MODE_PMEM) { + unsigned long memmap_size; + + /* + * vmemmap_populate_hugepages() allocates the memmap array in + * HPAGE_SIZE chunks. + */ + memmap_size = ALIGN(64 * npfns, HPAGE_SIZE); + offset = ALIGN(start + SZ_8K + memmap_size, nd_pfn->align) - start; - else if (nd_pfn->mode == PFN_MODE_RAM) + } else if (nd_pfn->mode == PFN_MODE_RAM) offset = ALIGN(start + SZ_8K, nd_pfn->align) - start; else goto err; -- cgit v1.2.3 From 1db488d12894f1936360779d6ab2aede3dd7f06a Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Sat, 2 Apr 2016 16:17:38 -0700 Subject: Drivers: hv: vmbus: Fix signaling logic in hv_need_to_signal_on_read() On the consumer side, we have interrupt driven flow management of the producer. It is sufficient to base the signaling decision on the amount of space that is available to write after the read is complete. The current code samples the previous available space and uses this in making the signaling decision. This state can be stale and is unnecessary. Since the state can be stale, we end up not signaling the host (when we should) and this can result in a hang. Fix this problem by removing the unnecessary check. I would like to thank Arseney Romanenko for pointing out this issue. Also, issue a full memory barrier before making the signaling descision to correctly deal with potential reordering of the write (read index) followed by the read of pending_sz. Signed-off-by: K. Y. Srinivasan Tested-by: Dexuan Cui Cc: Signed-off-by: Greg Kroah-Hartman --- drivers/hv/ring_buffer.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 5613e2b5cff7..a40a73a7b71d 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -103,15 +103,29 @@ static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi) * there is room for the producer to send the pending packet. */ -static bool hv_need_to_signal_on_read(u32 prev_write_sz, - struct hv_ring_buffer_info *rbi) +static bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi) { u32 cur_write_sz; u32 r_size; - u32 write_loc = rbi->ring_buffer->write_index; + u32 write_loc; u32 read_loc = rbi->ring_buffer->read_index; - u32 pending_sz = rbi->ring_buffer->pending_send_sz; + u32 pending_sz; + /* + * Issue a full memory barrier before making the signaling decision. + * Here is the reason for having this barrier: + * If the reading of the pend_sz (in this function) + * were to be reordered and read before we commit the new read + * index (in the calling function) we could + * have a problem. If the host were to set the pending_sz after we + * have sampled pending_sz and go to sleep before we commit the + * read index, we could miss sending the interrupt. Issue a full + * memory barrier to address this. + */ + mb(); + + pending_sz = rbi->ring_buffer->pending_send_sz; + write_loc = rbi->ring_buffer->write_index; /* If the other end is not blocked on write don't bother. */ if (pending_sz == 0) return false; @@ -120,7 +134,7 @@ static bool hv_need_to_signal_on_read(u32 prev_write_sz, cur_write_sz = write_loc >= read_loc ? r_size - (write_loc - read_loc) : read_loc - write_loc; - if ((prev_write_sz < pending_sz) && (cur_write_sz >= pending_sz)) + if (cur_write_sz >= pending_sz) return true; return false; @@ -455,7 +469,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, /* Update the read index */ hv_set_next_read_location(inring_info, next_read_location); - *signal = hv_need_to_signal_on_read(bytes_avail_towrite, inring_info); + *signal = hv_need_to_signal_on_read(inring_info); return ret; } -- cgit v1.2.3 From e00f7bd221292b318d4d09c3f0c2c8af9b1e5edf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 15 Apr 2016 17:45:10 +0300 Subject: virtio: Silence uninitialized variable warning Smatch complains that we might not initialize "queue". The issue is callers like setup_vq() from virtio_pci_modern.c where "num" could be something like 2 and "vring_align" is 64. In that case, vring_size() is less than PAGE_SIZE. It won't happen in real life, but we're getting the value of "num" from a register so it's not really possible to tell what value it holds with static analysis. Let's just silence the warning. Signed-off-by: Dan Carpenter Signed-off-by: Michael S. Tsirkin --- drivers/virtio/virtio_ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 5c802d47892c..ca6bfddaacad 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1006,7 +1006,7 @@ struct virtqueue *vring_create_virtqueue( const char *name) { struct virtqueue *vq; - void *queue; + void *queue = NULL; dma_addr_t dma_addr; size_t queue_size_in_bytes; struct vring vring; -- cgit v1.2.3 From 04974df8049fc4240d22759a91e035082ccd18b4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 1 May 2016 15:52:31 -0700 Subject: Linux 4.6-rc6 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9496df81b9a8..7466de60ddc7 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ VERSION = 4 PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = -rc5 -NAME = Blurry Fish Butt +EXTRAVERSION = -rc6 +NAME = Charred Weasel # *DOCUMENTATION* # To see a list of typical targets execute "make help" -- cgit v1.2.3 From 018f8258582381bcce484312f0e9ec2970d0383e Mon Sep 17 00:00:00 2001 From: Wang Shanker Date: Fri, 29 Apr 2016 01:29:43 +0800 Subject: net: l2tp: fix reversed udp6 checksum flags This patch fixes a bug which causes the behavior of whether to ignore udp6 checksum of udp6 encapsulated l2tp tunnel contrary to what userspace program requests. When the flag `L2TP_ATTR_UDP_ZERO_CSUM6_RX` is set by userspace, it is expected that udp6 checksums of received packets of the l2tp tunnel to create should be ignored. In `l2tp_netlink.c`: `l2tp_nl_cmd_tunnel_create()`, `cfg.udp6_zero_rx_checksums` is set according to the flag, and then passed to `l2tp_core.c`: `l2tp_tunnel_create()` and then `l2tp_tunnel_sock_create()`. In `l2tp_tunnel_sock_create()`, `udp_conf.use_udp6_rx_checksums` is set the same to `cfg.udp6_zero_rx_checksums`. However, if we want the checksum to be ignored, `udp_conf.use_udp6_rx_checksums` should be set to `false`, i.e. be set to the contrary. Similarly, the same should be done to `udp_conf.use_udp6_tx_checksums`. Signed-off-by: Miao Wang Acked-by: James Chapman Signed-off-by: David S. Miller --- net/l2tp/l2tp_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index afca2eb4dfa7..6edfa9980314 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1376,9 +1376,9 @@ static int l2tp_tunnel_sock_create(struct net *net, memcpy(&udp_conf.peer_ip6, cfg->peer_ip6, sizeof(udp_conf.peer_ip6)); udp_conf.use_udp6_tx_checksums = - cfg->udp6_zero_tx_checksums; + ! cfg->udp6_zero_tx_checksums; udp_conf.use_udp6_rx_checksums = - cfg->udp6_zero_rx_checksums; + ! cfg->udp6_zero_rx_checksums; } else #endif { -- cgit v1.2.3 From 90e5d0db2b221f0cbbb91e9e61fdb7dbb9e1afc2 Mon Sep 17 00:00:00 2001 From: Craig Gallek Date: Thu, 28 Apr 2016 19:24:32 -0400 Subject: soreuseport: Fix TCP listener hash collision I forgot to include a check for listener port equality when deciding if two sockets should belong to the same reuseport group. This was not caught previously because it's only necessary when two listening sockets for the same user happen to hash to the same listener bucket. The same error does not exist in the UDP path. Fixes: c125e80b8868("soreuseport: fast reuseport TCP socket selection") Signed-off-by: Craig Gallek Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/inet_hashtables.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index bc68eced0105..0d9e9d7bb029 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -470,6 +470,7 @@ static int inet_reuseport_add_sock(struct sock *sk, const struct sock *sk2, bool match_wildcard)) { + struct inet_bind_bucket *tb = inet_csk(sk)->icsk_bind_hash; struct sock *sk2; struct hlist_nulls_node *node; kuid_t uid = sock_i_uid(sk); @@ -479,6 +480,7 @@ static int inet_reuseport_add_sock(struct sock *sk, sk2->sk_family == sk->sk_family && ipv6_only_sock(sk2) == ipv6_only_sock(sk) && sk2->sk_bound_dev_if == sk->sk_bound_dev_if && + inet_csk(sk2)->icsk_bind_hash == tb && sk2->sk_reuseport && uid_eq(uid, sock_i_uid(sk2)) && saddr_same(sk, sk2, false)) return reuseport_add_sock(sk, sk2); -- cgit v1.2.3 From c489565b536ff5382460273fd9513f0adebec024 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Apr 2016 09:05:59 +0200 Subject: net/smscx5xx: use the device tree for mac address This takes the MAC address for smsc75xx/smsc95xx USB network devices from a the device tree. This is required to get a usable persistent address on the popular beagleboard, whose hardware designers accidentally forgot that an ethernet device really requires an a MAC address to be functional. The Raspberry Pi also ships smsc9514 without a serial EEPROM, stores the MAC address in ROM accessible via VC4 firmware. The smsc75xx and smsc95xx drivers are just two copies of the same code, so better fix both. [lkundrak@v3.sk: updated to use of_get_property() as per suggestion from Arnd, reworded the message and comments a bit] Tested-by: Lubomir Rintel Signed-off-by: Arnd Bergmann Signed-off-by: Lubomir Rintel Signed-off-by: David S. Miller --- drivers/net/usb/smsc75xx.c | 12 +++++++++++- drivers/net/usb/smsc95xx.c | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 30033dbe6662..c369db99c005 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "smsc75xx.h" #define SMSC_CHIPNAME "smsc75xx" @@ -761,6 +762,15 @@ static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) static void smsc75xx_init_mac_address(struct usbnet *dev) { + const u8 *mac_addr; + + /* maybe the boot loader passed the MAC address in devicetree */ + mac_addr = of_get_mac_address(dev->udev->dev.of_node); + if (mac_addr) { + memcpy(dev->net->dev_addr, mac_addr, ETH_ALEN); + return; + } + /* try reading mac address from EEPROM */ if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { @@ -772,7 +782,7 @@ static void smsc75xx_init_mac_address(struct usbnet *dev) } } - /* no eeprom, or eeprom values are invalid. generate random MAC */ + /* no useful static MAC address found. generate a random one */ eth_hw_addr_random(dev->net); netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); } diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 66b3ab9f614e..2edc2bc6d1b9 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "smsc95xx.h" #define SMSC_CHIPNAME "smsc95xx" @@ -765,6 +766,15 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) static void smsc95xx_init_mac_address(struct usbnet *dev) { + const u8 *mac_addr; + + /* maybe the boot loader passed the MAC address in devicetree */ + mac_addr = of_get_mac_address(dev->udev->dev.of_node); + if (mac_addr) { + memcpy(dev->net->dev_addr, mac_addr, ETH_ALEN); + return; + } + /* try reading mac address from EEPROM */ if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { @@ -775,7 +785,7 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) } } - /* no eeprom, or eeprom values are invalid. generate random MAC */ + /* no useful static MAC address found. generate a random one */ eth_hw_addr_random(dev->net); netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); } -- cgit v1.2.3 From 0b86a2a1e5807326f8eb44e9919d0baadeda3a69 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Fri, 29 Apr 2016 11:06:50 +0200 Subject: cxgb3: fix out of bounds read An out of bounds read of 2 bytes was discovered in cxgb3 with KASAN. t3_config_rss() expects both arrays it gets as parameters to have terminators. setup_rss(), the caller, forgets to add a terminator to one of the arrays. Thankfully the iteration in t3_config_rss() stops anyway, but in the last iteration the check for the terminator is an out of bounds read. Add the missing terminator to rspq_map[]. Reported-by: Jan Stancek Signed-off-by: Michal Schmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 60908eab3b3a..43da891fab97 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -576,7 +576,7 @@ static void setup_rss(struct adapter *adap) unsigned int nq0 = adap2pinfo(adap, 0)->nqsets; unsigned int nq1 = adap->port[1] ? adap2pinfo(adap, 1)->nqsets : 1; u8 cpus[SGE_QSETS + 1]; - u16 rspq_map[RSS_TABLE_SIZE]; + u16 rspq_map[RSS_TABLE_SIZE + 1]; for (i = 0; i < SGE_QSETS; ++i) cpus[i] = i; @@ -586,6 +586,7 @@ static void setup_rss(struct adapter *adap) rspq_map[i] = i % nq0; rspq_map[i + RSS_TABLE_SIZE / 2] = (i % nq1) + nq0; } + rspq_map[RSS_TABLE_SIZE] = 0xffff; /* terminator */ t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN | F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | -- cgit v1.2.3 From efe790502be85c60daa65c8aa51f05c333186e12 Mon Sep 17 00:00:00 2001 From: Hamish Martin Date: Fri, 29 Apr 2016 10:40:24 -0400 Subject: tipc: only process unicast on intended node We have observed complete lock up of broadcast-link transmission due to unacknowledged packets never being removed from the 'transmq' queue. This is traced to nodes having their ack field set beyond the sequence number of packets that have actually been transmitted to them. Consider an example where node 1 has sent 10 packets to node 2 on a link and node 3 has sent 20 packets to node 2 on another link. We see examples of an ack from node 2 destined for node 3 being treated as an ack from node 2 at node 1. This leads to the ack on the node 1 to node 2 link being increased to 20 even though we have only sent 10 packets. When node 1 does get around to sending further packets, none of the packets with sequence numbers less than 21 are actually removed from the transmq. To resolve this we reinstate some code lost in commit d999297c3dbb ("tipc: reduce locking scope during packet reception") which ensures that only messages destined for the receiving node are processed by that node. This prevents the sequence numbers from getting out of sync and resolves the packet leakage, thereby resolving the broadcast-link transmission lock-ups we observed. While we are aware that this change only patches over a root problem that we still haven't identified, this is a sanity test that it is always legitimate to do. It will remain in the code even after we identify and fix the real problem. Reviewed-by: Chris Packham Reviewed-by: John Thompson Signed-off-by: Hamish Martin Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/node.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/tipc/node.c b/net/tipc/node.c index ace178fd3850..9aaa1bc566ae 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -1444,6 +1444,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) int bearer_id = b->identity; struct tipc_link_entry *le; u16 bc_ack = msg_bcast_ack(hdr); + u32 self = tipc_own_addr(net); int rc = 0; __skb_queue_head_init(&xmitq); @@ -1460,6 +1461,10 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) return tipc_node_bc_rcv(net, skb, bearer_id); } + /* Discard unicast link messages destined for another node */ + if (unlikely(!msg_short(hdr) && (msg_destnode(hdr) != self))) + goto discard; + /* Locate neighboring node that sent packet */ n = tipc_node_find(net, msg_prevnode(hdr)); if (unlikely(!n)) -- cgit v1.2.3 From b4c112114aab9aff5ed4568ca5e662bb02cdfe74 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sat, 30 Apr 2016 08:29:27 +1000 Subject: powerpc: Fix bad inline asm constraint in create_zero_mask() In create_zero_mask() we have: addi %1,%2,-1 andc %1,%1,%2 popcntd %0,%1 using the "r" constraint for %2. r0 is a valid register in the "r" set, but addi X,r0,X turns it into an li: li r7,-1 andc r7,r7,r0 popcntd r4,r7 Fix this by using the "b" constraint, for which r0 is not a valid register. This was found with a kernel build using gcc trunk, narrowed down to when -frename-registers was enabled at -O2. It is just luck however that we aren't seeing this on older toolchains. Thanks to Segher for working with me to find this issue. Cc: stable@vger.kernel.org Fixes: d0cebfa650a0 ("powerpc: word-at-a-time optimization for 64-bit Little Endian") Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/word-at-a-time.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/word-at-a-time.h b/arch/powerpc/include/asm/word-at-a-time.h index e4396a7d0f7c..4afe66aa1400 100644 --- a/arch/powerpc/include/asm/word-at-a-time.h +++ b/arch/powerpc/include/asm/word-at-a-time.h @@ -82,7 +82,7 @@ static inline unsigned long create_zero_mask(unsigned long bits) "andc %1,%1,%2\n\t" "popcntd %0,%1" : "=r" (leading_zero_bits), "=&r" (trailing_zero_bit_mask) - : "r" (bits)); + : "b" (bits)); return leading_zero_bits; } -- cgit v1.2.3 From 2c94b53738549d81dc7464a32117d1f5112c64d3 Mon Sep 17 00:00:00 2001 From: Tim Bingham Date: Fri, 29 Apr 2016 13:30:23 -0400 Subject: net: Implement net_dbg_ratelimited() for CONFIG_DYNAMIC_DEBUG case Prior to commit d92cff89a0c8 ("net_dbg_ratelimited: turn into no-op when !DEBUG") the implementation of net_dbg_ratelimited() was buggy for both the DEBUG and CONFIG_DYNAMIC_DEBUG cases. The bug was that net_ratelimit() was being called and, despite returning true, nothing was being printed to the console. This resulted in messages like the following - "net_ratelimit: %d callbacks suppressed" with no other output nearby. After commit d92cff89a0c8 ("net_dbg_ratelimited: turn into no-op when !DEBUG") the bug is fixed for the DEBUG case. However, there's no output at all for CONFIG_DYNAMIC_DEBUG case. This patch restores debug output (if enabled) for the CONFIG_DYNAMIC_DEBUG case. Add a definition of net_dbg_ratelimited() for the CONFIG_DYNAMIC_DEBUG case. The implementation takes care to check that dynamic debugging is enabled before calling net_ratelimit(). Fixes: d92cff89a0c8 ("net_dbg_ratelimited: turn into no-op when !DEBUG") Signed-off-by: Tim Bingham Signed-off-by: David S. Miller --- include/linux/net.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/linux/net.h b/include/linux/net.h index 49175e4ced11..f840d77c6c31 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -246,7 +246,15 @@ do { \ net_ratelimited_function(pr_warn, fmt, ##__VA_ARGS__) #define net_info_ratelimited(fmt, ...) \ net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__) -#if defined(DEBUG) +#if defined(CONFIG_DYNAMIC_DEBUG) +#define net_dbg_ratelimited(fmt, ...) \ +do { \ + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ + if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \ + net_ratelimit()) \ + __dynamic_pr_debug(&descriptor, fmt, ##__VA_ARGS__); \ +} while (0) +#elif defined(DEBUG) #define net_dbg_ratelimited(fmt, ...) \ net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__) #else -- cgit v1.2.3 From b7f8fe251e4609e2a437bd2c2dea01e61db6849c Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Fri, 29 Apr 2016 23:31:32 +0200 Subject: gre: do not pull header in ICMP error processing iptunnel_pull_header expects that IP header was already pulled; with this expectation, it pulls the tunnel header. This is not true in gre_err. Furthermore, ipv4_update_pmtu and ipv4_redirect expect that skb->data points to the IP header. We cannot pull the tunnel header in this path. It's just a matter of not calling iptunnel_pull_header - we don't need any of its effects. Fixes: bda7bb463436 ("gre: Allow multiple protocol listener for gre protocol.") Signed-off-by: Jiri Benc Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index f502d34bcb40..205a2b8a5a84 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -179,6 +179,7 @@ static __be16 tnl_flags_to_gre_flags(__be16 tflags) return flags; } +/* Fills in tpi and returns header length to be pulled. */ static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, bool *csum_err) { @@ -238,7 +239,7 @@ static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, return -EINVAL; } } - return iptunnel_pull_header(skb, hdr_len, tpi->proto, false); + return hdr_len; } static void ipgre_err(struct sk_buff *skb, u32 info, @@ -341,7 +342,7 @@ static void gre_err(struct sk_buff *skb, u32 info) struct tnl_ptk_info tpi; bool csum_err = false; - if (parse_gre_header(skb, &tpi, &csum_err)) { + if (parse_gre_header(skb, &tpi, &csum_err) < 0) { if (!csum_err) /* ignore csum errors. */ return; } @@ -419,6 +420,7 @@ static int gre_rcv(struct sk_buff *skb) { struct tnl_ptk_info tpi; bool csum_err = false; + int hdr_len; #ifdef CONFIG_NET_IPGRE_BROADCAST if (ipv4_is_multicast(ip_hdr(skb)->daddr)) { @@ -428,7 +430,10 @@ static int gre_rcv(struct sk_buff *skb) } #endif - if (parse_gre_header(skb, &tpi, &csum_err) < 0) + hdr_len = parse_gre_header(skb, &tpi, &csum_err); + if (hdr_len < 0) + goto drop; + if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false) < 0) goto drop; if (ipgre_rcv(skb, &tpi) == PACKET_RCVD) -- cgit v1.2.3 From ba41e1bc28bd862089b0fc00e8136aa258a62b21 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 2 May 2016 02:27:19 +0200 Subject: cpufreq: intel_pstate: Fix HWP on boot CPU after system resume Commit 41cfd64cf49fc "Update frequencies of policy->cpus only from ->set_policy()" changed the way the intel_pstate driver's ->set_policy callback updates the HWP (hardware-managed P-states) settings. A side effect of it is that if those settings are modified on the boot CPU during system suspend and wakeup, they will never be restored during subsequent system resume. To address this problem, allow cpufreq drivers that don't provide ->target or ->target_index callbacks to use ->suspend and ->resume callbacks and add a ->resume callback to intel_pstate to restore the HWP settings on the CPUs that belong to the given policy. Fixes: 41cfd64cf49fc "Update frequencies of policy->cpus only from ->set_policy()" Tested-by: Srinivas Pandruvada Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 26 +++++++++++++++----------- drivers/cpufreq/intel_pstate.c | 12 ++++++++++-- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index e93405f0eac4..c4acfc5273b3 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1557,21 +1557,25 @@ void cpufreq_suspend(void) if (!cpufreq_driver) return; - if (!has_target()) + if (!has_target() && !cpufreq_driver->suspend) goto suspend; pr_debug("%s: Suspending Governors\n", __func__); for_each_active_policy(policy) { - down_write(&policy->rwsem); - ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); - up_write(&policy->rwsem); + if (has_target()) { + down_write(&policy->rwsem); + ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); + up_write(&policy->rwsem); - if (ret) - pr_err("%s: Failed to stop governor for policy: %p\n", - __func__, policy); - else if (cpufreq_driver->suspend - && cpufreq_driver->suspend(policy)) + if (ret) { + pr_err("%s: Failed to stop governor for policy: %p\n", + __func__, policy); + continue; + } + } + + if (cpufreq_driver->suspend && cpufreq_driver->suspend(policy)) pr_err("%s: Failed to suspend driver: %p\n", __func__, policy); } @@ -1596,7 +1600,7 @@ void cpufreq_resume(void) cpufreq_suspended = false; - if (!has_target()) + if (!has_target() && !cpufreq_driver->resume) return; pr_debug("%s: Resuming Governors\n", __func__); @@ -1605,7 +1609,7 @@ void cpufreq_resume(void) if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) { pr_err("%s: Failed to resume driver: %p\n", __func__, policy); - } else { + } else if (has_target()) { down_write(&policy->rwsem); ret = cpufreq_start_governor(policy); up_write(&policy->rwsem); diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index f502d5b90c25..66f7f0071cab 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -453,6 +453,14 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask) } } +static int intel_pstate_hwp_set_policy(struct cpufreq_policy *policy) +{ + if (hwp_active) + intel_pstate_hwp_set(policy->cpus); + + return 0; +} + static void intel_pstate_hwp_set_online_cpus(void) { get_online_cpus(); @@ -1346,8 +1354,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) out: intel_pstate_set_update_util_hook(policy->cpu); - if (hwp_active) - intel_pstate_hwp_set(policy->cpus); + intel_pstate_hwp_set_policy(policy); return 0; } @@ -1411,6 +1418,7 @@ static struct cpufreq_driver intel_pstate_driver = { .flags = CPUFREQ_CONST_LOOPS, .verify = intel_pstate_verify_policy, .setpolicy = intel_pstate_set_policy, + .resume = intel_pstate_hwp_set_policy, .get = intel_pstate_get, .init = intel_pstate_cpu_init, .stop_cpu = intel_pstate_stop_cpu, -- cgit v1.2.3 From 243d4c0270a184e91ae589138652e19394edb1e7 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 28 Apr 2016 07:25:03 -0300 Subject: [media] media: exynos4-is: fix deadlock on driver probe Commit 0c426c472b5585ed6e59160359c979506d45ae49 ("[media] media: Always keep a graph walk large enough around") changed media_device_register_entity() function to take mdev->graph_mutex. This causes deadlock in driver probe, which calls (indirectly) this function with ->graph_mutex taken. This patch removes taking ->graph_mutex in driver probe to avoid deadlock. Other drivers don't take ->graph_mutex for entity registration, so this change should be safe. Signed-off-by: Marek Szyprowski Acked-by: Sakari Ailus Tested-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/media-dev.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index feb521f28e14..4f494acd8150 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1446,22 +1446,13 @@ static int fimc_md_probe(struct platform_device *pdev) platform_set_drvdata(pdev, fmd); - /* Protect the media graph while we're registering entities */ - mutex_lock(&fmd->media_dev.graph_mutex); - ret = fimc_md_register_platform_entities(fmd, dev->of_node); - if (ret) { - mutex_unlock(&fmd->media_dev.graph_mutex); + if (ret) goto err_clk; - } ret = fimc_md_register_sensor_entities(fmd); - if (ret) { - mutex_unlock(&fmd->media_dev.graph_mutex); + if (ret) goto err_m_ent; - } - - mutex_unlock(&fmd->media_dev.graph_mutex); ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); if (ret) -- cgit v1.2.3 From 9b15dfe0542fd6f7455c6aeca1cf711192343bf9 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 28 Apr 2016 07:25:04 -0300 Subject: [media] media: s3c-camif: fix deadlock on driver probe() Commit 0c426c472b5585ed6e59160359c979506d45ae49 ("[media] media: Always keep a graph walk large enough around") changed media_device_register_entity() function to take mdev->graph_mutex. This causes deadlock in driver probe, which calls (indirectly) this function with ->graph_mutex taken. This patch removes taking ->graph_mutex in driver probe to avoid deadlock. Other drivers don't take ->graph_mutex for entity registration, so this change should be safe. Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s3c-camif/camif-core.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index 0b44b9accf50..af237af204e2 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -493,21 +493,17 @@ static int s3c_camif_probe(struct platform_device *pdev) if (ret < 0) goto err_sens; - mutex_lock(&camif->media_dev.graph_mutex); - ret = v4l2_device_register_subdev_nodes(&camif->v4l2_dev); if (ret < 0) - goto err_unlock; + goto err_sens; ret = camif_register_video_nodes(camif); if (ret < 0) - goto err_unlock; + goto err_sens; ret = camif_create_media_links(camif); if (ret < 0) - goto err_unlock; - - mutex_unlock(&camif->media_dev.graph_mutex); + goto err_sens; ret = media_device_register(&camif->media_dev); if (ret < 0) @@ -516,8 +512,6 @@ static int s3c_camif_probe(struct platform_device *pdev) pm_runtime_put(dev); return 0; -err_unlock: - mutex_unlock(&camif->media_dev.graph_mutex); err_sens: v4l2_device_unregister(&camif->v4l2_dev); media_device_unregister(&camif->media_dev); -- cgit v1.2.3 From d1306eb675ad7a9a760b6b8e8e189824b8db89e7 Mon Sep 17 00:00:00 2001 From: Stanislav Meduna Date: Mon, 2 May 2016 16:05:11 +0100 Subject: nvmem: mxs-ocotp: fix buffer overflow in read This patch fixes the issue where the mxs_ocotp_read is reading the ocotp in reg_size steps but decrements the remaining size by 1. The number of iterations is thus four times higher, overwriting the area behind the output buffer. Fixes: c01e9a11ab6f ("nvmem: add driver for ocotp in i.MX23 and i.MX28") Tested-by: Stefan Wahren Signed-off-by: Stanislav Meduna Signed-off-by: Srinivas Kandagatla Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/mxs-ocotp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nvmem/mxs-ocotp.c b/drivers/nvmem/mxs-ocotp.c index 8ba19bba3156..2bb3c5799ac4 100644 --- a/drivers/nvmem/mxs-ocotp.c +++ b/drivers/nvmem/mxs-ocotp.c @@ -94,7 +94,7 @@ static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size, if (ret) goto close_banks; - while (val_size) { + while (val_size >= reg_size) { if ((offset < OCOTP_DATA_OFFSET) || (offset % 16)) { /* fill up non-data register */ *buf = 0; @@ -103,7 +103,7 @@ static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size, } buf++; - val_size--; + val_size -= reg_size; offset += reg_size; } -- cgit v1.2.3 From 9be427efc764464fbcbc1ca3f0d34f575cb0f037 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 2 May 2016 15:35:57 +0200 Subject: Revert "USB / PM: Allow USB devices to remain runtime-suspended when sleeping" This reverts commit e3345db85068ddb937fc0ba40dfc39c293dad977, which broke system resume for a large class of devices. Devices that after having been reset during resume need to be rebound due to a missing reset_resume callback, are now left in a suspended state. This specifically broke resume of common USB-serial devices, which are now unusable after system suspend (until disconnected and reconnected) when USB persist is enabled. During resume, usb_resume_interface will set the needs_binding flag for such interfaces, but unlike system resume, run-time resume does not honour it. Cc: stable # 4.5 Signed-off-by: Johan Hovold Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/port.c | 6 ------ drivers/usb/core/usb.c | 8 +------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 14718a9ffcfb..460c855be0d0 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -249,18 +249,12 @@ static int usb_port_runtime_suspend(struct device *dev) return retval; } - -static int usb_port_prepare(struct device *dev) -{ - return 1; -} #endif static const struct dev_pm_ops usb_port_pm_ops = { #ifdef CONFIG_PM .runtime_suspend = usb_port_runtime_suspend, .runtime_resume = usb_port_runtime_resume, - .prepare = usb_port_prepare, #endif }; diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index dcb85e3cd5a7..479187c32571 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -312,13 +312,7 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env) static int usb_dev_prepare(struct device *dev) { - struct usb_device *udev = to_usb_device(dev); - - /* Return 0 if the current wakeup setting is wrong, otherwise 1 */ - if (udev->do_remote_wakeup != device_may_wakeup(dev)) - return 0; - - return 1; + return 0; /* Implement eventually? */ } static void usb_dev_complete(struct device *dev) -- cgit v1.2.3 From 2eea65829dc6c20dccbe79726fd0f3fe7f8aa43b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 2 May 2016 09:11:53 -0700 Subject: nfit: fix translation of command status results When transportation of the command completes successfully, it indicates that the 'status' result is valid. Fix the missed checking and translation of the status field at the end of acpi_nfit_ctl(). Otherwise, we fail to handle reported errors and assume commands complete successfully. Reported-by: Linda Knippers Reviewed-by: Johannes Thumshirn Signed-off-by: Dan Williams --- drivers/acpi/nfit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c index d0f35e63640b..63cc9dbe4f3b 100644 --- a/drivers/acpi/nfit.c +++ b/drivers/acpi/nfit.c @@ -287,8 +287,11 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, offset); rc = -ENXIO; } - } else + } else { rc = 0; + if (cmd_rc) + *cmd_rc = xlat_status(buf, cmd); + } out: ACPI_FREE(out_obj); -- cgit v1.2.3 From 689de1d6ca95b3b5bd8ee446863bf81a4883ea25 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 2 May 2016 12:46:42 -0700 Subject: Minimal fix-up of bad hashing behavior of hash_64() This is a fairly minimal fixup to the horribly bad behavior of hash_64() with certain input patterns. In particular, because the multiplicative value used for the 64-bit hash was intentionally bit-sparse (so that the multiply could be done with shifts and adds on architectures without hardware multipliers), some bits did not get spread out very much. In particular, certain fairly common bit ranges in the input (roughly bits 12-20: commonly with the most information in them when you hash things like byte offsets in files or memory that have block factors that mean that the low bits are often zero) would not necessarily show up much in the result. There's a bigger patch-series brewing to fix up things more completely, but this is the fairly minimal fix for the 64-bit hashing problem. It simply picks a much better constant multiplier, spreading the bits out a lot better. NOTE! For 32-bit architectures, the bad old hash_64() remains the same for now, since 64-bit multiplies are expensive. The bigger hashing cleanup will replace the 32-bit case with something better. The new constants were picked by George Spelvin who wrote that bigger cleanup series. I just picked out the constants and part of the comment from that series. Cc: stable@vger.kernel.org Cc: George Spelvin Cc: Thomas Gleixner Signed-off-by: Linus Torvalds --- include/linux/hash.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/include/linux/hash.h b/include/linux/hash.h index 1afde47e1528..79c52fa81cac 100644 --- a/include/linux/hash.h +++ b/include/linux/hash.h @@ -32,12 +32,28 @@ #error Wordsize not 32 or 64 #endif +/* + * The above primes are actively bad for hashing, since they are + * too sparse. The 32-bit one is mostly ok, the 64-bit one causes + * real problems. Besides, the "prime" part is pointless for the + * multiplicative hash. + * + * Although a random odd number will do, it turns out that the golden + * ratio phi = (sqrt(5)-1)/2, or its negative, has particularly nice + * properties. + * + * These are the negative, (1 - phi) = (phi^2) = (3 - sqrt(5))/2. + * (See Knuth vol 3, section 6.4, exercise 9.) + */ +#define GOLDEN_RATIO_32 0x61C88647 +#define GOLDEN_RATIO_64 0x61C8864680B583EBull + static __always_inline u64 hash_64(u64 val, unsigned int bits) { u64 hash = val; -#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64 - hash = hash * GOLDEN_RATIO_PRIME_64; +#if BITS_PER_LONG == 64 + hash = hash * GOLDEN_RATIO_64; #else /* Sigh, gcc can't optimise this alone like it does for 32 bits. */ u64 n = hash; -- cgit v1.2.3 From 6071bd1aa13ed9e41824bafad845b7b7f4df5cfd Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 2 May 2016 12:20:15 -0400 Subject: netem: Segment GSO packets on enqueue This was recently reported to me, and reproduced on the latest net kernel, when attempting to run netperf from a host that had a netem qdisc attached to the egress interface: [ 788.073771] ---------------------[ cut here ]--------------------------- [ 788.096716] WARNING: at net/core/dev.c:2253 skb_warn_bad_offload+0xcd/0xda() [ 788.129521] bnx2: caps=(0x00000001801949b3, 0x0000000000000000) len=2962 data_len=0 gso_size=1448 gso_type=1 ip_summed=3 [ 788.182150] Modules linked in: sch_netem kvm_amd kvm crc32_pclmul ipmi_ssif ghash_clmulni_intel sp5100_tco amd64_edac_mod aesni_intel lrw gf128mul glue_helper ablk_helper edac_mce_amd cryptd pcspkr sg edac_core hpilo ipmi_si i2c_piix4 k10temp fam15h_power hpwdt ipmi_msghandler shpchp acpi_power_meter pcc_cpufreq nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables xfs libcrc32c sd_mod crc_t10dif crct10dif_generic mgag200 syscopyarea sysfillrect sysimgblt i2c_algo_bit drm_kms_helper ahci ata_generic pata_acpi ttm libahci crct10dif_pclmul pata_atiixp tg3 libata crct10dif_common drm crc32c_intel ptp serio_raw bnx2 r8169 hpsa pps_core i2c_core mii dm_mirror dm_region_hash dm_log dm_mod [ 788.465294] CPU: 16 PID: 0 Comm: swapper/16 Tainted: G W ------------ 3.10.0-327.el7.x86_64 #1 [ 788.511521] Hardware name: HP ProLiant DL385p Gen8, BIOS A28 12/17/2012 [ 788.542260] ffff880437c036b8 f7afc56532a53db9 ffff880437c03670 ffffffff816351f1 [ 788.576332] ffff880437c036a8 ffffffff8107b200 ffff880633e74200 ffff880231674000 [ 788.611943] 0000000000000001 0000000000000003 0000000000000000 ffff880437c03710 [ 788.647241] Call Trace: [ 788.658817] [] dump_stack+0x19/0x1b [ 788.686193] [] warn_slowpath_common+0x70/0xb0 [ 788.713803] [] warn_slowpath_fmt+0x5c/0x80 [ 788.741314] [] ? ___ratelimit+0x93/0x100 [ 788.767018] [] skb_warn_bad_offload+0xcd/0xda [ 788.796117] [] skb_checksum_help+0x17c/0x190 [ 788.823392] [] netem_enqueue+0x741/0x7c0 [sch_netem] [ 788.854487] [] dev_queue_xmit+0x2a8/0x570 [ 788.880870] [] ip_finish_output+0x53d/0x7d0 ... The problem occurs because netem is not prepared to handle GSO packets (as it uses skb_checksum_help in its enqueue path, which cannot manipulate these frames). The solution I think is to simply segment the skb in a simmilar fashion to the way we do in __dev_queue_xmit (via validate_xmit_skb), with some minor changes. When we decide to corrupt an skb, if the frame is GSO, we segment it, corrupt the first segment, and enqueue the remaining ones. tested successfully by myself on the latest net kernel, to which this applies Signed-off-by: Neil Horman CC: Jamal Hadi Salim CC: "David S. Miller" CC: netem@lists.linux-foundation.org CC: eric.dumazet@gmail.com CC: stephen@networkplumber.org Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/sch_netem.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 9640bb39a5d2..4befe97a9034 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -395,6 +395,25 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) sch->q.qlen++; } +/* netem can't properly corrupt a megapacket (like we get from GSO), so instead + * when we statistically choose to corrupt one, we instead segment it, returning + * the first packet to be corrupted, and re-enqueue the remaining frames + */ +static struct sk_buff *netem_segment(struct sk_buff *skb, struct Qdisc *sch) +{ + struct sk_buff *segs; + netdev_features_t features = netif_skb_features(skb); + + segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); + + if (IS_ERR_OR_NULL(segs)) { + qdisc_reshape_fail(skb, sch); + return NULL; + } + consume_skb(skb); + return segs; +} + /* * Insert one skb into qdisc. * Note: parent depends on return value to account for queue length. @@ -407,7 +426,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) /* We don't fill cb now as skb_unshare() may invalidate it */ struct netem_skb_cb *cb; struct sk_buff *skb2; + struct sk_buff *segs = NULL; + unsigned int len = 0, last_len, prev_len = qdisc_pkt_len(skb); + int nb = 0; int count = 1; + int rc = NET_XMIT_SUCCESS; /* Random duplication */ if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) @@ -453,10 +476,23 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) * do it now in software before we mangle it. */ if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) { + if (skb_is_gso(skb)) { + segs = netem_segment(skb, sch); + if (!segs) + return NET_XMIT_DROP; + } else { + segs = skb; + } + + skb = segs; + segs = segs->next; + if (!(skb = skb_unshare(skb, GFP_ATOMIC)) || (skb->ip_summed == CHECKSUM_PARTIAL && - skb_checksum_help(skb))) - return qdisc_drop(skb, sch); + skb_checksum_help(skb))) { + rc = qdisc_drop(skb, sch); + goto finish_segs; + } skb->data[prandom_u32() % skb_headlen(skb)] ^= 1<<(prandom_u32() % 8); @@ -516,6 +552,27 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) sch->qstats.requeues++; } +finish_segs: + if (segs) { + while (segs) { + skb2 = segs->next; + segs->next = NULL; + qdisc_skb_cb(segs)->pkt_len = segs->len; + last_len = segs->len; + rc = qdisc_enqueue(segs, sch); + if (rc != NET_XMIT_SUCCESS) { + if (net_xmit_drop_count(rc)) + qdisc_qstats_drop(sch); + } else { + nb++; + len += last_len; + } + segs = skb2; + } + sch->q.qlen += nb; + if (nb > 1) + qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len); + } return NET_XMIT_SUCCESS; } -- cgit v1.2.3 From 4441f63ab7e581ae460c9f7e06fba8a2be192e81 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 3 May 2016 11:19:33 +0200 Subject: fuse: update mailing list in MAINTAINERS The fuse mailing list seems not to be open anymore. The discussion on fuse-devel@... is mostly userspace related anyway. Reported-by: Andreas Gruenbacher Signed-off-by: Miklos Szeredi --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1d5b4becab6f..924d399a15d2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4744,7 +4744,7 @@ F: drivers/platform/x86/fujitsu-tablet.c FUSE: FILESYSTEM IN USERSPACE M: Miklos Szeredi -L: fuse-devel@lists.sourceforge.net +L: linux-fsdevel@vger.kernel.org W: http://fuse.sourceforge.net/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git S: Maintained -- cgit v1.2.3 From eff6ca97998386447b795362cc20213114af2870 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Mon, 2 May 2016 21:17:34 -0700 Subject: HID: wacom: add missed stylus_in_proximity line back Commit 7e12978 ("HID: wacom: break out wacom_intuos_get_tool_type") by accident removed stylus_in_proximity flag for Intuos series while shuffling the code around. Fix that by reintroducing that flag setting in wacom_intuos_inout(), where it originally was. Fixes: 7e12978 ("HID: wacom: break out wacom_intuos_get_tool_type") Signed-off-by: Ping Cheng Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index e9902f2f8ec9..cf2ba43453fd 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -684,6 +684,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) wacom->tool[idx] = wacom_intuos_get_tool_type(wacom->id[idx]); + wacom->shared->stylus_in_proximity = true; return 1; } -- cgit v1.2.3 From 0092d3edcb23fcdb8cbe4159ba94a534290ff982 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 3 May 2016 12:44:29 +1000 Subject: drm/amdgpu: set metadata pointer to NULL after freeing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this there was a double free of the metadata, which ended up freeing the fd table for me here, and taking out the machine more often than not. I reproduced with X.org + modesetting DDX + latest llvm/mesa, also required using dri3. Cc: stable@vger.kernel.org Reviewed-by: Christian König Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index e557fc1f17c8..7ecea83ce453 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -541,6 +541,7 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata, if (!metadata_size) { if (bo->metadata_size) { kfree(bo->metadata); + bo->metadata = NULL; bo->metadata_size = 0; } return 0; -- cgit v1.2.3 From 854145e0a8e9a05f7366d240e2f99d9c1ca6d6dd Mon Sep 17 00:00:00 2001 From: Chunyu Hu Date: Tue, 3 May 2016 19:34:34 +0800 Subject: tracing: Don't display trigger file for events that can't be enabled Currently register functions for events will be called through the 'reg' field of event class directly without any check when seting up triggers. Triggers for events that don't support register through debug fs (events under events/ftrace are for trace-cmd to read event format, and most of them don't have a register function except events/ftrace/functionx) can't be enabled at all, and an oops will be hit when setting up trigger for those events, so just not creating them is an easy way to avoid the oops. Link: http://lkml.kernel.org/r/1462275274-3911-1-git-send-email-chuhu@redhat.com Cc: stable@vger.kernel.org # 3.14+ Fixes: 85f2b08268c01 ("tracing: Add basic event trigger framework") Signed-off-by: Chunyu Hu Signed-off-by: Steven Rostedt --- kernel/trace/trace_events.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 05ddc0820771..6f965864cc02 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2095,8 +2095,13 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file) trace_create_file("filter", 0644, file->dir, file, &ftrace_event_filter_fops); - trace_create_file("trigger", 0644, file->dir, file, - &event_trigger_fops); + /* + * Only event directories that can be enabled should have + * triggers. + */ + if (!(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) + trace_create_file("trigger", 0644, file->dir, file, + &event_trigger_fops); trace_create_file("format", 0444, file->dir, call, &ftrace_event_format_fops); -- cgit v1.2.3 From 5f8a02a441b861fd3b1b5135a1a6e1c13ee4bb33 Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Sun, 1 May 2016 22:59:54 +0300 Subject: net/mlx5: Unmap only the relevant IO memory mapping When freeing UAR the driver tries to unmap uar->map and uar->bf_map which are mutually exclusive thus always unmapping a NULL pointer. Make sure we only call iounmap() once, for the actual mapping. Fixes: 0ba422410bbf ('net/mlx5: Fix global UAR mapping') Signed-off-by: Gal Pressman Reported-by: Doron Tsur Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/uar.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/uar.c b/drivers/net/ethernet/mellanox/mlx5/core/uar.c index 8ba080e441a1..5ff8af472bf5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/uar.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/uar.c @@ -269,8 +269,10 @@ EXPORT_SYMBOL(mlx5_alloc_map_uar); void mlx5_unmap_free_uar(struct mlx5_core_dev *mdev, struct mlx5_uar *uar) { - iounmap(uar->map); - iounmap(uar->bf_map); + if (uar->map) + iounmap(uar->map); + else + iounmap(uar->bf_map); mlx5_cmd_free_uar(mdev, uar->index); } EXPORT_SYMBOL(mlx5_unmap_free_uar); -- cgit v1.2.3 From 69976fb1045850a742deb9790ea49cbc6f497531 Mon Sep 17 00:00:00 2001 From: Matthew Finlay Date: Sun, 1 May 2016 22:59:55 +0300 Subject: net/mlx5: Kconfig: Fix MLX5_EN/VXLAN build issue When MLX5_EN=y MLX5_CORE=y and VXLAN=m there is a linker error for vxlan_get_rx_port() due to the fact that VXLAN is a module. Change Kconfig to select VXLAN when MLX5_CORE=y. When MLX5_CORE=m there is no dependency on the value of VXLAN. Fixes: b3f63c3d5e2c ('net/mlx5e: Add netdev support for VXLAN tunneling') Signed-off-by: Matthew Finlay Reported-by: Arnd Bergmann Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig index 1cf722eba607..559d11a443bc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig +++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig @@ -14,6 +14,7 @@ config MLX5_CORE_EN bool "Mellanox Technologies ConnectX-4 Ethernet support" depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE select PTP_1588_CLOCK + select VXLAN if MLX5_CORE=y default n ---help--- Ethernet support in Mellanox Technologies ConnectX-4 NIC. -- cgit v1.2.3 From 7bb2975599210097115021e542b6137781a09588 Mon Sep 17 00:00:00 2001 From: Matthew Finlay Date: Sun, 1 May 2016 22:59:56 +0300 Subject: net/mlx5e: Implement a mlx5e workqueue Implement a mlx5e workqueue to handle all mlx5e specific tasks. Move all tasks currently using the system workqueue to the new workqueue. This is in preparation for vxlan using the mlx5e workqueue in order to schedule port add/remove operations. Signed-off-by: Matthew Finlay Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 + drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 30 ++++++++++++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index e80ce94b5dcf..3881dce0cc30 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -567,6 +567,7 @@ struct mlx5e_priv { struct mlx5e_vxlan_db vxlan; struct mlx5e_params params; + struct workqueue_struct *wq; struct work_struct update_carrier_work; struct work_struct set_rx_mode_work; struct delayed_work update_stats_work; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 67d548b70e14..9ab08419c557 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -262,9 +262,8 @@ static void mlx5e_update_stats_work(struct work_struct *work) mutex_lock(&priv->state_lock); if (test_bit(MLX5E_STATE_OPENED, &priv->state)) { mlx5e_update_stats(priv); - schedule_delayed_work(dwork, - msecs_to_jiffies( - MLX5E_UPDATE_STATS_INTERVAL)); + queue_delayed_work(priv->wq, dwork, + msecs_to_jiffies(MLX5E_UPDATE_STATS_INTERVAL)); } mutex_unlock(&priv->state_lock); } @@ -280,7 +279,7 @@ static void mlx5e_async_event(struct mlx5_core_dev *mdev, void *vpriv, switch (event) { case MLX5_DEV_EVENT_PORT_UP: case MLX5_DEV_EVENT_PORT_DOWN: - schedule_work(&priv->update_carrier_work); + queue_work(priv->wq, &priv->update_carrier_work); break; default: @@ -1505,7 +1504,7 @@ int mlx5e_open_locked(struct net_device *netdev) mlx5e_update_carrier(priv); mlx5e_timestamp_init(priv); - schedule_delayed_work(&priv->update_stats_work, 0); + queue_delayed_work(priv->wq, &priv->update_stats_work, 0); return 0; @@ -1961,7 +1960,7 @@ static void mlx5e_set_rx_mode(struct net_device *dev) { struct mlx5e_priv *priv = netdev_priv(dev); - schedule_work(&priv->set_rx_mode_work); + queue_work(priv->wq, &priv->set_rx_mode_work); } static int mlx5e_set_mac(struct net_device *netdev, void *addr) @@ -1976,7 +1975,7 @@ static int mlx5e_set_mac(struct net_device *netdev, void *addr) ether_addr_copy(netdev->dev_addr, saddr->sa_data); netif_addr_unlock_bh(netdev); - schedule_work(&priv->set_rx_mode_work); + queue_work(priv->wq, &priv->set_rx_mode_work); return 0; } @@ -2498,10 +2497,14 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) priv = netdev_priv(netdev); + priv->wq = create_singlethread_workqueue("mlx5e"); + if (!priv->wq) + goto err_free_netdev; + err = mlx5_alloc_map_uar(mdev, &priv->cq_uar, false); if (err) { mlx5_core_err(mdev, "alloc_map uar failed, %d\n", err); - goto err_free_netdev; + goto err_destroy_wq; } err = mlx5_core_alloc_pd(mdev, &priv->pdn); @@ -2580,7 +2583,7 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev) vxlan_get_rx_port(netdev); mlx5e_enable_async_events(priv); - schedule_work(&priv->set_rx_mode_work); + queue_work(priv->wq, &priv->set_rx_mode_work); return priv; @@ -2617,6 +2620,9 @@ err_dealloc_pd: err_unmap_free_uar: mlx5_unmap_free_uar(mdev, &priv->cq_uar); +err_destroy_wq: + destroy_workqueue(priv->wq); + err_free_netdev: free_netdev(netdev); @@ -2630,9 +2636,9 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) set_bit(MLX5E_STATE_DESTROYING, &priv->state); - schedule_work(&priv->set_rx_mode_work); + queue_work(priv->wq, &priv->set_rx_mode_work); mlx5e_disable_async_events(priv); - flush_scheduled_work(); + flush_workqueue(priv->wq); if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) { netif_device_detach(netdev); mutex_lock(&priv->state_lock); @@ -2655,6 +2661,8 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv) mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn); mlx5_core_dealloc_pd(priv->mdev, priv->pdn); mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar); + cancel_delayed_work_sync(&priv->update_stats_work); + destroy_workqueue(priv->wq); if (!test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) free_netdev(netdev); -- cgit v1.2.3 From d8cf2dda3de6e6293fb01539fb4e180a7ab42afd Mon Sep 17 00:00:00 2001 From: Matthew Finlay Date: Sun, 1 May 2016 22:59:57 +0300 Subject: net/mlx5e: Use workqueue for vxlan ops The vxlan add/delete port NDOs are called under rcu lock. The current mlx5e implementation can potentially block in these calls, which is not allowed. Move to using the mlx5e workqueue to handle these NDOs. Fixes: b3f63c3d5e2c ('net/mlx5e: Add netdev support for VXLAN tunneling') Signed-off-by: Matthew Finlay Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 4 +- drivers/net/ethernet/mellanox/mlx5/core/vxlan.c | 50 +++++++++++++++++------ drivers/net/ethernet/mellanox/mlx5/core/vxlan.h | 11 ++++- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 9ab08419c557..d4dfc5ce516a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -2157,7 +2157,7 @@ static void mlx5e_add_vxlan_port(struct net_device *netdev, if (!mlx5e_vxlan_allowed(priv->mdev)) return; - mlx5e_vxlan_add_port(priv, be16_to_cpu(port)); + mlx5e_vxlan_queue_work(priv, sa_family, be16_to_cpu(port), 1); } static void mlx5e_del_vxlan_port(struct net_device *netdev, @@ -2168,7 +2168,7 @@ static void mlx5e_del_vxlan_port(struct net_device *netdev, if (!mlx5e_vxlan_allowed(priv->mdev)) return; - mlx5e_vxlan_del_port(priv, be16_to_cpu(port)); + mlx5e_vxlan_queue_work(priv, sa_family, be16_to_cpu(port), 0); } static netdev_features_t mlx5e_vxlan_features_check(struct mlx5e_priv *priv, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c index 9f10df25f3cd..f2fd1ef16da7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c @@ -95,21 +95,22 @@ struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port) return vxlan; } -int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port) +static void mlx5e_vxlan_add_port(struct work_struct *work) { + struct mlx5e_vxlan_work *vxlan_work = + container_of(work, struct mlx5e_vxlan_work, work); + struct mlx5e_priv *priv = vxlan_work->priv; struct mlx5e_vxlan_db *vxlan_db = &priv->vxlan; + u16 port = vxlan_work->port; struct mlx5e_vxlan *vxlan; int err; - err = mlx5e_vxlan_core_add_port_cmd(priv->mdev, port); - if (err) - return err; + if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port)) + goto free_work; vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL); - if (!vxlan) { - err = -ENOMEM; + if (!vxlan) goto err_delete_port; - } vxlan->udp_port = port; @@ -119,13 +120,14 @@ int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port) if (err) goto err_free; - return 0; + goto free_work; err_free: kfree(vxlan); err_delete_port: mlx5e_vxlan_core_del_port_cmd(priv->mdev, port); - return err; +free_work: + kfree(vxlan_work); } static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) @@ -145,12 +147,36 @@ static void __mlx5e_vxlan_core_del_port(struct mlx5e_priv *priv, u16 port) kfree(vxlan); } -void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port) +static void mlx5e_vxlan_del_port(struct work_struct *work) { - if (!mlx5e_vxlan_lookup_port(priv, port)) - return; + struct mlx5e_vxlan_work *vxlan_work = + container_of(work, struct mlx5e_vxlan_work, work); + struct mlx5e_priv *priv = vxlan_work->priv; + u16 port = vxlan_work->port; __mlx5e_vxlan_core_del_port(priv, port); + + kfree(vxlan_work); +} + +void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family, + u16 port, int add) +{ + struct mlx5e_vxlan_work *vxlan_work; + + vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC); + if (!vxlan_work) + return; + + if (add) + INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_port); + else + INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_port); + + vxlan_work->priv = priv; + vxlan_work->port = port; + vxlan_work->sa_family = sa_family; + queue_work(priv->wq, &vxlan_work->work); } void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h index a01685056ab1..129f3527aa14 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h @@ -39,6 +39,13 @@ struct mlx5e_vxlan { u16 udp_port; }; +struct mlx5e_vxlan_work { + struct work_struct work; + struct mlx5e_priv *priv; + sa_family_t sa_family; + u16 port; +}; + static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev) { return (MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) && @@ -46,8 +53,8 @@ static inline bool mlx5e_vxlan_allowed(struct mlx5_core_dev *mdev) } void mlx5e_vxlan_init(struct mlx5e_priv *priv); -int mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port); -void mlx5e_vxlan_del_port(struct mlx5e_priv *priv, u16 port); +void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, sa_family_t sa_family, + u16 port, int add); struct mlx5e_vxlan *mlx5e_vxlan_lookup_port(struct mlx5e_priv *priv, u16 port); void mlx5e_vxlan_cleanup(struct mlx5e_priv *priv); -- cgit v1.2.3 From 3104b8128d4d646a574ed9d5b17c7d10752cd70b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 2 May 2016 18:53:27 -0400 Subject: drm/radeon: make sure vertical front porch is at least 1 hw doesn't like a 0 value. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/atombios_encoders.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index edd05cdb0cd8..587cae4e73c9 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -310,6 +310,10 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; + /* vertical FP must be at least 1 */ + if (mode->crtc_vsync_start == mode->crtc_vdisplay) + adjusted_mode->crtc_vsync_start++; + /* get the native mode for scaling */ if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { radeon_panel_mode_fixup(encoder, adjusted_mode); -- cgit v1.2.3 From 0126d4b9a516256f2432ca0dc78ab293a8255378 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 2 May 2016 18:54:39 -0400 Subject: drm/amdgpu: make sure vertical front porch is at least 1 hw doesn't like a 0 value. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/atombios_encoders.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c index 1e0bba29e167..1cd6de575305 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c @@ -298,6 +298,10 @@ bool amdgpu_atombios_encoder_mode_fixup(struct drm_encoder *encoder, && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; + /* vertical FP must be at least 1 */ + if (mode->crtc_vsync_start == mode->crtc_vdisplay) + adjusted_mode->crtc_vsync_start++; + /* get the native mode for scaling */ if (amdgpu_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) amdgpu_panel_mode_fixup(encoder, adjusted_mode); -- cgit v1.2.3 From 6dd745425807dc977bbea810ef703b935002fcc3 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 30 Apr 2016 23:35:11 +0300 Subject: pxa168_eth: fix mdiobus_scan() error check Since mdiobus_scan() returns either an error code or NULL on error, the driver should check for both, not only for NULL, otherwise a crash is imminent... Reported-by: Arnd Bergmann Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/pxa168_eth.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 7ace07dad6a3..c442f6ad15ff 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -979,6 +979,8 @@ static int pxa168_init_phy(struct net_device *dev) return 0; pep->phy = mdiobus_scan(pep->smi_bus, pep->phy_addr); + if (IS_ERR(pep->phy)) + return PTR_ERR(pep->phy); if (!pep->phy) return -ENODEV; -- cgit v1.2.3 From ce24c2b8a904753701fe4df313b4cbc2b0649e3e Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 1 May 2016 01:47:36 +0300 Subject: macb: fix mdiobus_scan() error check Now mdiobus_scan() returns ERR_PTR(-ENODEV) instead of NULL if the PHY device ID was read as all ones. As this was not an error before, this value should be filtered out now in this driver. Fixes: b74766a0a0fe ("phylib: don't return NULL from get_phy_device()") Signed-off-by: Sergei Shtylyov Reviewed-by: Florian Fainelli Acked-by: Nicolas Ferre Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 48a7d7dee846..898f06f9e286 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -458,7 +458,8 @@ static int macb_mii_init(struct macb *bp) struct phy_device *phydev; phydev = mdiobus_scan(bp->mii_bus, i); - if (IS_ERR(phydev)) { + if (IS_ERR(phydev) && + PTR_ERR(phydev) != -ENODEV) { err = PTR_ERR(phydev); break; } -- cgit v1.2.3 From 0e28bf93a273cce0db67a17428697abb722c36b8 Mon Sep 17 00:00:00 2001 From: Anna-Maria Gleixner Date: Mon, 2 May 2016 11:02:51 +0200 Subject: net: mvneta: Remove superfluous SMP function call Since commit 3b9d6da67e11 ("cpu/hotplug: Fix rollback during error-out in __cpu_disable()") it is ensured that callbacks of CPU_ONLINE and CPU_DOWN_PREPARE are processed on the hotplugged CPU. Due to this SMP function calls are no longer required. Replace smp_call_function_single() with a direct call to mvneta_percpu_enable() or mvneta_percpu_disable(). The functions do not require to be called with interrupts disabled, therefore the smp_call_function_single() calling convention is not preserved. Cc: Thomas Petazzoni Cc: netdev@vger.kernel.org Signed-off-by: Anna-Maria Gleixner Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 7fc490225da5..a6d26d351dfc 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -3354,8 +3354,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, /* Enable per-CPU interrupts on the CPU that is * brought up. */ - smp_call_function_single(cpu, mvneta_percpu_enable, - pp, true); + mvneta_percpu_enable(pp); /* Enable per-CPU interrupt on the one CPU we care * about. @@ -3387,8 +3386,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, /* Disable per-CPU interrupts on the CPU that is * brought down. */ - smp_call_function_single(cpu, mvneta_percpu_disable, - pp, true); + mvneta_percpu_disable(pp); break; case CPU_DEAD: -- cgit v1.2.3 From 996e802187889f1cd412e6929c9344b92ccb78c4 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Mon, 2 May 2016 09:25:10 -0700 Subject: net: Disable segmentation if checksumming is not supported In the case of the mlx4 and mlx5 driver they do not support IPv6 checksum offload for tunnels. With this being the case we should disable GSO in addition to the checksum offload features when we find that a device cannot perform a checksum on a given packet type. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 77a71cd68535..5c925ac50b95 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2802,7 +2802,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb, if (skb->ip_summed != CHECKSUM_NONE && !can_checksum_protocol(features, type)) { - features &= ~NETIF_F_CSUM_MASK; + features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); } else if (illegal_highdma(skb->dev, skb)) { features &= ~NETIF_F_SG; } -- cgit v1.2.3 From af67eb9e7e1ab37880459f83153d34b3c42b0075 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Mon, 2 May 2016 09:25:16 -0700 Subject: vxlan: Add checksum check to the features check function We need to perform an additional check on the inner headers to determine if we can offload the checksum for them. Previously this check didn't occur so we would generate an invalid frame in the case of an IPv6 header encapsulated inside of an IPv4 tunnel. To fix this I added a secondary check to vxlan_features_check so that we can verify that we can offload the inner checksum. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- include/linux/if_ether.h | 5 +++++ include/net/vxlan.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index d5569734f672..548fd535fd02 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -28,6 +28,11 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) return (struct ethhdr *)skb_mac_header(skb); } +static inline struct ethhdr *inner_eth_hdr(const struct sk_buff *skb) +{ + return (struct ethhdr *)skb_inner_mac_header(skb); +} + int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); diff --git a/include/net/vxlan.h b/include/net/vxlan.h index 73ed2e951c02..35437c779da8 100644 --- a/include/net/vxlan.h +++ b/include/net/vxlan.h @@ -252,7 +252,9 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, (skb->inner_protocol_type != ENCAP_TYPE_ETHER || skb->inner_protocol != htons(ETH_P_TEB) || (skb_inner_mac_header(skb) - skb_transport_header(skb) != - sizeof(struct udphdr) + sizeof(struct vxlanhdr)))) + sizeof(struct udphdr) + sizeof(struct vxlanhdr)) || + (skb->ip_summed != CHECKSUM_NONE && + !can_checksum_protocol(features, inner_eth_hdr(skb)->h_proto)))) return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); return features; -- cgit v1.2.3 From eb192840266fab3e3da644018121eed30153355d Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Mon, 2 May 2016 11:24:51 -0700 Subject: RDS:TCP: Synchronize rds_tcp_accept_one with rds_send_xmit when resetting t_sock There is a race condition between rds_send_xmit -> rds_tcp_xmit and the code that deals with resolution of duelling syns added by commit 241b271952eb ("RDS-TCP: Reset tcp callbacks if re-using an outgoing socket in rds_tcp_accept_one()"). Specifically, we may end up derefencing a null pointer in rds_send_xmit if we have the interleaving sequence: rds_tcp_accept_one rds_send_xmit conn is RDS_CONN_UP, so invoke rds_tcp_xmit tc = conn->c_transport_data rds_tcp_restore_callbacks /* reset t_sock */ null ptr deref from tc->t_sock The race condition can be avoided without adding the overhead of additional locking in the xmit path: have rds_tcp_accept_one wait for rds_tcp_xmit threads to complete before resetting callbacks. The synchronization can be done in the same manner as rds_conn_shutdown(). First set the rds_conn_state to something other than RDS_CONN_UP (so that new threads cannot get into rds_tcp_xmit()), then wait for RDS_IN_XMIT to be cleared in the conn->c_flags indicating that any threads in rds_tcp_xmit are done. Fixes: 241b271952eb ("RDS-TCP: Reset tcp callbacks if re-using an outgoing socket in rds_tcp_accept_one()") Signed-off-by: Sowmini Varadhan Acked-by: Santosh Shilimkar Signed-off-by: David S. Miller --- net/rds/tcp.c | 2 +- net/rds/tcp_listen.c | 40 ++++++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 61ed2a8764ba..9134544941c2 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -127,7 +127,7 @@ void rds_tcp_restore_callbacks(struct socket *sock, /* * This is the only path that sets tc->t_sock. Send and receive trust that - * it is set. The RDS_CONN_CONNECTED bit protects those paths from being + * it is set. The RDS_CONN_UP bit protects those paths from being * called while it isn't set. */ void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn) diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 0936a4a32b47..0896187243d6 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c @@ -115,24 +115,32 @@ int rds_tcp_accept_one(struct socket *sock) * rds_tcp_state_change() will do that cleanup */ rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data; - if (rs_tcp->t_sock && - ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) { - struct sock *nsk = new_sock->sk; - - nsk->sk_user_data = NULL; - nsk->sk_prot->disconnect(nsk, 0); - tcp_done(nsk); - new_sock = NULL; - ret = 0; - goto out; - } else if (rs_tcp->t_sock) { - rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp); - conn->c_outgoing = 0; - } - rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING); + if (rs_tcp->t_sock) { + /* Need to resolve a duelling SYN between peers. + * We have an outstanding SYN to this peer, which may + * potentially have transitioned to the RDS_CONN_UP state, + * so we must quiesce any send threads before resetting + * c_transport_data. + */ + wait_event(conn->c_waitq, + !test_bit(RDS_IN_XMIT, &conn->c_flags)); + if (ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) { + struct sock *nsk = new_sock->sk; + + nsk->sk_user_data = NULL; + nsk->sk_prot->disconnect(nsk, 0); + tcp_done(nsk); + new_sock = NULL; + ret = 0; + goto out; + } else if (rs_tcp->t_sock) { + rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp); + conn->c_outgoing = 0; + } + } rds_tcp_set_callbacks(new_sock, conn); - rds_connect_complete(conn); + rds_connect_complete(conn); /* marks RDS_CONN_UP */ new_sock = NULL; ret = 0; -- cgit v1.2.3 From bd7c5f983f3185b75cc23bdd5dbc3a676aef3d1e Mon Sep 17 00:00:00 2001 From: Sowmini Varadhan Date: Mon, 2 May 2016 11:24:52 -0700 Subject: RDS: TCP: Synchronize accept() and connect() paths on t_conn_lock. An arbitration scheme for duelling SYNs is implemented as part of commit 241b271952eb ("RDS-TCP: Reset tcp callbacks if re-using an outgoing socket in rds_tcp_accept_one()") which ensures that both nodes involved will arrive at the same arbitration decision. However, this needs to be synchronized with an outgoing SYN to be generated by rds_tcp_conn_connect(). This commit achieves the synchronization through the t_conn_lock mutex in struct rds_tcp_connection. The rds_conn_state is checked in rds_tcp_conn_connect() after acquiring the t_conn_lock mutex. A SYN is sent out only if the RDS connection is not already UP (an UP would indicate that rds_tcp_accept_one() has completed 3WH, so no SYN needs to be generated). Similarly, the rds_conn_state is checked in rds_tcp_accept_one() after acquiring the t_conn_lock mutex. The only acceptable states (to allow continuation of the arbitration logic) are UP (i.e., outgoing SYN was SYN-ACKed by peer after it sent us the SYN) or CONNECTING (we sent outgoing SYN before we saw incoming SYN). Signed-off-by: Sowmini Varadhan Acked-by: Santosh Shilimkar Signed-off-by: David S. Miller --- net/rds/tcp.c | 1 + net/rds/tcp.h | 4 ++++ net/rds/tcp_connect.c | 8 ++++++++ net/rds/tcp_listen.c | 30 ++++++++++++++++++++---------- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 9134544941c2..86187dad1440 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -216,6 +216,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) if (!tc) return -ENOMEM; + mutex_init(&tc->t_conn_lock); tc->t_sock = NULL; tc->t_tinc = NULL; tc->t_tinc_hdr_rem = sizeof(struct rds_header); diff --git a/net/rds/tcp.h b/net/rds/tcp.h index 64f873c0c6b6..41c228300525 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h @@ -12,6 +12,10 @@ struct rds_tcp_connection { struct list_head t_tcp_node; struct rds_connection *conn; + /* t_conn_lock synchronizes the connection establishment between + * rds_tcp_accept_one and rds_tcp_conn_connect + */ + struct mutex t_conn_lock; struct socket *t_sock; void *t_orig_write_space; void *t_orig_data_ready; diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index 5cb16875c460..49a3fcfed360 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c @@ -78,7 +78,14 @@ int rds_tcp_conn_connect(struct rds_connection *conn) struct socket *sock = NULL; struct sockaddr_in src, dest; int ret; + struct rds_tcp_connection *tc = conn->c_transport_data; + + mutex_lock(&tc->t_conn_lock); + if (rds_conn_up(conn)) { + mutex_unlock(&tc->t_conn_lock); + return 0; + } ret = sock_create_kern(rds_conn_net(conn), PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); if (ret < 0) @@ -120,6 +127,7 @@ int rds_tcp_conn_connect(struct rds_connection *conn) } out: + mutex_unlock(&tc->t_conn_lock); if (sock) sock_release(sock); return ret; diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 0896187243d6..be263cdf268b 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c @@ -76,7 +76,9 @@ int rds_tcp_accept_one(struct socket *sock) struct rds_connection *conn; int ret; struct inet_sock *inet; - struct rds_tcp_connection *rs_tcp; + struct rds_tcp_connection *rs_tcp = NULL; + int conn_state; + struct sock *nsk; ret = sock_create_kern(sock_net(sock->sk), sock->sk->sk_family, sock->sk->sk_type, sock->sk->sk_protocol, @@ -116,6 +118,10 @@ int rds_tcp_accept_one(struct socket *sock) */ rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data; rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING); + mutex_lock(&rs_tcp->t_conn_lock); + conn_state = rds_conn_state(conn); + if (conn_state != RDS_CONN_CONNECTING && conn_state != RDS_CONN_UP) + goto rst_nsk; if (rs_tcp->t_sock) { /* Need to resolve a duelling SYN between peers. * We have an outstanding SYN to this peer, which may @@ -126,14 +132,7 @@ int rds_tcp_accept_one(struct socket *sock) wait_event(conn->c_waitq, !test_bit(RDS_IN_XMIT, &conn->c_flags)); if (ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) { - struct sock *nsk = new_sock->sk; - - nsk->sk_user_data = NULL; - nsk->sk_prot->disconnect(nsk, 0); - tcp_done(nsk); - new_sock = NULL; - ret = 0; - goto out; + goto rst_nsk; } else if (rs_tcp->t_sock) { rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp); conn->c_outgoing = 0; @@ -143,8 +142,19 @@ int rds_tcp_accept_one(struct socket *sock) rds_connect_complete(conn); /* marks RDS_CONN_UP */ new_sock = NULL; ret = 0; - + goto out; +rst_nsk: + /* reset the newly returned accept sock and bail */ + nsk = new_sock->sk; + rds_tcp_stats_inc(s_tcp_listen_closed_stale); + nsk->sk_user_data = NULL; + nsk->sk_prot->disconnect(nsk, 0); + tcp_done(nsk); + new_sock = NULL; + ret = 0; out: + if (rs_tcp) + mutex_unlock(&rs_tcp->t_conn_lock); if (new_sock) sock_release(new_sock); return ret; -- cgit v1.2.3 From cf6696608a069aaac10a253207deeb63dcd6a653 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 2 May 2016 18:38:45 -0700 Subject: net: macb: Probe MDIO bus before registering netdev The current sequence makes us register for a network device prior to registering and probing the MDIO bus which could lead to some unwanted consequences, like a thread of execution calling into ndo_open before register_netdev() returns, while the MDIO bus is not ready yet. Rework the sequence to register for the MDIO bus, and therefore attach to a PHY prior to calling register_netdev(), which implies reworking the error path a bit. Signed-off-by: Florian Fainelli Acked-by: Nicolas Ferre Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 898f06f9e286..a63551d0a18a 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -441,7 +441,7 @@ static int macb_mii_init(struct macb *bp) snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", bp->pdev->name, bp->pdev->id); bp->mii_bus->priv = bp; - bp->mii_bus->parent = &bp->dev->dev; + bp->mii_bus->parent = &bp->pdev->dev; pdata = dev_get_platdata(&bp->pdev->dev); dev_set_drvdata(&bp->dev->dev, bp->mii_bus); @@ -3020,29 +3020,36 @@ static int macb_probe(struct platform_device *pdev) if (err) goto err_out_free_netdev; + err = macb_mii_init(bp); + if (err) + goto err_out_free_netdev; + + phydev = bp->phy_dev; + + netif_carrier_off(dev); + err = register_netdev(dev); if (err) { dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); - goto err_out_unregister_netdev; + goto err_out_unregister_mdio; } - err = macb_mii_init(bp); - if (err) - goto err_out_unregister_netdev; - - netif_carrier_off(dev); + phy_attached_info(phydev); netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n", macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID), dev->base_addr, dev->irq, dev->dev_addr); - phydev = bp->phy_dev; - phy_attached_info(phydev); - return 0; -err_out_unregister_netdev: - unregister_netdev(dev); +err_out_unregister_mdio: + phy_disconnect(bp->phy_dev); + mdiobus_unregister(bp->mii_bus); + mdiobus_free(bp->mii_bus); + + /* Shutdown the PHY if there is a GPIO reset */ + if (bp->reset_gpio) + gpiod_set_value(bp->reset_gpio, 0); err_out_free_netdev: free_netdev(dev); -- cgit v1.2.3 From 79e8dc8b80bff0bc5bbb90ca5e73044bf207c8ac Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Tue, 3 May 2016 09:58:27 +0200 Subject: ipv6/ila: fix nlsize calculation for lwtunnel The handler 'ila_fill_encap_info' adds one attribute: ILA_ATTR_LOCATOR. Fixes: 65d7ab8de582 ("net: Identifier Locator Addressing module") CC: Tom Herbert Signed-off-by: Nicolas Dichtel Signed-off-by: David S. Miller --- net/ipv6/ila/ila_lwt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c index 2ae3c4fd8aab..41f18de5dcc2 100644 --- a/net/ipv6/ila/ila_lwt.c +++ b/net/ipv6/ila/ila_lwt.c @@ -120,8 +120,7 @@ nla_put_failure: static int ila_encap_nlsize(struct lwtunnel_state *lwtstate) { - /* No encapsulation overhead */ - return 0; + return nla_total_size(sizeof(u64)); /* ILA_ATTR_LOCATOR */ } static int ila_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b) -- cgit v1.2.3 From e8dfe6d8f6762d515fcd4f30577f7bfcf7659887 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 3 May 2016 20:29:39 +0100 Subject: MAINTAINERS: Remove asterisk from EFI directory names Mark reported that having asterisks on the end of directory names confuses get_maintainer.pl when it encounters subdirectories, and that my name does not appear when run on drivers/firmware/efi/libstub. Reported-by: Mark Rutland Signed-off-by: Matt Fleming Cc: Cc: Ard Biesheuvel Cc: Catalin Marinas Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1462303781-8686-2-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 42e65d128d01..4dca3b3895ba 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4223,8 +4223,8 @@ F: Documentation/efi-stub.txt F: arch/ia64/kernel/efi.c F: arch/x86/boot/compressed/eboot.[ch] F: arch/x86/include/asm/efi.h -F: arch/x86/platform/efi/* -F: drivers/firmware/efi/* +F: arch/x86/platform/efi/ +F: drivers/firmware/efi/ F: include/linux/efi*.h EFI VARIABLE FILESYSTEM -- cgit v1.2.3 From 7f9b474c92713067237c8188f32791cc4007b5da Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 3 May 2016 20:29:41 +0100 Subject: x86/efi-bgrt: Switch all pr_err() to pr_notice() for invalid BGRT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The promise of pretty boot splashes from firmware via BGRT was at best only that; a promise. The kernel diligently checks to make sure the BGRT data firmware gives it is valid, and dutifully warns the user when it isn't. However, it does so via the pr_err log level which seems unnecessary. The user cannot do anything about this and there really isn't an error on the part of Linux to correct. This lowers the log level by using pr_notice instead. Users will no longer have their boot process uglified by the kernel reminding us that firmware can and often is broken when the 'quiet' kernel parameter is specified. Ironic, considering BGRT is supposed to make boot pretty to begin with. Signed-off-by: Josh Boyer Signed-off-by: Matt Fleming Reviewed-by: Josh Triplett Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Môshe van der Sterre Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1462303781-8686-4-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/platform/efi/efi-bgrt.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c index a2433817c987..6a2f5691b1ab 100644 --- a/arch/x86/platform/efi/efi-bgrt.c +++ b/arch/x86/platform/efi/efi-bgrt.c @@ -43,40 +43,40 @@ void __init efi_bgrt_init(void) return; if (bgrt_tab->header.length < sizeof(*bgrt_tab)) { - pr_err("Ignoring BGRT: invalid length %u (expected %zu)\n", + pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n", bgrt_tab->header.length, sizeof(*bgrt_tab)); return; } if (bgrt_tab->version != 1) { - pr_err("Ignoring BGRT: invalid version %u (expected 1)\n", + pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n", bgrt_tab->version); return; } if (bgrt_tab->status & 0xfe) { - pr_err("Ignoring BGRT: reserved status bits are non-zero %u\n", + pr_notice("Ignoring BGRT: reserved status bits are non-zero %u\n", bgrt_tab->status); return; } if (bgrt_tab->image_type != 0) { - pr_err("Ignoring BGRT: invalid image type %u (expected 0)\n", + pr_notice("Ignoring BGRT: invalid image type %u (expected 0)\n", bgrt_tab->image_type); return; } if (!bgrt_tab->image_address) { - pr_err("Ignoring BGRT: null image address\n"); + pr_notice("Ignoring BGRT: null image address\n"); return; } image = memremap(bgrt_tab->image_address, sizeof(bmp_header), MEMREMAP_WB); if (!image) { - pr_err("Ignoring BGRT: failed to map image header memory\n"); + pr_notice("Ignoring BGRT: failed to map image header memory\n"); return; } memcpy(&bmp_header, image, sizeof(bmp_header)); memunmap(image); if (bmp_header.id != 0x4d42) { - pr_err("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n", + pr_notice("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n", bmp_header.id); return; } @@ -84,14 +84,14 @@ void __init efi_bgrt_init(void) bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN); if (!bgrt_image) { - pr_err("Ignoring BGRT: failed to allocate memory for image (wanted %zu bytes)\n", + pr_notice("Ignoring BGRT: failed to allocate memory for image (wanted %zu bytes)\n", bgrt_image_size); return; } image = memremap(bgrt_tab->image_address, bmp_header.size, MEMREMAP_WB); if (!image) { - pr_err("Ignoring BGRT: failed to map image memory\n"); + pr_notice("Ignoring BGRT: failed to map image memory\n"); kfree(bgrt_image); bgrt_image = NULL; return; -- cgit v1.2.3 From 140afdd9626cdaaf54223e82931213de785c7c94 Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Wed, 2 Mar 2016 19:18:12 -0800 Subject: iio: imu: mpu6050: fix possible NULL dereferences Fix possible null dereferencing of i2c and spi driver data. Signed-off-by: Matt Ranostay Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 3 ++- drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index f581256d9d4c..d0c0e20c7122 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -117,6 +117,7 @@ static int inv_mpu_probe(struct i2c_client *client, struct inv_mpu6050_state *st; int result; const char *name = id ? id->name : NULL; + const int chip_type = id ? id->driver_data : 0; struct regmap *regmap; if (!i2c_check_functionality(client->adapter, @@ -131,7 +132,7 @@ static int inv_mpu_probe(struct i2c_client *client, } result = inv_mpu_core_probe(regmap, client->irq, name, - NULL, id->driver_data); + NULL, chip_type); if (result < 0) return result; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c index dea6c4361de0..7bcb8d839f05 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c @@ -46,6 +46,7 @@ static int inv_mpu_probe(struct spi_device *spi) struct regmap *regmap; const struct spi_device_id *id = spi_get_device_id(spi); const char *name = id ? id->name : NULL; + const int chip_type = id ? id->driver_data : 0; regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config); if (IS_ERR(regmap)) { @@ -55,7 +56,7 @@ static int inv_mpu_probe(struct spi_device *spi) } return inv_mpu_core_probe(regmap, spi->irq, name, - inv_mpu_i2c_disable, id->driver_data); + inv_mpu_i2c_disable, chip_type); } static int inv_mpu_remove(struct spi_device *spi) -- cgit v1.2.3 From 393dbe4e18dd5b17b3952c7d36ac88f61ec40924 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Thu, 17 Mar 2016 18:32:44 +0200 Subject: iio: imu: mpu6050: Fix name/chip_id when using ACPI When using ACPI, id is NULL and the current code automatically defaults name to NULL and chip id to 0. We should instead use the data provided in the ACPI device table. Fixes: c816d9e7a57b ("iio: imu: mpu6050: fix possible NULL dereferences") Signed-off-by: Daniel Baluta Reviewed-By: Matt Ranostay Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index d0c0e20c7122..5ee4e0dc093e 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -104,6 +104,19 @@ static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap, return 0; } +static const char *inv_mpu_match_acpi_device(struct device *dev, int *chip_id) +{ + const struct acpi_device_id *id; + + id = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!id) + return NULL; + + *chip_id = (int)id->driver_data; + + return dev_name(dev); +} + /** * inv_mpu_probe() - probe function. * @client: i2c client. @@ -115,15 +128,25 @@ static int inv_mpu_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct inv_mpu6050_state *st; - int result; - const char *name = id ? id->name : NULL; - const int chip_type = id ? id->driver_data : 0; + int result, chip_type; struct regmap *regmap; + const char *name; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return -EOPNOTSUPP; + if (id) { + chip_type = (int)id->driver_data; + name = id->name; + } else if (ACPI_HANDLE(&client->dev)) { + name = inv_mpu_match_acpi_device(&client->dev, &chip_type); + if (!name) + return -ENODEV; + } else { + return -ENOSYS; + } + regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config); if (IS_ERR(regmap)) { dev_err(&client->dev, "Failed to register i2c regmap %d\n", -- cgit v1.2.3 From cf90ea934028375805e2d39c796eb276001574d7 Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Tue, 19 Apr 2016 17:42:43 -0400 Subject: ima: fix the string representation of the LSM/IMA hook enumeration ordering This patch fixes the string representation of the LSM/IMA hook enumeration ordering used for displaying the IMA policy. Fixes: d9ddf077bb85 ("ima: support for kexec image and initramfs") Signed-off-by: Mimi Zohar Tested-by: Eric Richter Signed-off-by: James Morris --- security/integrity/ima/ima_policy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index be09e2cacf82..3cd0a58672dd 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -884,10 +884,10 @@ static char *func_tokens[] = { "BPRM_CHECK", "MODULE_CHECK", "FIRMWARE_CHECK", + "POST_SETATTR", "KEXEC_KERNEL_CHECK", "KEXEC_INITRAMFS_CHECK", - "POLICY_CHECK", - "POST_SETATTR" + "POLICY_CHECK" }; void *ima_policy_start(struct seq_file *m, loff_t *pos) -- cgit v1.2.3 From 6d45b719cbd51f014bb1b5dd8ed99068d78d36af Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 4 May 2016 14:01:10 +0200 Subject: intel_pstate: Fix intel_pstate_get() After commit 8fa520af5081 "intel_pstate: Remove freq calculation from intel_pstate_calc_busy()" intel_pstate_get() calls get_avg_frequency() to compute the average frequency, which is problematic for two reasons. First, intel_pstate_get() may be invoked before the driver reads the CPU feedback registers for the first time and if that happens, get_avg_frequency() will attempt to divide by zero. Second, the get_avg_frequency() call in intel_pstate_get() is racy with respect to intel_pstate_sample() and it may end up returning completely meaningless values for this reason. Moreover, after commit 7349ec0470b6 "intel_pstate: Move intel_pstate_calc_busy() into get_target_pstate_use_performance()" sample.core_pct_busy is never computed on Atom, but it is used in intel_pstate_adjust_busy_pstate() in that case too. To address those problems notice that if sample.core_pct_busy was used in the average frequency computation carried out by get_avg_frequency(), both the divide by zero problem and the race with respect to intel_pstate_sample() would be avoided. Accordingly, move the invocation of intel_pstate_calc_busy() from get_target_pstate_use_performance() to intel_pstate_update_util(), which also will take care of the uninitialized sample.core_pct_busy on Atom, and modify get_avg_frequency() to use sample.core_pct_busy as per the above. Reported-by: kernel test robot Link: http://marc.info/?l=linux-kernel&m=146226437623173&w=4 Fixes: 8fa520af5081 "intel_pstate: Remove freq calculation from intel_pstate_calc_busy()" Fixes: 7349ec0470b6 "intel_pstate: Move intel_pstate_calc_busy() into get_target_pstate_use_performance()" Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 66f7f0071cab..b230ebaae66c 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1070,8 +1070,9 @@ static inline bool intel_pstate_sample(struct cpudata *cpu, u64 time) static inline int32_t get_avg_frequency(struct cpudata *cpu) { - return div64_u64(cpu->pstate.max_pstate_physical * cpu->sample.aperf * - cpu->pstate.scaling, cpu->sample.mperf); + return fp_toint(mul_fp(cpu->sample.core_pct_busy, + int_tofp(cpu->pstate.max_pstate_physical * + cpu->pstate.scaling / 100))); } static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu) @@ -1114,8 +1115,6 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu) int32_t core_busy, max_pstate, current_pstate, sample_ratio; u64 duration_ns; - intel_pstate_calc_busy(cpu); - /* * core_busy is the ratio of actual performance to max * max_pstate is the max non turbo pstate available @@ -1199,8 +1198,11 @@ static void intel_pstate_update_util(struct update_util_data *data, u64 time, if ((s64)delta_ns >= pid_params.sample_rate_ns) { bool sample_taken = intel_pstate_sample(cpu, time); - if (sample_taken && !hwp_active) - intel_pstate_adjust_busy_pstate(cpu); + if (sample_taken) { + intel_pstate_calc_busy(cpu); + if (!hwp_active) + intel_pstate_adjust_busy_pstate(cpu); + } } } -- cgit v1.2.3 From 27e0e6385377c4dc68a4ddaf1a35a2dfa951f3c5 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 4 May 2016 07:02:36 -0600 Subject: xen/evtchn: fix ring resize when binding new events The copying of ring data was wrong for two cases: For a full ring nothing got copied at all (as in that case the canonicalized producer and consumer indexes are identical). And in case one or both of the canonicalized (after the resize) indexes would point into the second half of the buffer, the copied data ended up in the wrong (free) part of the new buffer. In both cases uninitialized data would get passed back to the caller. Fix this by simply copying the old ring contents twice: Once to the low half of the new buffer, and a second time to the high half. This addresses the inability to boot a HVM guest with 64 or more vCPUs. This regression was caused by 8620015499101090 (xen/evtchn: dynamically grow pending event channel ring). Reported-by: Konrad Rzeszutek Wilk Signed-off-by: Jan Beulich Cc: # 4.4+ Signed-off-by: David Vrabel --- drivers/xen/evtchn.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index 38272ad24551..f4edd6df3df2 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -316,7 +316,6 @@ static int evtchn_resize_ring(struct per_user_data *u) { unsigned int new_size; evtchn_port_t *new_ring, *old_ring; - unsigned int p, c; /* * Ensure the ring is large enough to capture all possible @@ -346,20 +345,17 @@ static int evtchn_resize_ring(struct per_user_data *u) /* * Copy the old ring contents to the new ring. * - * If the ring contents crosses the end of the current ring, - * it needs to be copied in two chunks. + * To take care of wrapping, a full ring, and the new index + * pointing into the second half, simply copy the old contents + * twice. * * +---------+ +------------------+ - * |34567 12| -> | 1234567 | - * +-----p-c-+ +------------------+ + * |34567 12| -> |34567 1234567 12| + * +-----p-c-+ +-------c------p---+ */ - p = evtchn_ring_offset(u, u->ring_prod); - c = evtchn_ring_offset(u, u->ring_cons); - if (p < c) { - memcpy(new_ring + c, u->ring + c, (u->ring_size - c) * sizeof(*u->ring)); - memcpy(new_ring + u->ring_size, u->ring, p * sizeof(*u->ring)); - } else - memcpy(new_ring + c, u->ring + c, (p - c) * sizeof(*u->ring)); + memcpy(new_ring, old_ring, u->ring_size * sizeof(*u->ring)); + memcpy(new_ring + u->ring_size, old_ring, + u->ring_size * sizeof(*u->ring)); u->ring = new_ring; u->ring_size = new_size; -- cgit v1.2.3 From 93d68841a23a5779cef6fb9aa0ef32e7c5bd00da Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Wed, 4 May 2016 13:48:56 +0800 Subject: ACPICA: Dispatcher: Update thread ID for recursive method calls ACPICA commit 7a3bd2d962f221809f25ddb826c9e551b916eb25 Set the mutex owner thread ID. Original patch from: Prarit Bhargava Link: https://bugzilla.kernel.org/show_bug.cgi?id=115121 Link: https://github.com/acpica/acpica/commit/7a3bd2d9 Signed-off-by: Prarit Bhargava Tested-by: Andy Lutomirski # On a Dell XPS 13 9350 Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/dsmethod.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 1982310e6d83..da198b864107 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -428,6 +428,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, obj_desc->method.mutex->mutex. original_sync_level = obj_desc->method.mutex->mutex.sync_level; + + obj_desc->method.mutex->mutex.thread_id = + acpi_os_get_thread_id(); } } -- cgit v1.2.3 From 1f93e9f2318b598e6775a1fc9701604993c512b1 Mon Sep 17 00:00:00 2001 From: Yury Norov Date: Mon, 2 May 2016 19:12:47 +0300 Subject: asm-generic: use compat version for preadv2 and pwritev2 Compat architectures that does not use generic unistd (mips, s390), declare compat version in their syscall tables for preadv2 and pwritev2. Generic unistd syscall table should do it as well. [arnd: this initially slipped through the review and an incorrect patch got merged. arch/tile/ is the only architecture that could be affected for their 32-bit compat mode, every other architecture we support today is fine.] Signed-off-by: Yury Norov Signed-off-by: Arnd Bergmann --- include/uapi/asm-generic/unistd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 6e0f5f01734c..c51afb71bfab 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -718,9 +718,9 @@ __SYSCALL(__NR_mlock2, sys_mlock2) #define __NR_copy_file_range 285 __SYSCALL(__NR_copy_file_range, sys_copy_file_range) #define __NR_preadv2 286 -__SYSCALL(__NR_preadv2, sys_preadv2) +__SC_COMP(__NR_preadv2, sys_preadv2, compat_sys_preadv2) #define __NR_pwritev2 287 -__SYSCALL(__NR_pwritev2, sys_pwritev2) +__SC_COMP(__NR_pwritev2, sys_pwritev2, compat_sys_pwritev2) #undef __NR_syscalls #define __NR_syscalls 288 -- cgit v1.2.3 From 21f8a99ce61b2d4b74bd425a5bf7e9efbe162788 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 4 May 2016 18:49:55 +0530 Subject: PM / OPP: Remove useless check Regulators are optional for devices using OPPs and the OPP core shouldn't be printing any errors for such missing regulators. It was fine before the commit 0c717d0f9cb4, but that failed to update this part of the code to remove an 'always true' check and an extra unwanted print message. Fix that now. Fixes: 0c717d0f9cb4 (PM / OPP: Initialize regulator pointer to an error value) Reported-by: Marc Gonzalez Signed-off-by: Viresh Kumar Reviewed-by: Stephen Boyd Signed-off-by: Rafael J. Wysocki --- drivers/base/power/opp/core.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index 433b60092972..d8f4cc22856c 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -259,9 +259,6 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) reg = opp_table->regulator; if (IS_ERR(reg)) { /* Regulator may not be required for device */ - if (reg) - dev_err(dev, "%s: Invalid regulator (%ld)\n", __func__, - PTR_ERR(reg)); rcu_read_unlock(); return 0; } -- cgit v1.2.3 From 503fe87bd0a8346ba9d8b7f49115dcd0a4185226 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Apr 2016 10:17:51 +0200 Subject: gpu: ipu-v3: Fix imx-ipuv3-crtc module autoloading If of_node is set before calling platform_device_add, the driver core will try to use of: modalias matching, which fails because the device tree nodes don't have a compatible property set. This patch fixes imx-ipuv3-crtc module autoloading by setting the of_node property only after the platform modalias is set. Fixes: 304e6be652e2 ("gpu: ipu-v3: Assign of_node of child platform devices to corresponding ports") Reported-by: Dennis Gilmore Signed-off-by: Philipp Zabel Tested-By: Dennis Gilmore Cc: stable@vger.kernel.org # 4.4+ Signed-off-by: Dave Airlie --- drivers/gpu/ipu-v3/ipu-common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index e00db3f510dd..abb98c77bad2 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -1068,7 +1068,6 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) goto err_register; } - pdev->dev.of_node = of_node; pdev->dev.parent = dev; ret = platform_device_add_data(pdev, ®->pdata, @@ -1079,6 +1078,12 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) platform_device_put(pdev); goto err_register; } + + /* + * Set of_node only after calling platform_device_add. Otherwise + * the platform:imx-ipuv3-crtc modalias won't be used. + */ + pdev->dev.of_node = of_node; } return 0; -- cgit v1.2.3 From cba1b3798e2c4c094f2079a0d4c1ba4ec2c5a9ac Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 29 Apr 2016 17:55:48 -0700 Subject: perf/x86: Add model numbers for Kabylake CPUs Everything the same as Skylake, just new model numbers. Signed-off-by: Andi Kleen Signed-off-by: Peter Zijlstra (Intel) Link: http://lkml.kernel.org/r/1461977748-17616-1-git-send-email-andi@firstfloor.org Signed-off-by: Ingo Molnar --- arch/x86/events/intel/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index aff79884e17d..a6fd4dbcf820 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3637,6 +3637,8 @@ __init int intel_pmu_init(void) pr_cont("Knights Landing events, "); break; + case 142: /* 14nm Kabylake Mobile */ + case 158: /* 14nm Kabylake Desktop */ case 78: /* 14nm Skylake Mobile */ case 94: /* 14nm Skylake Desktop */ case 85: /* 14nm Skylake Server */ -- cgit v1.2.3 From 08914f436bdd2ed60923f49cbc402307aba20fe4 Mon Sep 17 00:00:00 2001 From: Alex Thorlton Date: Wed, 4 May 2016 17:39:52 -0500 Subject: x86/platform/UV: Bring back the call to map_low_mmrs in uv_system_init A while back the following commit: d394f2d9d8e1 ("x86/platform/UV: Remove EFI memmap quirk for UV2+") changed uv_system_init() to only call map_low_mmrs() on older UV1 hardware, which requires EFI_OLD_MEMMAP to be set in order to boot. The recent changes to the EFI memory mapping code in: d2f7cbe7b26a ("x86/efi: Runtime services virtual mapping") exposed some issues with the fact that we were relying on the EFI memory mapping mechanisms to map in our MMRs for us, after commit d394f2d9d8e1. Rather than revert the entire commit and go back to forcing EFI_OLD_MEMMAP on all UVs, we're going to add the call to map_low_mmrs() back into uv_system_init(), and then fix up our EFI runtime calls to use the appropriate page table. For now, UV2+ will still need efi=old_map to boot, but there will be other changes soon that should eliminate the need for this. Signed-off-by: Alex Thorlton Cc: Matt Fleming Cc: Adam Buchbinder Cc: Len Brown Cc: Borislav Petkov Cc: Russ Anderson Cc: Dimitri Sivanich Link: http://lkml.kernel.org/r/1462401592-120735-1-git-send-email-athorlton@sgi.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/x2apic_uv_x.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 8f4942e2bcbb..d7ce96a7daca 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -891,9 +891,7 @@ void __init uv_system_init(void) } pr_info("UV: Found %s hub\n", hub); - /* We now only need to map the MMRs on UV1 */ - if (is_uv1_hub()) - map_low_mmrs(); + map_low_mmrs(); m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); m_val = m_n_config.s.m_skt; -- cgit v1.2.3 From 8482716b9d865db34c55d4bf2fed19498e7195b9 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 24 Apr 2016 00:42:55 +0200 Subject: perf/x86/amd/iommu: Do not register a task ctx for uncore like PMUs The new sanity check introduced by: 26657848502b ("perf/core: Verify we have a single perf_hw_context PMU") ... triggered on the AMD IOMMU driver. IOMMUs are not per logical CPU, they cannot have per-task counters. Fix it. Reported-by: Borislav Petkov Tested-by: Borislav Petkov Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: jroedel@suse.de Cc: suravee.suthikulpanit@amd.com Link: http://lkml.kernel.org/r/20160423224255.GB3430@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar --- arch/x86/events/amd/iommu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c index 40625ca7a190..6011a573dd64 100644 --- a/arch/x86/events/amd/iommu.c +++ b/arch/x86/events/amd/iommu.c @@ -474,6 +474,7 @@ static __init int _init_perf_amd_iommu( static struct perf_amd_iommu __perf_iommu = { .pmu = { + .task_ctx_nr = perf_invalid_context, .event_init = perf_iommu_event_init, .add = perf_iommu_add, .del = perf_iommu_del, -- cgit v1.2.3 From b34ecd5aa34800aefa9e2990a805243ec9348437 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 5 May 2016 08:01:34 -0300 Subject: [media] media-device: fix builds when USB or PCI is compiled as module Just checking ifdef CONFIG_USB is not enough, if the USB is compiled as module. The same applies to PCI. Tested with the following .config alternatives: CONFIG_USB=m CONFIG_MEDIA_CONTROLLER=y CONFIG_MEDIA_SUPPORT=m CONFIG_VIDEO_AU0828=m CONFIG_USB=m CONFIG_MEDIA_CONTROLLER=y CONFIG_MEDIA_SUPPORT=y CONFIG_VIDEO_AU0828=m CONFIG_USB=y CONFIG_MEDIA_CONTROLLER=y CONFIG_MEDIA_SUPPORT=y CONFIG_VIDEO_AU0828=m CONFIG_USB=y CONFIG_MEDIA_CONTROLLER=y CONFIG_MEDIA_SUPPORT=y CONFIG_VIDEO_AU0828=y Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 6e43c95629ea..3cfd7af8c5ca 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -846,11 +846,11 @@ struct media_device *media_device_find_devres(struct device *dev) } EXPORT_SYMBOL_GPL(media_device_find_devres); +#if IS_ENABLED(CONFIG_PCI) void media_device_pci_init(struct media_device *mdev, struct pci_dev *pci_dev, const char *name) { -#ifdef CONFIG_PCI mdev->dev = &pci_dev->dev; if (name) @@ -866,16 +866,16 @@ void media_device_pci_init(struct media_device *mdev, mdev->driver_version = LINUX_VERSION_CODE; media_device_init(mdev); -#endif } EXPORT_SYMBOL_GPL(media_device_pci_init); +#endif +#if IS_ENABLED(CONFIG_USB) void __media_device_usb_init(struct media_device *mdev, struct usb_device *udev, const char *board_name, const char *driver_name) { -#ifdef CONFIG_USB mdev->dev = &udev->dev; if (driver_name) @@ -895,9 +895,9 @@ void __media_device_usb_init(struct media_device *mdev, mdev->driver_version = LINUX_VERSION_CODE; media_device_init(mdev); -#endif } EXPORT_SYMBOL_GPL(__media_device_usb_init); +#endif #endif /* CONFIG_MEDIA_CONTROLLER */ -- cgit v1.2.3 From e5bc0478ab6cf565619224536d75ecb2aedca43b Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 5 May 2016 13:32:34 +0530 Subject: ARC: Add missing io barriers to io{read,write}{16,32}be() While reviewing a different change to asm-generic/io.h Arnd spotted that ARC ioread32 and ioread32be both of which come from asm-generic versions are not symmetrical in terms of calling the io barriers. generic ioread32 -> ARC readl() [ has barriers] generic ioread32be -> __be32_to_cpu(__raw_readl()) [ lacks barriers] While generic ioread32be is being remediated to call readl(), that involves a swab32(), causing double swaps on ioread32be() on Big Endian systems. So provide our versions of big endian IO accessors to ensure io barrier calls while also keeping them optimal Suggested-by: Arnd Bergmann Acked-by: Arnd Bergmann Cc: stable@vger.kernel.org [4.2+] Signed-off-by: Vineet Gupta --- arch/arc/include/asm/io.h | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h index 17f85c9c73cf..c22b181e8206 100644 --- a/arch/arc/include/asm/io.h +++ b/arch/arc/include/asm/io.h @@ -13,6 +13,15 @@ #include #include +#ifdef CONFIG_ISA_ARCV2 +#include +#define __iormb() rmb() +#define __iowmb() wmb() +#else +#define __iormb() do { } while (0) +#define __iowmb() do { } while (0) +#endif + extern void __iomem *ioremap(phys_addr_t paddr, unsigned long size); extern void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, unsigned long flags); @@ -31,6 +40,15 @@ extern void iounmap(const void __iomem *addr); #define ioremap_wc(phy, sz) ioremap(phy, sz) #define ioremap_wt(phy, sz) ioremap(phy, sz) +/* + * io{read,write}{16,32}be() macros + */ +#define ioread16be(p) ({ u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; }) +#define ioread32be(p) ({ u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; }) + +#define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force u16)cpu_to_be16(v), p); }) +#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force u32)cpu_to_be32(v), p); }) + /* Change struct page to physical address */ #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) @@ -108,15 +126,6 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr) } -#ifdef CONFIG_ISA_ARCV2 -#include -#define __iormb() rmb() -#define __iowmb() wmb() -#else -#define __iormb() do { } while (0) -#define __iowmb() do { } while (0) -#endif - /* * MMIO can also get buffered/optimized in micro-arch, so barriers needed * Based on ARM model for the typical use case -- cgit v1.2.3 From 2519d753676bdf2460fbbcde276d5b6ba8d6b695 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 5 May 2016 14:53:48 +0530 Subject: ARC: Fix PAE40 boot failures due to PTE truncation So a benign looking cleanup which macro'ized PAGE_SHIFT shifts turned out to be bad (since it was done non-sensically across the board). It caused boot failures with PAE40 as forced cast to (unsigned long) from newly introduced virt_to_pfn() was causing truncatiion of the (long long) pte/paddr values. It is OK to use this in accessors dealing with kernel virtual address, pointers etc, but not for PTE values themelves. Fixes: cJ2ff5cf2735c ("ARC: mm: Use virt_to_pfn() for addr >> PAGE_SHIFT pattern) Signed-off-by: Vineet Gupta --- arch/arc/include/asm/page.h | 9 ++++++++- arch/arc/include/asm/pgtable.h | 13 ++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 36da89e2c853..533e5a0c6ba5 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -72,6 +72,13 @@ typedef unsigned long pgprot_t; typedef pte_t * pgtable_t; +/* + * Use virt_to_pfn with caution: + * If used in pte or paddr related macros, it could cause truncation + * in PAE40 builds + * As a rule of thumb, only use it in helpers starting with virt_ + * You have been warned ! + */ #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) #define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_LINK_BASE) @@ -85,7 +92,7 @@ typedef pte_t * pgtable_t; * virt here means link-address/program-address as embedded in object code. * And for ARC, link-addr = physical address */ -#define __pa(vaddr) ((unsigned long)vaddr) +#define __pa(vaddr) ((unsigned long)(vaddr)) #define __va(paddr) ((void *)((unsigned long)(paddr))) #define virt_to_page(kaddr) \ diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index 7d6c93e63adf..10d4b8b8e545 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h @@ -278,14 +278,13 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) #define pmd_present(x) (pmd_val(x)) #define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0) -#define pte_page(pte) \ - (mem_map + virt_to_pfn(pte_val(pte) - CONFIG_LINUX_LINK_BASE)) - +#define pte_page(pte) pfn_to_page(pte_pfn(pte)) #define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot) -#define pte_pfn(pte) virt_to_pfn(pte_val(pte)) -#define pfn_pte(pfn, prot) (__pte(((pte_t)(pfn) << PAGE_SHIFT) | \ - pgprot_val(prot))) -#define __pte_index(addr) (virt_to_pfn(addr) & (PTRS_PER_PTE - 1)) +#define pfn_pte(pfn, prot) (__pte(((pte_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))) + +/* Don't use virt_to_pfn for macros below: could cause truncations for PAE40*/ +#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) +#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) /* * pte_offset gets a @ptr to PMD entry (PGD in our 2-tier paging system) -- cgit v1.2.3 From 26f9d5fd82ca20fe536cb493ec7cf5628f8997e5 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Mon, 18 Apr 2016 10:49:56 +0530 Subject: ARC: support HIGHMEM even without PAE40 Initial HIGHMEM support on ARC was introduced for PAE40 where the low memory (0x8000_0000 based) and high memory (0x1_0000_0000) were physically contiguous. So CONFIG_FLATMEM sufficed (despite a peipheral hole in the middle, which wasted a bit of struct page memory, but things worked). However w/o PAE, highmem was not possible and we could only reach ~1.75GB of DDR. Now there is a use case to access ~4GB of DDR w/o PAE40 The idea is to have low memory at canonical 0x8000_0000 and highmem at 0 so enire 4GB address space is available for physical addressing This needs additional platform/interconnect mapping to convert the non contiguous physical addresses into linear bus adresses. From Linux point of view, non contiguous divide means FLATMEM no longer works and DISCONTIGMEM is needed to track the pfns in the 2 regions. This scheme would also work for PAE40, only better in that we don't waste struct page memory for the peripheral hole. The DT description will be something like memory { ... reg = <0x80000000 0x200000000 /* 512MB: lowmem */ 0x00000000 0x10000000>; /* 256MB: highmem */ } Signed-off-by: Noam Camus Signed-off-by: Vineet Gupta --- arch/arc/Kconfig | 13 +++++++++++ arch/arc/include/asm/mmzone.h | 43 ++++++++++++++++++++++++++++++++++ arch/arc/include/asm/page.h | 6 ++--- arch/arc/mm/init.c | 54 +++++++++++++++++++++++++++++++------------ 4 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 arch/arc/include/asm/mmzone.h diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index ec4791ea6911..a8767430df7d 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -58,6 +58,9 @@ config GENERIC_CSUM config RWSEM_GENERIC_SPINLOCK def_bool y +config ARCH_DISCONTIGMEM_ENABLE + def_bool y + config ARCH_FLATMEM_ENABLE def_bool y @@ -347,6 +350,15 @@ config ARC_HUGEPAGE_16M endchoice +config NODES_SHIFT + int "Maximum NUMA Nodes (as a power of 2)" + default "1" if !DISCONTIGMEM + default "2" if DISCONTIGMEM + depends on NEED_MULTIPLE_NODES + ---help--- + Accessing memory beyond 1GB (with or w/o PAE) requires 2 memory + zones. + if ISA_ARCOMPACT config ARC_COMPACT_IRQ_LEVELS @@ -455,6 +467,7 @@ config LINUX_LINK_BASE config HIGHMEM bool "High Memory Support" + select DISCONTIGMEM help With ARC 2G:2G address split, only upper 2G is directly addressable by kernel. Enable this to potentially allow access to rest of 2G and PAE diff --git a/arch/arc/include/asm/mmzone.h b/arch/arc/include/asm/mmzone.h new file mode 100644 index 000000000000..8e97136413d9 --- /dev/null +++ b/arch/arc/include/asm/mmzone.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _ASM_ARC_MMZONE_H +#define _ASM_ARC_MMZONE_H + +#ifdef CONFIG_DISCONTIGMEM + +extern struct pglist_data node_data[]; +#define NODE_DATA(nid) (&node_data[nid]) + +static inline int pfn_to_nid(unsigned long pfn) +{ + int is_end_low = 1; + + if (IS_ENABLED(CONFIG_ARC_HAS_PAE40)) + is_end_low = pfn <= virt_to_pfn(0xFFFFFFFFUL); + + /* + * node 0: lowmem: 0x8000_0000 to 0xFFFF_FFFF + * node 1: HIGHMEM w/o PAE40: 0x0 to 0x7FFF_FFFF + * HIGHMEM with PAE40: 0x1_0000_0000 to ... + */ + if (pfn >= ARCH_PFN_OFFSET && is_end_low) + return 0; + + return 1; +} + +static inline int pfn_valid(unsigned long pfn) +{ + int nid = pfn_to_nid(pfn); + + return (pfn <= node_end_pfn(nid)); +} +#endif /* CONFIG_DISCONTIGMEM */ + +#endif diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 533e5a0c6ba5..0d53854884d0 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -83,7 +83,9 @@ typedef pte_t * pgtable_t; #define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_LINK_BASE) +#ifdef CONFIG_FLATMEM #define pfn_valid(pfn) (((pfn) - ARCH_PFN_OFFSET) < max_mapnr) +#endif /* * __pa, __va, virt_to_page (ALERT: deprecated, don't use them) @@ -95,9 +97,7 @@ typedef pte_t * pgtable_t; #define __pa(vaddr) ((unsigned long)(vaddr)) #define __va(paddr) ((void *)((unsigned long)(paddr))) -#define virt_to_page(kaddr) \ - (mem_map + virt_to_pfn((kaddr) - CONFIG_LINUX_LINK_BASE)) - +#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) #define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr)) /* Default Permissions for stack/heaps pages (Non Executable) */ diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c index 5487d0b97400..8be930394750 100644 --- a/arch/arc/mm/init.c +++ b/arch/arc/mm/init.c @@ -30,11 +30,16 @@ static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE; static unsigned long low_mem_sz; #ifdef CONFIG_HIGHMEM -static unsigned long min_high_pfn; +static unsigned long min_high_pfn, max_high_pfn; static u64 high_mem_start; static u64 high_mem_sz; #endif +#ifdef CONFIG_DISCONTIGMEM +struct pglist_data node_data[MAX_NUMNODES] __read_mostly; +EXPORT_SYMBOL(node_data); +#endif + /* User can over-ride above with "mem=nnn[KkMm]" in cmdline */ static int __init setup_mem_sz(char *str) { @@ -109,13 +114,11 @@ void __init setup_arch_memory(void) /* Last usable page of low mem */ max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz); -#ifdef CONFIG_HIGHMEM - min_high_pfn = PFN_DOWN(high_mem_start); - max_pfn = PFN_DOWN(high_mem_start + high_mem_sz); +#ifdef CONFIG_FLATMEM + /* pfn_valid() uses this */ + max_mapnr = max_low_pfn - min_low_pfn; #endif - max_mapnr = max_pfn - min_low_pfn; - /*------------- bootmem allocator setup -----------------------*/ /* @@ -129,7 +132,7 @@ void __init setup_arch_memory(void) * the crash */ - memblock_add(low_mem_start, low_mem_sz); + memblock_add_node(low_mem_start, low_mem_sz, 0); memblock_reserve(low_mem_start, __pa(_end) - low_mem_start); #ifdef CONFIG_BLK_DEV_INITRD @@ -149,13 +152,6 @@ void __init setup_arch_memory(void) zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn; zones_holes[ZONE_NORMAL] = 0; -#ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn; - - /* This handles the peripheral address space hole */ - zones_holes[ZONE_HIGHMEM] = min_high_pfn - max_low_pfn; -#endif - /* * We can't use the helper free_area_init(zones[]) because it uses * PAGE_OFFSET to compute the @min_low_pfn which would be wrong @@ -168,6 +164,34 @@ void __init setup_arch_memory(void) zones_holes); /* holes */ #ifdef CONFIG_HIGHMEM + /* + * Populate a new node with highmem + * + * On ARC (w/o PAE) HIGHMEM addresses are actually smaller (0 based) + * than addresses in normal ala low memory (0x8000_0000 based). + * Even with PAE, the huge peripheral space hole would waste a lot of + * mem with single mem_map[]. This warrants a mem_map per region design. + * Thus HIGHMEM on ARC is imlemented with DISCONTIGMEM. + * + * DISCONTIGMEM in turns requires multiple nodes. node 0 above is + * populated with normal memory zone while node 1 only has highmem + */ + node_set_online(1); + + min_high_pfn = PFN_DOWN(high_mem_start); + max_high_pfn = PFN_DOWN(high_mem_start + high_mem_sz); + + zones_size[ZONE_NORMAL] = 0; + zones_holes[ZONE_NORMAL] = 0; + + zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn; + zones_holes[ZONE_HIGHMEM] = 0; + + free_area_init_node(1, /* node-id */ + zones_size, /* num pages per zone */ + min_high_pfn, /* first pfn of node */ + zones_holes); /* holes */ + high_memory = (void *)(min_high_pfn << PAGE_SHIFT); kmap_init(); #endif @@ -185,7 +209,7 @@ void __init mem_init(void) unsigned long tmp; reset_all_zones_managed_pages(); - for (tmp = min_high_pfn; tmp < max_pfn; tmp++) + for (tmp = min_high_pfn; tmp < max_high_pfn; tmp++) free_highmem_page(pfn_to_page(tmp)); #endif -- cgit v1.2.3 From c10fcb14c7afd6688c7b197a814358fecf244222 Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Thu, 5 May 2016 14:14:21 +0100 Subject: x86/sysfb_efi: Fix valid BAR address range check The code for checking whether a BAR address range is valid will break out of the loop when a start address of 0x0 is encountered. This behaviour is wrong since by breaking out of the loop we may miss the BAR that describes the EFI frame buffer in a later iteration. Because of this bug I can't use video=efifb: boot parameter to get efifb on my new ThinkPad E550 for my old linux system hard disk with 3.10 kernel. In 3.10, efifb is the only choice due to DRM/I915 not supporting the GPU. This patch also add a trivial optimization to break out after we find the frame buffer address range without testing later BARs. Signed-off-by: Wang YanQing [ Rewrote changelog. ] Signed-off-by: Matt Fleming Reviewed-by: Peter Jones Cc: Cc: Ard Biesheuvel Cc: David Herrmann Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tomi Valkeinen Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1462454061-21561-2-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/kernel/sysfb_efi.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/sysfb_efi.c b/arch/x86/kernel/sysfb_efi.c index b285d4e8c68e..5da924bbf0a0 100644 --- a/arch/x86/kernel/sysfb_efi.c +++ b/arch/x86/kernel/sysfb_efi.c @@ -106,14 +106,24 @@ static int __init efifb_set_system(const struct dmi_system_id *id) continue; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { resource_size_t start, end; + unsigned long flags; + + flags = pci_resource_flags(dev, i); + if (!(flags & IORESOURCE_MEM)) + continue; + + if (flags & IORESOURCE_UNSET) + continue; + + if (pci_resource_len(dev, i) == 0) + continue; start = pci_resource_start(dev, i); - if (start == 0) - break; end = pci_resource_end(dev, i); if (screen_info.lfb_base >= start && screen_info.lfb_base < end) { found_bar = 1; + break; } } } -- cgit v1.2.3 From 5ec0811d30378ae104f250bfc9b3640242d81e3f Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 5 May 2016 09:29:29 -0500 Subject: propogate_mnt: Handle the first propogated copy being a slave When the first propgated copy was a slave the following oops would result: > BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 > IP: [] propagate_one+0xbe/0x1c0 > PGD bacd4067 PUD bac66067 PMD 0 > Oops: 0000 [#1] SMP > Modules linked in: > CPU: 1 PID: 824 Comm: mount Not tainted 4.6.0-rc5userns+ #1523 > Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 > task: ffff8800bb0a8000 ti: ffff8800bac3c000 task.ti: ffff8800bac3c000 > RIP: 0010:[] [] propagate_one+0xbe/0x1c0 > RSP: 0018:ffff8800bac3fd38 EFLAGS: 00010283 > RAX: 0000000000000000 RBX: ffff8800bb77ec00 RCX: 0000000000000010 > RDX: 0000000000000000 RSI: ffff8800bb58c000 RDI: ffff8800bb58c480 > RBP: ffff8800bac3fd48 R08: 0000000000000001 R09: 0000000000000000 > R10: 0000000000001ca1 R11: 0000000000001c9d R12: 0000000000000000 > R13: ffff8800ba713800 R14: ffff8800bac3fda0 R15: ffff8800bb77ec00 > FS: 00007f3c0cd9b7e0(0000) GS:ffff8800bfb00000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 0000000000000010 CR3: 00000000bb79d000 CR4: 00000000000006e0 > Stack: > ffff8800bb77ec00 0000000000000000 ffff8800bac3fd88 ffffffff811fbf85 > ffff8800bac3fd98 ffff8800bb77f080 ffff8800ba713800 ffff8800bb262b40 > 0000000000000000 0000000000000000 ffff8800bac3fdd8 ffffffff811f1da0 > Call Trace: > [] propagate_mnt+0x105/0x140 > [] attach_recursive_mnt+0x120/0x1e0 > [] graft_tree+0x63/0x70 > [] do_add_mount+0x9b/0x100 > [] do_mount+0x2aa/0xdf0 > [] ? strndup_user+0x4e/0x70 > [] SyS_mount+0x75/0xc0 > [] do_syscall_64+0x4b/0xa0 > [] entry_SYSCALL64_slow_path+0x25/0x25 > Code: 00 00 75 ec 48 89 0d 02 22 22 01 8b 89 10 01 00 00 48 89 05 fd 21 22 01 39 8e 10 01 00 00 0f 84 e0 00 00 00 48 8b 80 d8 00 00 00 <48> 8b 50 10 48 89 05 df 21 22 01 48 89 15 d0 21 22 01 8b 53 30 > RIP [] propagate_one+0xbe/0x1c0 > RSP > CR2: 0000000000000010 > ---[ end trace 2725ecd95164f217 ]--- This oops happens with the namespace_sem held and can be triggered by non-root users. An all around not pleasant experience. To avoid this scenario when finding the appropriate source mount to copy stop the walk up the mnt_master chain when the first source mount is encountered. Further rewrite the walk up the last_source mnt_master chain so that it is clear what is going on. The reason why the first source mount is special is that it it's mnt_parent is not a mount in the dest_mnt propagation tree, and as such termination conditions based up on the dest_mnt mount propgation tree do not make sense. To avoid other kinds of confusion last_dest is not changed when computing last_source. last_dest is only used once in propagate_one and that is above the point of the code being modified, so changing the global variable is meaningless and confusing. Cc: stable@vger.kernel.org fixes: f2ebb3a921c1ca1e2ddd9242e95a1989a50c4c68 ("smarter propagate_mnt()") Reported-by: Tycho Andersen Reviewed-by: Seth Forshee Tested-by: Seth Forshee Signed-off-by: "Eric W. Biederman" --- fs/pnode.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/fs/pnode.c b/fs/pnode.c index c524fdddc7fb..99899705b105 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -198,7 +198,7 @@ static struct mount *next_group(struct mount *m, struct mount *origin) /* all accesses are serialized by namespace_sem */ static struct user_namespace *user_ns; -static struct mount *last_dest, *last_source, *dest_master; +static struct mount *last_dest, *first_source, *last_source, *dest_master; static struct mountpoint *mp; static struct hlist_head *list; @@ -221,20 +221,22 @@ static int propagate_one(struct mount *m) type = CL_MAKE_SHARED; } else { struct mount *n, *p; + bool done; for (n = m; ; n = p) { p = n->mnt_master; - if (p == dest_master || IS_MNT_MARKED(p)) { - while (last_dest->mnt_master != p) { - last_source = last_source->mnt_master; - last_dest = last_source->mnt_parent; - } - if (!peers(n, last_dest)) { - last_source = last_source->mnt_master; - last_dest = last_source->mnt_parent; - } + if (p == dest_master || IS_MNT_MARKED(p)) break; - } } + do { + struct mount *parent = last_source->mnt_parent; + if (last_source == first_source) + break; + done = parent->mnt_master == p; + if (done && peers(n, parent)) + break; + last_source = last_source->mnt_master; + } while (!done); + type = CL_SLAVE; /* beginning of peer group among the slaves? */ if (IS_MNT_SHARED(m)) @@ -286,6 +288,7 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp, */ user_ns = current->nsproxy->mnt_ns->user_ns; last_dest = dest_mnt; + first_source = source_mnt; last_source = source_mnt; mp = dest_mp; list = tree_list; -- cgit v1.2.3 From 9c674815d346305068b27bf03b5e86b659a1b111 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 18 Apr 2016 17:06:28 -0400 Subject: IB/iser: Fix max_sectors calculation iSER currently has a couple places that set max_sectors in either the host template or SCSI host, and all of them get it wrong. This patch instead uses a single assignment that (hopefully) gets it right: the max_sectors value must be derived from the number of segments in the FR or FMR structure, but actually be one lower than the page size multiplied by the number of sectors, as it has to handle the case of non-aligned I/O. Without this I get trivial to reproduce hangs when running xfstests (on XFS) over iSER to Linux targets. Signed-off-by: Christoph Hellwig Reviewed-by: Max Gurtovoy Acked-by: Sagi Grimberg Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/iser/iscsi_iser.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 80b6bedc172f..64b3d11dcf1e 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -612,6 +612,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, struct Scsi_Host *shost; struct iser_conn *iser_conn = NULL; struct ib_conn *ib_conn; + u32 max_fr_sectors; u16 max_cmds; shost = iscsi_host_alloc(&iscsi_iser_sht, 0, 0); @@ -632,7 +633,6 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, iser_conn = ep->dd_data; max_cmds = iser_conn->max_cmds; shost->sg_tablesize = iser_conn->scsi_sg_tablesize; - shost->max_sectors = iser_conn->scsi_max_sectors; mutex_lock(&iser_conn->state_mutex); if (iser_conn->state != ISER_CONN_UP) { @@ -657,8 +657,6 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, */ shost->sg_tablesize = min_t(unsigned short, shost->sg_tablesize, ib_conn->device->ib_device->attrs.max_fast_reg_page_list_len); - shost->max_sectors = min_t(unsigned int, - 1024, (shost->sg_tablesize * PAGE_SIZE) >> 9); if (iscsi_host_add(shost, ib_conn->device->ib_device->dma_device)) { @@ -672,6 +670,15 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep, goto free_host; } + /* + * FRs or FMRs can only map up to a (device) page per entry, but if the + * first entry is misaligned we'll end up using using two entries + * (head and tail) for a single page worth data, so we have to drop + * one segment from the calculation. + */ + max_fr_sectors = ((shost->sg_tablesize - 1) * PAGE_SIZE) >> 9; + shost->max_sectors = min(iser_max_sectors, max_fr_sectors); + if (cmds_max > max_cmds) { iser_info("cmds_max changed from %u to %u\n", cmds_max, max_cmds); @@ -989,7 +996,6 @@ static struct scsi_host_template iscsi_iser_sht = { .queuecommand = iscsi_queuecommand, .change_queue_depth = scsi_change_queue_depth, .sg_tablesize = ISCSI_ISER_DEF_SG_TABLESIZE, - .max_sectors = ISER_DEF_MAX_SECTORS, .cmd_per_lun = ISER_DEF_CMD_PER_LUN, .eh_abort_handler = iscsi_eh_abort, .eh_device_reset_handler= iscsi_eh_device_reset, -- cgit v1.2.3 From 695665b0c5237bee8a3d0099ea856282d5d8f25b Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Wed, 4 May 2016 10:37:22 +0100 Subject: ARM: 8571/1: nommu: fix PMSAv7 setup Commit 1c2f87c (ARM: 8025/1: Get rid of meminfo) broke the support for MPU on ARMv7-R. This patch adapts the code inside CONFIG_ARM_MPU to use memblocks appropriately. MPU initialisation only uses the first memory region, and removes all subsequent ones. Because looping over all regions that need removal is inefficient, and memblock_remove already handles memory ranges, we can flatten the 'for_each_memblock' part. Signed-off-by: Jean-Philippe Brucker Signed-off-by: Vladimir Murzin Signed-off-by: Russell King --- arch/arm/mm/nommu.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 1dd10936d68d..4d113fcceb4a 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -87,7 +87,6 @@ static unsigned long irbar_read(void) /* MPU initialisation functions */ void __init sanity_check_meminfo_mpu(void) { - int i; phys_addr_t phys_offset = PHYS_OFFSET; phys_addr_t aligned_region_size, specified_mem_size, rounded_mem_size; struct memblock_region *reg; @@ -110,11 +109,13 @@ void __init sanity_check_meminfo_mpu(void) } else { /* * memblock auto merges contiguous blocks, remove - * all blocks afterwards + * all blocks afterwards in one go (we can't remove + * blocks separately while iterating) */ pr_notice("Ignoring RAM after %pa, memory at %pa ignored\n", - &mem_start, ®->base); - memblock_remove(reg->base, reg->size); + &mem_end, ®->base); + memblock_remove(reg->base, 0 - reg->base); + break; } } @@ -144,7 +145,7 @@ void __init sanity_check_meminfo_mpu(void) pr_warn("Truncating memory from %pa to %pa (MPU region constraints)", &specified_mem_size, &aligned_region_size); memblock_remove(mem_start + aligned_region_size, - specified_mem_size - aligned_round_size); + specified_mem_size - aligned_region_size); mem_end = mem_start + aligned_region_size; } @@ -261,7 +262,7 @@ void __init mpu_setup(void) return; region_err = mpu_setup_region(MPU_RAM_REGION, PHYS_OFFSET, - ilog2(meminfo.bank[0].size), + ilog2(memblock.memory.regions[0].size), MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL); if (region_err) { panic("MPU region initialization failure! %d", region_err); -- cgit v1.2.3 From 5b526bd92511a12807a51b7bedd16af03e99bc33 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Wed, 4 May 2016 10:38:12 +0100 Subject: ARM: 8572/1: nommu: change memory reserve for the vectors Commit 19accfd3 (ARM: move vector stubs) moved the vector stubs in an additional page above the base vector one. This change wasn't taken into account by the nommu memreserve. This patch ensures that the kernel won't overwrite any vector stub on nommu. [changed the MPU side too] Signed-off-by: Jean-Philippe Brucker Signed-off-by: Vladimir Murzin Signed-off-by: Russell King --- arch/arm/kernel/head-nommu.S | 2 +- arch/arm/mm/nommu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 9b8c5a113434..fb1a69eb49c1 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -236,7 +236,7 @@ ENTRY(__setup_mpu) mov r0, #CONFIG_VECTORS_BASE @ Cover from VECTORS_BASE ldr r5,=(MPU_AP_PL1RW_PL0NA | MPU_RGN_NORMAL) /* Writing N to bits 5:1 (RSR_SZ) --> region size 2^N+1 */ - mov r6, #(((PAGE_SHIFT - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN) + mov r6, #(((2 * PAGE_SHIFT - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN) setup_region r0, r5, r6, MPU_DATA_SIDE @ VECTORS_BASE, PL0 NA, enabled beq 3f @ Memory-map not unified diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 4d113fcceb4a..d5805e4bf2fc 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -286,7 +286,7 @@ void __init arm_mm_memblock_reserve(void) * some architectures which the DRAM is the exception vector to trap, * alloc_page breaks with error, although it is not NULL, but "0." */ - memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE); + memblock_reserve(CONFIG_VECTORS_BASE, 2 * PAGE_SIZE); #else /* ifndef CONFIG_CPU_V7M */ /* * There is no dedicated vector page on V7-M. So nothing needs to be -- cgit v1.2.3 From ec953b70f368330e806a94df6fe2dd1d72176b2d Mon Sep 17 00:00:00 2001 From: Vladimir Murzin Date: Wed, 4 May 2016 10:39:02 +0100 Subject: ARM: 8573/1: domain: move {set,get}_domain under config guard Recursive undefined instrcution falut is seen with R-class taking an exception. The reson for that is __show_regs() tries to get domain information, but domains is not available on !MMU cores, like R/M class. Fix it by puting {set,get}_domain functions under CONFIG_CPU_CP15_MMU guard and providing stubs for the case where domains is not supported. Signed-off-by: Vladimir Murzin Signed-off-by: Russell King --- arch/arm/include/asm/domain.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h index fc8ba1663601..99d9f630d6b6 100644 --- a/arch/arm/include/asm/domain.h +++ b/arch/arm/include/asm/domain.h @@ -84,6 +84,7 @@ #ifndef __ASSEMBLY__ +#ifdef CONFIG_CPU_CP15_MMU static inline unsigned int get_domain(void) { unsigned int domain; @@ -103,6 +104,16 @@ static inline void set_domain(unsigned val) : : "r" (val) : "memory"); isb(); } +#else +static inline unsigned int get_domain(void) +{ + return 0; +} + +static inline void set_domain(unsigned val) +{ +} +#endif #ifdef CONFIG_CPU_USE_DOMAINS #define modify_domain(dom,type) \ -- cgit v1.2.3 From 74d369443325063a5f0260e63971decb950fd8fa Mon Sep 17 00:00:00 2001 From: Howard Cochran Date: Thu, 10 Mar 2016 01:12:39 -0500 Subject: writeback: Fix performance regression in wb_over_bg_thresh() Commit 947e9762a8dd ("writeback: update wb_over_bg_thresh() to use wb_domain aware operations") unintentionally changed this function's meaning from "are there more dirty pages than the background writeback threshold" to "are there more dirty pages than the writeback threshold". The background writeback threshold is typically half of the writeback threshold, so this had the effect of raising the number of dirty pages required to cause a writeback worker to perform background writeout. This can cause a very severe performance regression when a BDI uses BDI_CAP_STRICTLIMIT because balance_dirty_pages() and the writeback worker can now disagree on whether writeback should be initiated. For example, in a system having 1GB of RAM, a single spinning disk, and a "pass-through" FUSE filesystem mounted over the disk, application code mmapped a 128MB file on the disk and was randomly dirtying pages in that mapping. Because FUSE uses strictlimit and has a default max_ratio of only 1%, in balance_dirty_pages, thresh is ~200, bg_thresh is ~100, and the dirty_freerun_ceiling is the average of those, ~150. So, it pauses the dirtying processes when we have 151 dirty pages and wakes up a background writeback worker. But the worker tests the wrong threshold (200 instead of 100), so it does not initiate writeback and just returns. Thus, balance_dirty_pages keeps looping, sleeping and then waking up the worker who will do nothing. It remains stuck in this state until the few dirty pages that we have finally expire and we write them back for that reason. Then the whole process repeats, resulting in near-zero throughput through the FUSE BDI. The fix is to call the parameterized variant of wb_calc_thresh, so that the worker will do writeback if the bg_thresh is exceeded which was the behavior before the referenced commit. Fixes: 947e9762a8dd ("writeback: update wb_over_bg_thresh() to use wb_domain aware operations") Signed-off-by: Howard Cochran Acked-by: Tejun Heo Signed-off-by: Miklos Szeredi Cc: # v4.2+ Tested-by Sedat Dilek Signed-off-by: Jens Axboe --- mm/page-writeback.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 11ff8f758631..eeaa431ee4ec 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -1910,7 +1910,8 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb) if (gdtc->dirty > gdtc->bg_thresh) return true; - if (wb_stat(wb, WB_RECLAIMABLE) > __wb_calc_thresh(gdtc)) + if (wb_stat(wb, WB_RECLAIMABLE) > + wb_calc_thresh(gdtc->wb, gdtc->bg_thresh)) return true; if (mdtc) { @@ -1924,7 +1925,8 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb) if (mdtc->dirty > mdtc->bg_thresh) return true; - if (wb_stat(wb, WB_RECLAIMABLE) > __wb_calc_thresh(mdtc)) + if (wb_stat(wb, WB_RECLAIMABLE) > + wb_calc_thresh(mdtc->wb, mdtc->bg_thresh)) return true; } -- cgit v1.2.3 From 54176cc6803844613b3dca13174c13c47e9686db Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 5 May 2016 17:12:54 +0100 Subject: maintainers: update rmk's email address(es) Update my email and web addresses in the kernel maintainers file. Signed-off-by: Russell King Signed-off-by: Linus Torvalds --- MAINTAINERS | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index ecbb2f6a3ba0..73141b4f46a9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -872,9 +872,9 @@ F: drivers/perf/arm_pmu.c F: include/linux/perf/arm_pmu.h ARM PORT -M: Russell King +M: Russell King L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -W: http://www.arm.linux.org.uk/ +W: http://www.armlinux.org.uk/ S: Maintained F: arch/arm/ @@ -886,35 +886,35 @@ F: arch/arm/plat-*/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git ARM PRIMECELL AACI PL041 DRIVER -M: Russell King +M: Russell King S: Maintained F: sound/arm/aaci.* ARM PRIMECELL CLCD PL110 DRIVER -M: Russell King +M: Russell King S: Maintained F: drivers/video/fbdev/amba-clcd.* ARM PRIMECELL KMI PL050 DRIVER -M: Russell King +M: Russell King S: Maintained F: drivers/input/serio/ambakmi.* F: include/linux/amba/kmi.h ARM PRIMECELL MMCI PL180/1 DRIVER -M: Russell King +M: Russell King S: Maintained F: drivers/mmc/host/mmci.* F: include/linux/amba/mmci.h ARM PRIMECELL UART PL010 AND PL011 DRIVERS -M: Russell King +M: Russell King S: Maintained F: drivers/tty/serial/amba-pl01*.c F: include/linux/amba/serial.h ARM PRIMECELL BUS SUPPORT -M: Russell King +M: Russell King S: Maintained F: drivers/amba/ F: include/linux/amba/bus.h @@ -1036,7 +1036,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained ARM/CLKDEV SUPPORT -M: Russell King +M: Russell King L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/include/asm/clkdev.h @@ -1093,9 +1093,9 @@ F: arch/arm/boot/dts/cx92755* N: digicolor ARM/EBSA110 MACHINE SUPPORT -M: Russell King +M: Russell King L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -W: http://www.arm.linux.org.uk/ +W: http://www.armlinux.org.uk/ S: Maintained F: arch/arm/mach-ebsa110/ F: drivers/net/ethernet/amd/am79c961a.* @@ -1124,9 +1124,9 @@ T: git git://git.berlios.de/gemini-board F: arch/arm/mm/*-fa* ARM/FOOTBRIDGE ARCHITECTURE -M: Russell King +M: Russell King L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -W: http://www.arm.linux.org.uk/ +W: http://www.armlinux.org.uk/ S: Maintained F: arch/arm/include/asm/hardware/dec21285.h F: arch/arm/mach-footbridge/ @@ -1457,7 +1457,7 @@ S: Maintained ARM/PT DIGITAL BOARD PORT M: Stefan Eletzhofer L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -W: http://www.arm.linux.org.uk/ +W: http://www.armlinux.org.uk/ S: Maintained ARM/QUALCOMM SUPPORT @@ -1493,9 +1493,9 @@ S: Supported F: arch/arm64/boot/dts/renesas/ ARM/RISCPC ARCHITECTURE -M: Russell King +M: Russell King L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -W: http://www.arm.linux.org.uk/ +W: http://www.armlinux.org.uk/ S: Maintained F: arch/arm/include/asm/hardware/entry-macro-iomd.S F: arch/arm/include/asm/hardware/ioc.h @@ -1773,9 +1773,9 @@ F: drivers/clk/versatile/clk-vexpress-osc.c F: drivers/clocksource/versatile.c ARM/VFP SUPPORT -M: Russell King +M: Russell King L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -W: http://www.arm.linux.org.uk/ +W: http://www.armlinux.org.uk/ S: Maintained F: arch/arm/vfp/ @@ -2921,7 +2921,7 @@ F: mm/cleancache.c F: include/linux/cleancache.h CLK API -M: Russell King +M: Russell King L: linux-clk@vger.kernel.org S: Maintained F: include/linux/clk.h @@ -3354,9 +3354,9 @@ S: Supported F: drivers/net/ethernet/stmicro/stmmac/ CYBERPRO FB DRIVER -M: Russell King +M: Russell King L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -W: http://www.arm.linux.org.uk/ +W: http://www.armlinux.org.uk/ S: Maintained F: drivers/video/fbdev/cyber2000fb.* @@ -3881,7 +3881,7 @@ F: Documentation/devicetree/bindings/display/st,stih4xx.txt DRM DRIVERS FOR VIVANTE GPU IP M: Lucas Stach -R: Russell King +R: Russell King R: Christian Gmeiner L: dri-devel@lists.freedesktop.org S: Maintained @@ -6905,7 +6905,7 @@ L: linux-man@vger.kernel.org S: Maintained MARVELL ARMADA DRM SUPPORT -M: Russell King +M: Russell King S: Maintained F: drivers/gpu/drm/armada/ @@ -7905,7 +7905,7 @@ S: Supported F: drivers/nfc/nxp-nci NXP TDA998X DRM DRIVER -M: Russell King +M: Russell King S: Supported F: drivers/gpu/drm/i2c/tda998x_drv.c F: include/drm/i2c/tda998x.h -- cgit v1.2.3 From 145bdaa1501bf1c8a6cfa8ea5e347b9a46aad1b7 Mon Sep 17 00:00:00 2001 From: Yang Shi Date: Thu, 5 May 2016 16:22:00 -0700 Subject: mm: thp: correct split_huge_pages file permission split_huge_pages doesn't support get method at all, so the read permission sounds confusing, change the permission to write only. And, add "\n" to the output of set method to make it more readable. Signed-off-by: Yang Shi Acked-by: Kirill A. Shutemov Cc: Andrea Arcangeli Cc: Mel Gorman Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/huge_memory.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index df67b53ae3c5..f7daa7de8f48 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3452,7 +3452,7 @@ next: } } - pr_info("%lu of %lu THP split", split, total); + pr_info("%lu of %lu THP split\n", split, total); return 0; } @@ -3463,7 +3463,7 @@ static int __init split_huge_pages_debugfs(void) { void *ret; - ret = debugfs_create_file("split_huge_pages", 0644, NULL, NULL, + ret = debugfs_create_file("split_huge_pages", 0200, NULL, NULL, &split_huge_pages_fops); if (!ret) pr_warn("Failed to create split_huge_pages in debugfs"); -- cgit v1.2.3 From 4550c4e157ca3da929593bb6c64080a59141af35 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 5 May 2016 16:22:03 -0700 Subject: mm: memcontrol: let v2 cgroups follow changes in system swappiness Cgroup2 currently doesn't have a per-cgroup swappiness setting. We might want to add one later - that's a different discussion - but until we do, the cgroups should always follow the system setting. Otherwise it will be unchangeably set to whatever the ancestor inherited from the system setting at the time of cgroup creation. Signed-off-by: Johannes Weiner Acked-by: Michal Hocko Acked-by: Vladimir Davydov Cc: [4.5] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/swap.h b/include/linux/swap.h index 2b83359c19ca..0a4cd4703f40 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -533,6 +533,10 @@ static inline swp_entry_t get_swap_page(void) #ifdef CONFIG_MEMCG static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg) { + /* Cgroup2 doesn't have per-cgroup swappiness */ + if (cgroup_subsys_on_dfl(memory_cgrp_subsys)) + return vm_swappiness; + /* root ? */ if (mem_cgroup_disabled() || !memcg->css.parent) return vm_swappiness; -- cgit v1.2.3 From 4e1016dac1ccce6d8a960775526cdc3a5baa690b Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Thu, 5 May 2016 16:22:06 -0700 Subject: rapidio/mport_cdev: fix uapi type definitions Fix problems in uapi definitions reported by Gabriel Laskar: (see https://lkml.org/lkml/2016/4/5/205 for details) - move public header file rio_mport_cdev.h to include/uapi/linux directory - change types in data structures passed as IOCTL parameters - improve parameter checking in some IOCTL service routines Signed-off-by: Alexandre Bounine Reported-by: Gabriel Laskar Tested-by: Barry Wood Cc: Gabriel Laskar Cc: Matt Porter Cc: Aurelien Jacquiot Cc: Andre van Herk Cc: Barry Wood Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/devices/rio_mport_cdev.c | 115 +++++++------ include/linux/rio_mport_cdev.h | 271 ------------------------------ include/uapi/linux/rio_mport_cdev.h | 277 +++++++++++++++++++++++++++++++ 3 files changed, 341 insertions(+), 322 deletions(-) delete mode 100644 include/linux/rio_mport_cdev.h create mode 100644 include/uapi/linux/rio_mport_cdev.h diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 96168b819044..e165b7ce29d7 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -126,7 +126,7 @@ struct rio_mport_mapping { struct list_head node; struct mport_dev *md; enum rio_mport_map_dir dir; - u32 rioid; + u16 rioid; u64 rio_addr; dma_addr_t phys_addr; /* for mmap */ void *virt_addr; /* kernel address, for dma_free_coherent */ @@ -137,7 +137,7 @@ struct rio_mport_mapping { struct rio_mport_dma_map { int valid; - uint64_t length; + u64 length; void *vaddr; dma_addr_t paddr; }; @@ -208,7 +208,7 @@ struct mport_cdev_priv { struct kfifo event_fifo; wait_queue_head_t event_rx_wait; spinlock_t fifo_lock; - unsigned int event_mask; /* RIO_DOORBELL, RIO_PORTWRITE */ + u32 event_mask; /* RIO_DOORBELL, RIO_PORTWRITE */ #ifdef CONFIG_RAPIDIO_DMA_ENGINE struct dma_chan *dmach; struct list_head async_list; @@ -276,7 +276,8 @@ static int rio_mport_maint_rd(struct mport_cdev_priv *priv, void __user *arg, return -EFAULT; if ((maint_io.offset % 4) || - (maint_io.length == 0) || (maint_io.length % 4)) + (maint_io.length == 0) || (maint_io.length % 4) || + (maint_io.length + maint_io.offset) > RIO_MAINT_SPACE_SZ) return -EINVAL; buffer = vmalloc(maint_io.length); @@ -298,7 +299,8 @@ static int rio_mport_maint_rd(struct mport_cdev_priv *priv, void __user *arg, offset += 4; } - if (unlikely(copy_to_user(maint_io.buffer, buffer, maint_io.length))) + if (unlikely(copy_to_user((void __user *)(uintptr_t)maint_io.buffer, + buffer, maint_io.length))) ret = -EFAULT; out: vfree(buffer); @@ -319,7 +321,8 @@ static int rio_mport_maint_wr(struct mport_cdev_priv *priv, void __user *arg, return -EFAULT; if ((maint_io.offset % 4) || - (maint_io.length == 0) || (maint_io.length % 4)) + (maint_io.length == 0) || (maint_io.length % 4) || + (maint_io.length + maint_io.offset) > RIO_MAINT_SPACE_SZ) return -EINVAL; buffer = vmalloc(maint_io.length); @@ -327,7 +330,8 @@ static int rio_mport_maint_wr(struct mport_cdev_priv *priv, void __user *arg, return -ENOMEM; length = maint_io.length; - if (unlikely(copy_from_user(buffer, maint_io.buffer, length))) { + if (unlikely(copy_from_user(buffer, + (void __user *)(uintptr_t)maint_io.buffer, length))) { ret = -EFAULT; goto out; } @@ -360,7 +364,7 @@ out: */ static int rio_mport_create_outbound_mapping(struct mport_dev *md, struct file *filp, - u32 rioid, u64 raddr, u32 size, + u16 rioid, u64 raddr, u32 size, dma_addr_t *paddr) { struct rio_mport *mport = md->mport; @@ -369,7 +373,7 @@ rio_mport_create_outbound_mapping(struct mport_dev *md, struct file *filp, rmcd_debug(OBW, "did=%d ra=0x%llx sz=0x%x", rioid, raddr, size); - map = kzalloc(sizeof(struct rio_mport_mapping), GFP_KERNEL); + map = kzalloc(sizeof(*map), GFP_KERNEL); if (map == NULL) return -ENOMEM; @@ -394,7 +398,7 @@ err_map_outb: static int rio_mport_get_outbound_mapping(struct mport_dev *md, struct file *filp, - u32 rioid, u64 raddr, u32 size, + u16 rioid, u64 raddr, u32 size, dma_addr_t *paddr) { struct rio_mport_mapping *map; @@ -433,7 +437,7 @@ static int rio_mport_obw_map(struct file *filp, void __user *arg) dma_addr_t paddr; int ret; - if (unlikely(copy_from_user(&map, arg, sizeof(struct rio_mmap)))) + if (unlikely(copy_from_user(&map, arg, sizeof(map)))) return -EFAULT; rmcd_debug(OBW, "did=%d ra=0x%llx sz=0x%llx", @@ -448,7 +452,7 @@ static int rio_mport_obw_map(struct file *filp, void __user *arg) map.handle = paddr; - if (unlikely(copy_to_user(arg, &map, sizeof(struct rio_mmap)))) + if (unlikely(copy_to_user(arg, &map, sizeof(map)))) return -EFAULT; return 0; } @@ -469,7 +473,7 @@ static int rio_mport_obw_free(struct file *filp, void __user *arg) if (!md->mport->ops->unmap_outb) return -EPROTONOSUPPORT; - if (copy_from_user(&handle, arg, sizeof(u64))) + if (copy_from_user(&handle, arg, sizeof(handle))) return -EFAULT; rmcd_debug(OBW, "h=0x%llx", handle); @@ -498,9 +502,9 @@ static int rio_mport_obw_free(struct file *filp, void __user *arg) static int maint_hdid_set(struct mport_cdev_priv *priv, void __user *arg) { struct mport_dev *md = priv->md; - uint16_t hdid; + u16 hdid; - if (copy_from_user(&hdid, arg, sizeof(uint16_t))) + if (copy_from_user(&hdid, arg, sizeof(hdid))) return -EFAULT; md->mport->host_deviceid = hdid; @@ -520,9 +524,9 @@ static int maint_hdid_set(struct mport_cdev_priv *priv, void __user *arg) static int maint_comptag_set(struct mport_cdev_priv *priv, void __user *arg) { struct mport_dev *md = priv->md; - uint32_t comptag; + u32 comptag; - if (copy_from_user(&comptag, arg, sizeof(uint32_t))) + if (copy_from_user(&comptag, arg, sizeof(comptag))) return -EFAULT; rio_local_write_config_32(md->mport, RIO_COMPONENT_TAG_CSR, comptag); @@ -837,7 +841,7 @@ err_out: * @xfer: data transfer descriptor structure */ static int -rio_dma_transfer(struct file *filp, uint32_t transfer_mode, +rio_dma_transfer(struct file *filp, u32 transfer_mode, enum rio_transfer_sync sync, enum dma_data_direction dir, struct rio_transfer_io *xfer) { @@ -875,7 +879,7 @@ rio_dma_transfer(struct file *filp, uint32_t transfer_mode, unsigned long offset; long pinned; - offset = (unsigned long)xfer->loc_addr & ~PAGE_MASK; + offset = (unsigned long)(uintptr_t)xfer->loc_addr & ~PAGE_MASK; nr_pages = PAGE_ALIGN(xfer->length + offset) >> PAGE_SHIFT; page_list = kmalloc_array(nr_pages, @@ -1015,19 +1019,20 @@ static int rio_mport_transfer_ioctl(struct file *filp, void __user *arg) if (unlikely(copy_from_user(&transaction, arg, sizeof(transaction)))) return -EFAULT; - if (transaction.count != 1) + if (transaction.count != 1) /* only single transfer for now */ return -EINVAL; if ((transaction.transfer_mode & priv->md->properties.transfer_mode) == 0) return -ENODEV; - transfer = vmalloc(transaction.count * sizeof(struct rio_transfer_io)); + transfer = vmalloc(transaction.count * sizeof(*transfer)); if (!transfer) return -ENOMEM; - if (unlikely(copy_from_user(transfer, transaction.block, - transaction.count * sizeof(struct rio_transfer_io)))) { + if (unlikely(copy_from_user(transfer, + (void __user *)(uintptr_t)transaction.block, + transaction.count * sizeof(*transfer)))) { ret = -EFAULT; goto out_free; } @@ -1038,8 +1043,9 @@ static int rio_mport_transfer_ioctl(struct file *filp, void __user *arg) ret = rio_dma_transfer(filp, transaction.transfer_mode, transaction.sync, dir, &transfer[i]); - if (unlikely(copy_to_user(transaction.block, transfer, - transaction.count * sizeof(struct rio_transfer_io)))) + if (unlikely(copy_to_user((void __user *)(uintptr_t)transaction.block, + transfer, + transaction.count * sizeof(*transfer)))) ret = -EFAULT; out_free: @@ -1129,11 +1135,11 @@ err_tmo: } static int rio_mport_create_dma_mapping(struct mport_dev *md, struct file *filp, - uint64_t size, struct rio_mport_mapping **mapping) + u64 size, struct rio_mport_mapping **mapping) { struct rio_mport_mapping *map; - map = kzalloc(sizeof(struct rio_mport_mapping), GFP_KERNEL); + map = kzalloc(sizeof(*map), GFP_KERNEL); if (map == NULL) return -ENOMEM; @@ -1165,7 +1171,7 @@ static int rio_mport_alloc_dma(struct file *filp, void __user *arg) struct rio_mport_mapping *mapping = NULL; int ret; - if (unlikely(copy_from_user(&map, arg, sizeof(struct rio_dma_mem)))) + if (unlikely(copy_from_user(&map, arg, sizeof(map)))) return -EFAULT; ret = rio_mport_create_dma_mapping(md, filp, map.length, &mapping); @@ -1174,7 +1180,7 @@ static int rio_mport_alloc_dma(struct file *filp, void __user *arg) map.dma_handle = mapping->phys_addr; - if (unlikely(copy_to_user(arg, &map, sizeof(struct rio_dma_mem)))) { + if (unlikely(copy_to_user(arg, &map, sizeof(map)))) { mutex_lock(&md->buf_mutex); kref_put(&mapping->ref, mport_release_mapping); mutex_unlock(&md->buf_mutex); @@ -1192,7 +1198,7 @@ static int rio_mport_free_dma(struct file *filp, void __user *arg) int ret = -EFAULT; struct rio_mport_mapping *map, *_map; - if (copy_from_user(&handle, arg, sizeof(u64))) + if (copy_from_user(&handle, arg, sizeof(handle))) return -EFAULT; rmcd_debug(EXIT, "filp=%p", filp); @@ -1242,14 +1248,18 @@ static int rio_mport_free_dma(struct file *filp, void __user *arg) static int rio_mport_create_inbound_mapping(struct mport_dev *md, struct file *filp, - u64 raddr, u32 size, + u64 raddr, u64 size, struct rio_mport_mapping **mapping) { struct rio_mport *mport = md->mport; struct rio_mport_mapping *map; int ret; - map = kzalloc(sizeof(struct rio_mport_mapping), GFP_KERNEL); + /* rio_map_inb_region() accepts u32 size */ + if (size > 0xffffffff) + return -EINVAL; + + map = kzalloc(sizeof(*map), GFP_KERNEL); if (map == NULL) return -ENOMEM; @@ -1262,7 +1272,7 @@ rio_mport_create_inbound_mapping(struct mport_dev *md, struct file *filp, if (raddr == RIO_MAP_ANY_ADDR) raddr = map->phys_addr; - ret = rio_map_inb_region(mport, map->phys_addr, raddr, size, 0); + ret = rio_map_inb_region(mport, map->phys_addr, raddr, (u32)size, 0); if (ret < 0) goto err_map_inb; @@ -1288,7 +1298,7 @@ err_dma_alloc: static int rio_mport_get_inbound_mapping(struct mport_dev *md, struct file *filp, - u64 raddr, u32 size, + u64 raddr, u64 size, struct rio_mport_mapping **mapping) { struct rio_mport_mapping *map; @@ -1331,7 +1341,7 @@ static int rio_mport_map_inbound(struct file *filp, void __user *arg) if (!md->mport->ops->map_inb) return -EPROTONOSUPPORT; - if (unlikely(copy_from_user(&map, arg, sizeof(struct rio_mmap)))) + if (unlikely(copy_from_user(&map, arg, sizeof(map)))) return -EFAULT; rmcd_debug(IBW, "%s filp=%p", dev_name(&priv->md->dev), filp); @@ -1344,7 +1354,7 @@ static int rio_mport_map_inbound(struct file *filp, void __user *arg) map.handle = mapping->phys_addr; map.rio_addr = mapping->rio_addr; - if (unlikely(copy_to_user(arg, &map, sizeof(struct rio_mmap)))) { + if (unlikely(copy_to_user(arg, &map, sizeof(map)))) { /* Delete mapping if it was created by this request */ if (ret == 0 && mapping->filp == filp) { mutex_lock(&md->buf_mutex); @@ -1375,7 +1385,7 @@ static int rio_mport_inbound_free(struct file *filp, void __user *arg) if (!md->mport->ops->unmap_inb) return -EPROTONOSUPPORT; - if (copy_from_user(&handle, arg, sizeof(u64))) + if (copy_from_user(&handle, arg, sizeof(handle))) return -EFAULT; mutex_lock(&md->buf_mutex); @@ -1401,7 +1411,7 @@ static int rio_mport_inbound_free(struct file *filp, void __user *arg) static int maint_port_idx_get(struct mport_cdev_priv *priv, void __user *arg) { struct mport_dev *md = priv->md; - uint32_t port_idx = md->mport->index; + u32 port_idx = md->mport->index; rmcd_debug(MPORT, "port_index=%d", port_idx); @@ -1451,7 +1461,7 @@ static void rio_mport_doorbell_handler(struct rio_mport *mport, void *dev_id, handled = 0; spin_lock(&data->db_lock); list_for_each_entry(db_filter, &data->doorbells, data_node) { - if (((db_filter->filter.rioid == 0xffffffff || + if (((db_filter->filter.rioid == RIO_INVALID_DESTID || db_filter->filter.rioid == src)) && info >= db_filter->filter.low && info <= db_filter->filter.high) { @@ -1525,6 +1535,9 @@ static int rio_mport_remove_db_filter(struct mport_cdev_priv *priv, if (copy_from_user(&filter, arg, sizeof(filter))) return -EFAULT; + if (filter.low > filter.high) + return -EINVAL; + spin_lock_irqsave(&priv->md->db_lock, flags); list_for_each_entry(db_filter, &priv->db_filters, priv_node) { if (db_filter->filter.rioid == filter.rioid && @@ -1737,10 +1750,10 @@ static int rio_mport_add_riodev(struct mport_cdev_priv *priv, return -EEXIST; } - size = sizeof(struct rio_dev); + size = sizeof(*rdev); mport = md->mport; - destid = (u16)dev_info.destid; - hopcount = (u8)dev_info.hopcount; + destid = dev_info.destid; + hopcount = dev_info.hopcount; if (rio_mport_read_config_32(mport, destid, hopcount, RIO_PEF_CAR, &rval)) @@ -1872,8 +1885,8 @@ static int rio_mport_del_riodev(struct mport_cdev_priv *priv, void __user *arg) do { rdev = rio_get_comptag(dev_info.comptag, rdev); if (rdev && rdev->dev.parent == &mport->net->dev && - rdev->destid == (u16)dev_info.destid && - rdev->hopcount == (u8)dev_info.hopcount) + rdev->destid == dev_info.destid && + rdev->hopcount == dev_info.hopcount) break; } while (rdev); } @@ -2146,8 +2159,8 @@ static long mport_cdev_ioctl(struct file *filp, return maint_port_idx_get(data, (void __user *)arg); case RIO_MPORT_GET_PROPERTIES: md->properties.hdid = md->mport->host_deviceid; - if (copy_to_user((void __user *)arg, &(data->md->properties), - sizeof(data->md->properties))) + if (copy_to_user((void __user *)arg, &(md->properties), + sizeof(md->properties))) return -EFAULT; return 0; case RIO_ENABLE_DOORBELL_RANGE: @@ -2159,11 +2172,11 @@ static long mport_cdev_ioctl(struct file *filp, case RIO_DISABLE_PORTWRITE_RANGE: return rio_mport_remove_pw_filter(data, (void __user *)arg); case RIO_SET_EVENT_MASK: - data->event_mask = arg; + data->event_mask = (u32)arg; return 0; case RIO_GET_EVENT_MASK: if (copy_to_user((void __user *)arg, &data->event_mask, - sizeof(data->event_mask))) + sizeof(u32))) return -EFAULT; return 0; case RIO_MAP_OUTBOUND: @@ -2374,7 +2387,7 @@ static ssize_t mport_write(struct file *filp, const char __user *buf, return -EINVAL; ret = rio_mport_send_doorbell(mport, - (u16)event.u.doorbell.rioid, + event.u.doorbell.rioid, event.u.doorbell.payload); if (ret < 0) return ret; @@ -2421,7 +2434,7 @@ static struct mport_dev *mport_cdev_add(struct rio_mport *mport) struct mport_dev *md; struct rio_mport_attr attr; - md = kzalloc(sizeof(struct mport_dev), GFP_KERNEL); + md = kzalloc(sizeof(*md), GFP_KERNEL); if (!md) { rmcd_error("Unable allocate a device object"); return NULL; @@ -2470,7 +2483,7 @@ static struct mport_dev *mport_cdev_add(struct rio_mport *mport) /* The transfer_mode property will be returned through mport query * interface */ -#ifdef CONFIG_PPC /* for now: only on Freescale's SoCs */ +#ifdef CONFIG_FSL_RIO /* for now: only on Freescale's SoCs */ md->properties.transfer_mode |= RIO_TRANSFER_MODE_MAPPED; #else md->properties.transfer_mode |= RIO_TRANSFER_MODE_TRANSFER; diff --git a/include/linux/rio_mport_cdev.h b/include/linux/rio_mport_cdev.h deleted file mode 100644 index b65d19df76d2..000000000000 --- a/include/linux/rio_mport_cdev.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2015-2016, Integrated Device Technology Inc. - * Copyright (c) 2015, Prodrive Technologies - * Copyright (c) 2015, Texas Instruments Incorporated - * Copyright (c) 2015, RapidIO Trade Association - * All rights reserved. - * - * This software is available to you under a choice of one of two licenses. - * You may choose to be licensed under the terms of the GNU General Public - * License(GPL) Version 2, or the BSD-3 Clause license below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _RIO_MPORT_CDEV_H_ -#define _RIO_MPORT_CDEV_H_ - -#ifndef __user -#define __user -#endif - -struct rio_mport_maint_io { - uint32_t rioid; /* destID of remote device */ - uint32_t hopcount; /* hopcount to remote device */ - uint32_t offset; /* offset in register space */ - size_t length; /* length in bytes */ - void __user *buffer; /* data buffer */ -}; - -/* - * Definitions for RapidIO data transfers: - * - memory mapped (MAPPED) - * - packet generation from memory (TRANSFER) - */ -#define RIO_TRANSFER_MODE_MAPPED (1 << 0) -#define RIO_TRANSFER_MODE_TRANSFER (1 << 1) -#define RIO_CAP_DBL_SEND (1 << 2) -#define RIO_CAP_DBL_RECV (1 << 3) -#define RIO_CAP_PW_SEND (1 << 4) -#define RIO_CAP_PW_RECV (1 << 5) -#define RIO_CAP_MAP_OUTB (1 << 6) -#define RIO_CAP_MAP_INB (1 << 7) - -struct rio_mport_properties { - uint16_t hdid; - uint8_t id; /* Physical port ID */ - uint8_t index; - uint32_t flags; - uint32_t sys_size; /* Default addressing size */ - uint8_t port_ok; - uint8_t link_speed; - uint8_t link_width; - uint32_t dma_max_sge; - uint32_t dma_max_size; - uint32_t dma_align; - uint32_t transfer_mode; /* Default transfer mode */ - uint32_t cap_sys_size; /* Capable system sizes */ - uint32_t cap_addr_size; /* Capable addressing sizes */ - uint32_t cap_transfer_mode; /* Capable transfer modes */ - uint32_t cap_mport; /* Mport capabilities */ -}; - -/* - * Definitions for RapidIO events; - * - incoming port-writes - * - incoming doorbells - */ -#define RIO_DOORBELL (1 << 0) -#define RIO_PORTWRITE (1 << 1) - -struct rio_doorbell { - uint32_t rioid; - uint16_t payload; -}; - -struct rio_doorbell_filter { - uint32_t rioid; /* 0xffffffff to match all ids */ - uint16_t low; - uint16_t high; -}; - - -struct rio_portwrite { - uint32_t payload[16]; -}; - -struct rio_pw_filter { - uint32_t mask; - uint32_t low; - uint32_t high; -}; - -/* RapidIO base address for inbound requests set to value defined below - * indicates that no specific RIO-to-local address translation is requested - * and driver should use direct (one-to-one) address mapping. -*/ -#define RIO_MAP_ANY_ADDR (uint64_t)(~((uint64_t) 0)) - -struct rio_mmap { - uint32_t rioid; - uint64_t rio_addr; - uint64_t length; - uint64_t handle; - void *address; -}; - -struct rio_dma_mem { - uint64_t length; /* length of DMA memory */ - uint64_t dma_handle; /* handle associated with this memory */ - void *buffer; /* pointer to this memory */ -}; - - -struct rio_event { - unsigned int header; /* event type RIO_DOORBELL or RIO_PORTWRITE */ - union { - struct rio_doorbell doorbell; /* header for RIO_DOORBELL */ - struct rio_portwrite portwrite; /* header for RIO_PORTWRITE */ - } u; -}; - -enum rio_transfer_sync { - RIO_TRANSFER_SYNC, /* synchronous transfer */ - RIO_TRANSFER_ASYNC, /* asynchronous transfer */ - RIO_TRANSFER_FAF, /* fire-and-forget transfer */ -}; - -enum rio_transfer_dir { - RIO_TRANSFER_DIR_READ, /* Read operation */ - RIO_TRANSFER_DIR_WRITE, /* Write operation */ -}; - -/* - * RapidIO data exchange transactions are lists of individual transfers. Each - * transfer exchanges data between two RapidIO devices by remote direct memory - * access and has its own completion code. - * - * The RapidIO specification defines four types of data exchange requests: - * NREAD, NWRITE, SWRITE and NWRITE_R. The RapidIO DMA channel interface allows - * to specify the required type of write operation or combination of them when - * only the last data packet requires response. - * - * NREAD: read up to 256 bytes from remote device memory into local memory - * NWRITE: write up to 256 bytes from local memory to remote device memory - * without confirmation - * SWRITE: as NWRITE, but all addresses and payloads must be 64-bit aligned - * NWRITE_R: as NWRITE, but expect acknowledgment from remote device. - * - * The default exchange is chosen from NREAD and any of the WRITE modes as the - * driver sees fit. For write requests the user can explicitly choose between - * any of the write modes for each transaction. - */ -enum rio_exchange { - RIO_EXCHANGE_DEFAULT, /* Default method */ - RIO_EXCHANGE_NWRITE, /* All packets using NWRITE */ - RIO_EXCHANGE_SWRITE, /* All packets using SWRITE */ - RIO_EXCHANGE_NWRITE_R, /* Last packet NWRITE_R, others NWRITE */ - RIO_EXCHANGE_SWRITE_R, /* Last packet NWRITE_R, others SWRITE */ - RIO_EXCHANGE_NWRITE_R_ALL, /* All packets using NWRITE_R */ -}; - -struct rio_transfer_io { - uint32_t rioid; /* Target destID */ - uint64_t rio_addr; /* Address in target's RIO mem space */ - enum rio_exchange method; /* Data exchange method */ - void __user *loc_addr; - uint64_t handle; - uint64_t offset; /* Offset in buffer */ - uint64_t length; /* Length in bytes */ - uint32_t completion_code; /* Completion code for this transfer */ -}; - -struct rio_transaction { - uint32_t transfer_mode; /* Data transfer mode */ - enum rio_transfer_sync sync; /* Synchronization method */ - enum rio_transfer_dir dir; /* Transfer direction */ - size_t count; /* Number of transfers */ - struct rio_transfer_io __user *block; /* Array of transfers */ -}; - -struct rio_async_tx_wait { - uint32_t token; /* DMA transaction ID token */ - uint32_t timeout; /* Wait timeout in msec, if 0 use default TO */ -}; - -#define RIO_MAX_DEVNAME_SZ 20 - -struct rio_rdev_info { - uint32_t destid; - uint8_t hopcount; - uint32_t comptag; - char name[RIO_MAX_DEVNAME_SZ + 1]; -}; - -/* Driver IOCTL codes */ -#define RIO_MPORT_DRV_MAGIC 'm' - -#define RIO_MPORT_MAINT_HDID_SET \ - _IOW(RIO_MPORT_DRV_MAGIC, 1, uint16_t) -#define RIO_MPORT_MAINT_COMPTAG_SET \ - _IOW(RIO_MPORT_DRV_MAGIC, 2, uint32_t) -#define RIO_MPORT_MAINT_PORT_IDX_GET \ - _IOR(RIO_MPORT_DRV_MAGIC, 3, uint32_t) -#define RIO_MPORT_GET_PROPERTIES \ - _IOR(RIO_MPORT_DRV_MAGIC, 4, struct rio_mport_properties) -#define RIO_MPORT_MAINT_READ_LOCAL \ - _IOR(RIO_MPORT_DRV_MAGIC, 5, struct rio_mport_maint_io) -#define RIO_MPORT_MAINT_WRITE_LOCAL \ - _IOW(RIO_MPORT_DRV_MAGIC, 6, struct rio_mport_maint_io) -#define RIO_MPORT_MAINT_READ_REMOTE \ - _IOR(RIO_MPORT_DRV_MAGIC, 7, struct rio_mport_maint_io) -#define RIO_MPORT_MAINT_WRITE_REMOTE \ - _IOW(RIO_MPORT_DRV_MAGIC, 8, struct rio_mport_maint_io) -#define RIO_ENABLE_DOORBELL_RANGE \ - _IOW(RIO_MPORT_DRV_MAGIC, 9, struct rio_doorbell_filter) -#define RIO_DISABLE_DOORBELL_RANGE \ - _IOW(RIO_MPORT_DRV_MAGIC, 10, struct rio_doorbell_filter) -#define RIO_ENABLE_PORTWRITE_RANGE \ - _IOW(RIO_MPORT_DRV_MAGIC, 11, struct rio_pw_filter) -#define RIO_DISABLE_PORTWRITE_RANGE \ - _IOW(RIO_MPORT_DRV_MAGIC, 12, struct rio_pw_filter) -#define RIO_SET_EVENT_MASK \ - _IOW(RIO_MPORT_DRV_MAGIC, 13, unsigned int) -#define RIO_GET_EVENT_MASK \ - _IOR(RIO_MPORT_DRV_MAGIC, 14, unsigned int) -#define RIO_MAP_OUTBOUND \ - _IOWR(RIO_MPORT_DRV_MAGIC, 15, struct rio_mmap) -#define RIO_UNMAP_OUTBOUND \ - _IOW(RIO_MPORT_DRV_MAGIC, 16, struct rio_mmap) -#define RIO_MAP_INBOUND \ - _IOWR(RIO_MPORT_DRV_MAGIC, 17, struct rio_mmap) -#define RIO_UNMAP_INBOUND \ - _IOW(RIO_MPORT_DRV_MAGIC, 18, uint64_t) -#define RIO_ALLOC_DMA \ - _IOWR(RIO_MPORT_DRV_MAGIC, 19, struct rio_dma_mem) -#define RIO_FREE_DMA \ - _IOW(RIO_MPORT_DRV_MAGIC, 20, uint64_t) -#define RIO_TRANSFER \ - _IOWR(RIO_MPORT_DRV_MAGIC, 21, struct rio_transaction) -#define RIO_WAIT_FOR_ASYNC \ - _IOW(RIO_MPORT_DRV_MAGIC, 22, struct rio_async_tx_wait) -#define RIO_DEV_ADD \ - _IOW(RIO_MPORT_DRV_MAGIC, 23, struct rio_rdev_info) -#define RIO_DEV_DEL \ - _IOW(RIO_MPORT_DRV_MAGIC, 24, struct rio_rdev_info) - -#endif /* _RIO_MPORT_CDEV_H_ */ diff --git a/include/uapi/linux/rio_mport_cdev.h b/include/uapi/linux/rio_mport_cdev.h new file mode 100644 index 000000000000..5796bf1d06ad --- /dev/null +++ b/include/uapi/linux/rio_mport_cdev.h @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2015-2016, Integrated Device Technology Inc. + * Copyright (c) 2015, Prodrive Technologies + * Copyright (c) 2015, Texas Instruments Incorporated + * Copyright (c) 2015, RapidIO Trade Association + * All rights reserved. + * + * This software is available to you under a choice of one of two licenses. + * You may choose to be licensed under the terms of the GNU General Public + * License(GPL) Version 2, or the BSD-3 Clause license below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RIO_MPORT_CDEV_H_ +#define _RIO_MPORT_CDEV_H_ + +#include +#include + +struct rio_mport_maint_io { + __u16 rioid; /* destID of remote device */ + __u8 hopcount; /* hopcount to remote device */ + __u8 pad0[5]; + __u32 offset; /* offset in register space */ + __u32 length; /* length in bytes */ + __u64 buffer; /* pointer to data buffer */ +}; + +/* + * Definitions for RapidIO data transfers: + * - memory mapped (MAPPED) + * - packet generation from memory (TRANSFER) + */ +#define RIO_TRANSFER_MODE_MAPPED (1 << 0) +#define RIO_TRANSFER_MODE_TRANSFER (1 << 1) +#define RIO_CAP_DBL_SEND (1 << 2) +#define RIO_CAP_DBL_RECV (1 << 3) +#define RIO_CAP_PW_SEND (1 << 4) +#define RIO_CAP_PW_RECV (1 << 5) +#define RIO_CAP_MAP_OUTB (1 << 6) +#define RIO_CAP_MAP_INB (1 << 7) + +struct rio_mport_properties { + __u16 hdid; + __u8 id; /* Physical port ID */ + __u8 index; + __u32 flags; + __u32 sys_size; /* Default addressing size */ + __u8 port_ok; + __u8 link_speed; + __u8 link_width; + __u8 pad0; + __u32 dma_max_sge; + __u32 dma_max_size; + __u32 dma_align; + __u32 transfer_mode; /* Default transfer mode */ + __u32 cap_sys_size; /* Capable system sizes */ + __u32 cap_addr_size; /* Capable addressing sizes */ + __u32 cap_transfer_mode; /* Capable transfer modes */ + __u32 cap_mport; /* Mport capabilities */ +}; + +/* + * Definitions for RapidIO events; + * - incoming port-writes + * - incoming doorbells + */ +#define RIO_DOORBELL (1 << 0) +#define RIO_PORTWRITE (1 << 1) + +struct rio_doorbell { + __u16 rioid; + __u16 payload; +}; + +struct rio_doorbell_filter { + __u16 rioid; /* Use RIO_INVALID_DESTID to match all ids */ + __u16 low; + __u16 high; + __u16 pad0; +}; + + +struct rio_portwrite { + __u32 payload[16]; +}; + +struct rio_pw_filter { + __u32 mask; + __u32 low; + __u32 high; + __u32 pad0; +}; + +/* RapidIO base address for inbound requests set to value defined below + * indicates that no specific RIO-to-local address translation is requested + * and driver should use direct (one-to-one) address mapping. +*/ +#define RIO_MAP_ANY_ADDR (__u64)(~((__u64) 0)) + +struct rio_mmap { + __u16 rioid; + __u16 pad0[3]; + __u64 rio_addr; + __u64 length; + __u64 handle; + __u64 address; +}; + +struct rio_dma_mem { + __u64 length; /* length of DMA memory */ + __u64 dma_handle; /* handle associated with this memory */ + __u64 address; +}; + +struct rio_event { + __u32 header; /* event type RIO_DOORBELL or RIO_PORTWRITE */ + union { + struct rio_doorbell doorbell; /* header for RIO_DOORBELL */ + struct rio_portwrite portwrite; /* header for RIO_PORTWRITE */ + } u; + __u32 pad0; +}; + +enum rio_transfer_sync { + RIO_TRANSFER_SYNC, /* synchronous transfer */ + RIO_TRANSFER_ASYNC, /* asynchronous transfer */ + RIO_TRANSFER_FAF, /* fire-and-forget transfer */ +}; + +enum rio_transfer_dir { + RIO_TRANSFER_DIR_READ, /* Read operation */ + RIO_TRANSFER_DIR_WRITE, /* Write operation */ +}; + +/* + * RapidIO data exchange transactions are lists of individual transfers. Each + * transfer exchanges data between two RapidIO devices by remote direct memory + * access and has its own completion code. + * + * The RapidIO specification defines four types of data exchange requests: + * NREAD, NWRITE, SWRITE and NWRITE_R. The RapidIO DMA channel interface allows + * to specify the required type of write operation or combination of them when + * only the last data packet requires response. + * + * NREAD: read up to 256 bytes from remote device memory into local memory + * NWRITE: write up to 256 bytes from local memory to remote device memory + * without confirmation + * SWRITE: as NWRITE, but all addresses and payloads must be 64-bit aligned + * NWRITE_R: as NWRITE, but expect acknowledgment from remote device. + * + * The default exchange is chosen from NREAD and any of the WRITE modes as the + * driver sees fit. For write requests the user can explicitly choose between + * any of the write modes for each transaction. + */ +enum rio_exchange { + RIO_EXCHANGE_DEFAULT, /* Default method */ + RIO_EXCHANGE_NWRITE, /* All packets using NWRITE */ + RIO_EXCHANGE_SWRITE, /* All packets using SWRITE */ + RIO_EXCHANGE_NWRITE_R, /* Last packet NWRITE_R, others NWRITE */ + RIO_EXCHANGE_SWRITE_R, /* Last packet NWRITE_R, others SWRITE */ + RIO_EXCHANGE_NWRITE_R_ALL, /* All packets using NWRITE_R */ +}; + +struct rio_transfer_io { + __u64 rio_addr; /* Address in target's RIO mem space */ + __u64 loc_addr; + __u64 handle; + __u64 offset; /* Offset in buffer */ + __u64 length; /* Length in bytes */ + __u16 rioid; /* Target destID */ + __u16 method; /* Data exchange method, one of rio_exchange enum */ + __u32 completion_code; /* Completion code for this transfer */ +}; + +struct rio_transaction { + __u64 block; /* Pointer to array of transfers */ + __u32 count; /* Number of transfers */ + __u32 transfer_mode; /* Data transfer mode */ + __u16 sync; /* Synch method, one of rio_transfer_sync enum */ + __u16 dir; /* Transfer direction, one of rio_transfer_dir enum */ + __u32 pad0; +}; + +struct rio_async_tx_wait { + __u32 token; /* DMA transaction ID token */ + __u32 timeout; /* Wait timeout in msec, if 0 use default TO */ +}; + +#define RIO_MAX_DEVNAME_SZ 20 + +struct rio_rdev_info { + __u16 destid; + __u8 hopcount; + __u8 pad0; + __u32 comptag; + char name[RIO_MAX_DEVNAME_SZ + 1]; +}; + +/* Driver IOCTL codes */ +#define RIO_MPORT_DRV_MAGIC 'm' + +#define RIO_MPORT_MAINT_HDID_SET \ + _IOW(RIO_MPORT_DRV_MAGIC, 1, __u16) +#define RIO_MPORT_MAINT_COMPTAG_SET \ + _IOW(RIO_MPORT_DRV_MAGIC, 2, __u32) +#define RIO_MPORT_MAINT_PORT_IDX_GET \ + _IOR(RIO_MPORT_DRV_MAGIC, 3, __u32) +#define RIO_MPORT_GET_PROPERTIES \ + _IOR(RIO_MPORT_DRV_MAGIC, 4, struct rio_mport_properties) +#define RIO_MPORT_MAINT_READ_LOCAL \ + _IOR(RIO_MPORT_DRV_MAGIC, 5, struct rio_mport_maint_io) +#define RIO_MPORT_MAINT_WRITE_LOCAL \ + _IOW(RIO_MPORT_DRV_MAGIC, 6, struct rio_mport_maint_io) +#define RIO_MPORT_MAINT_READ_REMOTE \ + _IOR(RIO_MPORT_DRV_MAGIC, 7, struct rio_mport_maint_io) +#define RIO_MPORT_MAINT_WRITE_REMOTE \ + _IOW(RIO_MPORT_DRV_MAGIC, 8, struct rio_mport_maint_io) +#define RIO_ENABLE_DOORBELL_RANGE \ + _IOW(RIO_MPORT_DRV_MAGIC, 9, struct rio_doorbell_filter) +#define RIO_DISABLE_DOORBELL_RANGE \ + _IOW(RIO_MPORT_DRV_MAGIC, 10, struct rio_doorbell_filter) +#define RIO_ENABLE_PORTWRITE_RANGE \ + _IOW(RIO_MPORT_DRV_MAGIC, 11, struct rio_pw_filter) +#define RIO_DISABLE_PORTWRITE_RANGE \ + _IOW(RIO_MPORT_DRV_MAGIC, 12, struct rio_pw_filter) +#define RIO_SET_EVENT_MASK \ + _IOW(RIO_MPORT_DRV_MAGIC, 13, __u32) +#define RIO_GET_EVENT_MASK \ + _IOR(RIO_MPORT_DRV_MAGIC, 14, __u32) +#define RIO_MAP_OUTBOUND \ + _IOWR(RIO_MPORT_DRV_MAGIC, 15, struct rio_mmap) +#define RIO_UNMAP_OUTBOUND \ + _IOW(RIO_MPORT_DRV_MAGIC, 16, struct rio_mmap) +#define RIO_MAP_INBOUND \ + _IOWR(RIO_MPORT_DRV_MAGIC, 17, struct rio_mmap) +#define RIO_UNMAP_INBOUND \ + _IOW(RIO_MPORT_DRV_MAGIC, 18, __u64) +#define RIO_ALLOC_DMA \ + _IOWR(RIO_MPORT_DRV_MAGIC, 19, struct rio_dma_mem) +#define RIO_FREE_DMA \ + _IOW(RIO_MPORT_DRV_MAGIC, 20, __u64) +#define RIO_TRANSFER \ + _IOWR(RIO_MPORT_DRV_MAGIC, 21, struct rio_transaction) +#define RIO_WAIT_FOR_ASYNC \ + _IOW(RIO_MPORT_DRV_MAGIC, 22, struct rio_async_tx_wait) +#define RIO_DEV_ADD \ + _IOW(RIO_MPORT_DRV_MAGIC, 23, struct rio_rdev_info) +#define RIO_DEV_DEL \ + _IOW(RIO_MPORT_DRV_MAGIC, 24, struct rio_rdev_info) + +#endif /* _RIO_MPORT_CDEV_H_ */ -- cgit v1.2.3 From 684283988f703811b8a05136d0d54f1c31025ad3 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Thu, 5 May 2016 16:22:09 -0700 Subject: huge pagecache: mmap_sem is unlocked when truncation splits pmd zap_pmd_range()'s CONFIG_DEBUG_VM !rwsem_is_locked(&mmap_sem) BUG() will be invalid with huge pagecache, in whatever way it is implemented: truncation of a hugely-mapped file to an unhugely-aligned size would easily hit it. (Although anon THP could in principle apply khugepaged to private file mappings, which are not excluded by the MADV_HUGEPAGE restrictions, in practice there's a vm_ops check which excludes them, so it never hits this BUG() - there's no interface to "truncate" an anonymous mapping.) We could complicate the test, to check i_mmap_rwsem also when there's a vm_file; but my inclination was to make zap_pmd_range() more readable by simply deleting this check. A search has shown no report of the issue in the years since commit e0897d75f0b2 ("mm, thp: print useful information when mmap_sem is unlocked in zap_pmd_range") expanded it from VM_BUG_ON() - though I cannot point to what commit I would say then fixed the issue. But there are a couple of other patches now floating around, neither yet in the tree: let's agree to retain the check as a VM_BUG_ON_VMA(), as Matthew Wilcox has done; but subject to a vma_is_anonymous() check, as Kirill Shutemov has done. And let's get this in, without waiting for any particular huge pagecache implementation to reach the tree. Matthew said "We can reproduce this BUG() in the current Linus tree with DAX PMDs". Signed-off-by: Hugh Dickins Tested-by: Matthew Wilcox Cc: "Kirill A. Shutemov" Cc: Andrea Arcangeli Cc: Andres Lagar-Cavilla Cc: Yang Shi Cc: Ning Qu Cc: Mel Gorman Cc: Andres Lagar-Cavilla Cc: Konstantin Khlebnikov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index 305537fc8640..52c218e2b724 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1222,15 +1222,8 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb, next = pmd_addr_end(addr, end); if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) { if (next - addr != HPAGE_PMD_SIZE) { -#ifdef CONFIG_DEBUG_VM - if (!rwsem_is_locked(&tlb->mm->mmap_sem)) { - pr_err("%s: mmap_sem is unlocked! addr=0x%lx end=0x%lx vma->vm_start=0x%lx vma->vm_end=0x%lx\n", - __func__, addr, end, - vma->vm_start, - vma->vm_end); - BUG(); - } -#endif + VM_BUG_ON_VMA(vma_is_anonymous(vma) && + !rwsem_is_locked(&tlb->mm->mmap_sem), vma); split_huge_pmd(vma, pmd, addr); } else if (zap_huge_pmd(tlb, vma, pmd, addr)) goto next; -- cgit v1.2.3 From bc22af74f271ef76b2e6f72f3941f91f0da3f5f8 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Thu, 5 May 2016 16:22:12 -0700 Subject: mm: update min_free_kbytes from khugepaged after core initialization Khugepaged attempts to raise min_free_kbytes if its set too low. However, on boot khugepaged sets min_free_kbytes first from subsys_initcall(), and then the mm 'core' over-rides min_free_kbytes after from init_per_zone_wmark_min(), via a module_init() call. Khugepaged used to use a late_initcall() to set min_free_kbytes (such that it occurred after the core initialization), however this was removed when the initialization of min_free_kbytes was integrated into the starting of the khugepaged thread. The fix here is simply to invoke the core initialization using a core_initcall() instead of module_init(), such that the previous initialization ordering is restored. I didn't restore the late_initcall() since start_stop_khugepaged() already sets min_free_kbytes via set_recommended_min_free_kbytes(). This was noticed when we had a number of page allocation failures when moving a workload to a kernel with this new initialization ordering. On an 8GB system this restores min_free_kbytes back to 67584 from 11365 when CONFIG_TRANSPARENT_HUGEPAGE=y is set and either CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y or CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y. Fixes: 79553da293d3 ("thp: cleanup khugepaged startup") Signed-off-by: Jason Baron Acked-by: Kirill A. Shutemov Acked-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 59de90d5d3a3..c1069efcc4d7 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -6485,7 +6485,7 @@ int __meminit init_per_zone_wmark_min(void) setup_per_zone_inactive_ratio(); return 0; } -module_init(init_per_zone_wmark_min) +core_initcall(init_per_zone_wmark_min) /* * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so -- cgit v1.2.3 From 14af4a5e9b26ad251f81c174e8a43f3e179434a5 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Thu, 5 May 2016 16:22:15 -0700 Subject: mm, cma: prevent nr_isolated_* counters from going negative /proc/sys/vm/stat_refresh warns nr_isolated_anon and nr_isolated_file go increasingly negative under compaction: which would add delay when should be none, or no delay when should delay. The bug in compaction was due to a recent mmotm patch, but much older instance of the bug was also noticed in isolate_migratepages_range() which is used for CMA and gigantic hugepage allocations. The bug is caused by putback_movable_pages() in an error path decrementing the isolated counters without them being previously incremented by acct_isolated(). Fix isolate_migratepages_range() by removing the error-path putback, thus reaching acct_isolated() with migratepages still isolated, and leaving putback to caller like most other places do. Fixes: edc2ca612496 ("mm, compaction: move pageblock checks up from isolate_migratepages_range()") [vbabka@suse.cz: expanded the changelog] Signed-off-by: Hugh Dickins Signed-off-by: Vlastimil Babka Acked-by: Joonsoo Kim Cc: Michal Hocko Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/compaction.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/mm/compaction.c b/mm/compaction.c index ccf97b02b85f..4a0d4b8ccde8 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -852,16 +852,8 @@ isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn, pfn = isolate_migratepages_block(cc, pfn, block_end_pfn, ISOLATE_UNEVICTABLE); - /* - * In case of fatal failure, release everything that might - * have been isolated in the previous iteration, and signal - * the failure back to caller. - */ - if (!pfn) { - putback_movable_pages(&cc->migratepages); - cc->nr_migratepages = 0; + if (!pfn) break; - } if (cc->nr_migratepages == COMPACT_CLUSTER_MAX) break; -- cgit v1.2.3 From ff2de822c94ca733a3f6177691eb0dca5ee2e658 Mon Sep 17 00:00:00 2001 From: Eric Engestrom Date: Thu, 5 May 2016 16:22:17 -0700 Subject: MAINTAINERS: fix Rajendra Nayak's address Signed-off-by: Eric Engestrom Cc: Rajendra Nayak Cc: Afzal Mohammed Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index ecbb2f6a3ba0..cdaf5c74a65b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7978,7 +7978,7 @@ F: arch/arm/*omap*/*pm* F: drivers/cpufreq/omap-cpufreq.c OMAP POWERDOMAIN SOC ADAPTATION LAYER SUPPORT -M: Rajendra Nayak +M: Rajendra Nayak M: Paul Walmsley L: linux-omap@vger.kernel.org S: Maintained -- cgit v1.2.3 From 127393fbe597dd85863a9bdccaa11007e7d4948f Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Thu, 5 May 2016 16:22:20 -0700 Subject: mm: thp: kvm: fix memory corruption in KVM with THP enabled After the THP refcounting change, obtaining a compound pages from get_user_pages() no longer allows us to assume the entire compound page is immediately mappable from a secondary MMU. A secondary MMU doesn't want to call get_user_pages() more than once for each compound page, in order to know if it can map the whole compound page. So a secondary MMU needs to know from a single get_user_pages() invocation when it can map immediately the entire compound page to avoid a flood of unnecessary secondary MMU faults and spurious atomic_inc()/atomic_dec() (pages don't have to be pinned by MMU notifier users). Ideally instead of the page->_mapcount < 1 check, get_user_pages() should return the granularity of the "page" mapping in the "mm" passed to get_user_pages(). However it's non trivial change to pass the "pmd" status belonging to the "mm" walked by get_user_pages up the stack (up to the caller of get_user_pages). So the fix just checks if there is not a single pte mapping on the page returned by get_user_pages, and in turn if the caller can assume that the whole compound page is mapped in the current "mm" (in a pmd_trans_huge()). In such case the entire compound page is safe to map into the secondary MMU without additional get_user_pages() calls on the surrounding tail/head pages. In addition of being faster, not having to run other get_user_pages() calls also reduces the memory footprint of the secondary MMU fault in case the pmd split happened as result of memory pressure. Without this fix after a MADV_DONTNEED (like invoked by QEMU during postcopy live migration or balloning) or after generic swapping (with a failure in split_huge_page() that would only result in pmd splitting and not a physical page split), KVM would map the whole compound page into the shadow pagetables, despite regular faults or userfaults (like UFFDIO_COPY) may map regular pages into the primary MMU as result of the pte faults, leading to the guest mode and userland mode going out of sync and not working on the same memory at all times. Any other secondary MMU notifier manager (KVM is just one of the many MMU notifier users) will need the same information if it doesn't want to run a flood of get_user_pages_fast and it can support multiple granularity in the secondary MMU mappings, so I think it is justified to be exposed not just to KVM. The other option would be to move transparent_hugepage_adjust to mm/huge_memory.c but that currently has all kind of KVM data structures in it, so it's definitely not a cut-and-paste work, so I couldn't do a fix as cleaner as this one for 4.6. Signed-off-by: Andrea Arcangeli Cc: "Dr. David Alan Gilbert" Cc: "Kirill A. Shutemov" Cc: "Li, Liang Z" Cc: Amit Shah Cc: Paolo Bonzini Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/kvm/mmu.c | 2 +- arch/x86/kvm/mmu.c | 4 ++-- include/linux/page-flags.h | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 58dbd5c439df..d6d4191e68f2 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -1004,7 +1004,7 @@ static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, phys_addr_t *ipap) kvm_pfn_t pfn = *pfnp; gfn_t gfn = *ipap >> PAGE_SHIFT; - if (PageTransCompound(pfn_to_page(pfn))) { + if (PageTransCompoundMap(pfn_to_page(pfn))) { unsigned long mask; /* * The address we faulted on is backed by a transparent huge diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 1ff4dbb73fb7..b6f50e8b0a39 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2823,7 +2823,7 @@ static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu, */ if (!is_error_noslot_pfn(pfn) && !kvm_is_reserved_pfn(pfn) && level == PT_PAGE_TABLE_LEVEL && - PageTransCompound(pfn_to_page(pfn)) && + PageTransCompoundMap(pfn_to_page(pfn)) && !mmu_gfn_lpage_is_disallowed(vcpu, gfn, PT_DIRECTORY_LEVEL)) { unsigned long mask; /* @@ -4785,7 +4785,7 @@ restart: */ if (sp->role.direct && !kvm_is_reserved_pfn(pfn) && - PageTransCompound(pfn_to_page(pfn))) { + PageTransCompoundMap(pfn_to_page(pfn))) { drop_spte(kvm, sptep); need_tlb_flush = 1; goto restart; diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index f4ed4f1b0c77..6b052aa7b5b7 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -516,6 +516,27 @@ static inline int PageTransCompound(struct page *page) return PageCompound(page); } +/* + * PageTransCompoundMap is the same as PageTransCompound, but it also + * guarantees the primary MMU has the entire compound page mapped + * through pmd_trans_huge, which in turn guarantees the secondary MMUs + * can also map the entire compound page. This allows the secondary + * MMUs to call get_user_pages() only once for each compound page and + * to immediately map the entire compound page with a single secondary + * MMU fault. If there will be a pmd split later, the secondary MMUs + * will get an update through the MMU notifier invalidation through + * split_huge_pmd(). + * + * Unlike PageTransCompound, this is safe to be called only while + * split_huge_pmd() cannot run from under us, like if protected by the + * MMU notifier, otherwise it may result in page->_mapcount < 0 false + * positives. + */ +static inline int PageTransCompoundMap(struct page *page) +{ + return PageTransCompound(page) && atomic_read(&page->_mapcount) < 0; +} + /* * PageTransTail returns true for both transparent huge pages * and hugetlbfs pages, so it should only be called when it's known @@ -559,6 +580,7 @@ static inline int TestClearPageDoubleMap(struct page *page) #else TESTPAGEFLAG_FALSE(TransHuge) TESTPAGEFLAG_FALSE(TransCompound) +TESTPAGEFLAG_FALSE(TransCompoundMap) TESTPAGEFLAG_FALSE(TransTail) TESTPAGEFLAG_FALSE(DoubleMap) TESTSETFLAG_FALSE(DoubleMap) -- cgit v1.2.3 From 32a4e169039927bfb6ee9f0ccbbe3a8aaf13a4bc Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 5 May 2016 16:22:23 -0700 Subject: mm/zswap: provide unique zpool name Instead of using "zswap" as the name for all zpools created, add an atomic counter and use "zswap%x" with the counter number for each zpool created, to provide a unique name for each new zpool. As zsmalloc, one of the zpool implementations, requires/expects a unique name for each pool created, zswap should provide a unique name. The zsmalloc pool creation does not fail if a new pool with a conflicting name is created, unless CONFIG_ZSMALLOC_STAT is enabled; in that case, zsmalloc pool creation fails with -ENOMEM. Then zswap will be unable to change its compressor parameter if its zpool is zsmalloc; it also will be unable to change its zpool parameter back to zsmalloc, if it has any existing old zpool using zsmalloc with page(s) in it. Attempts to change the parameters will result in failure to create the zpool. This changes zswap to provide a unique name for each zpool creation. Fixes: f1c54846ee45 ("zswap: dynamic pool creation") Signed-off-by: Dan Streetman Reported-by: Sergey Senozhatsky Reviewed-by: Sergey Senozhatsky Cc: Dan Streetman Cc: Minchan Kim Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/zswap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mm/zswap.c b/mm/zswap.c index 91dad80d068b..de0f119b1780 100644 --- a/mm/zswap.c +++ b/mm/zswap.c @@ -170,6 +170,8 @@ static struct zswap_tree *zswap_trees[MAX_SWAPFILES]; static LIST_HEAD(zswap_pools); /* protects zswap_pools list modification */ static DEFINE_SPINLOCK(zswap_pools_lock); +/* pool counter to provide unique names to zpool */ +static atomic_t zswap_pools_count = ATOMIC_INIT(0); /* used by param callback function */ static bool zswap_init_started; @@ -565,6 +567,7 @@ static struct zswap_pool *zswap_pool_find_get(char *type, char *compressor) static struct zswap_pool *zswap_pool_create(char *type, char *compressor) { struct zswap_pool *pool; + char name[38]; /* 'zswap' + 32 char (max) num + \0 */ gfp_t gfp = __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM; pool = kzalloc(sizeof(*pool), GFP_KERNEL); @@ -573,7 +576,10 @@ static struct zswap_pool *zswap_pool_create(char *type, char *compressor) return NULL; } - pool->zpool = zpool_create_pool(type, "zswap", gfp, &zswap_zpool_ops); + /* unique name for each pool specifically required by zsmalloc */ + snprintf(name, 38, "zswap%x", atomic_inc_return(&zswap_pools_count)); + + pool->zpool = zpool_create_pool(type, name, gfp, &zswap_zpool_ops); if (!pool->zpool) { pr_err("%s zpool not available\n", type); goto error; -- cgit v1.2.3 From 8148a73c9901a8794a50f950083c00ccf97d43b3 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 5 May 2016 16:22:26 -0700 Subject: proc: prevent accessing /proc//environ until it's ready If /proc//environ gets read before the envp[] array is fully set up in create_{aout,elf,elf_fdpic,flat}_tables(), we might end up trying to read more bytes than are actually written, as env_start will already be set but env_end will still be zero, making the range calculation underflow, allowing to read beyond the end of what has been written. Fix this as it is done for /proc//cmdline by testing env_end for zero. It is, apparently, intentionally set last in create_*_tables(). This bug was found by the PaX size_overflow plugin that detected the arithmetic underflow of 'this_len = env_end - (env_start + src)' when env_end is still zero. The expected consequence is that userland trying to access /proc//environ of a not yet fully set up process may get inconsistent data as we're in the middle of copying in the environment variables. Fixes: https://forums.grsecurity.net/viewtopic.php?f=3&t=4363 Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=116461 Signed-off-by: Mathias Krause Cc: Emese Revfy Cc: Pax Team Cc: Al Viro Cc: Mateusz Guzik Cc: Alexey Dobriyan Cc: Cyrill Gorcunov Cc: Jarod Wilson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/base.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index b1755b23893e..92e37e224cd2 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -955,7 +955,8 @@ static ssize_t environ_read(struct file *file, char __user *buf, struct mm_struct *mm = file->private_data; unsigned long env_start, env_end; - if (!mm) + /* Ensure the process spawned far enough to have an environment. */ + if (!mm || !mm->env_end) return 0; page = (char *)__get_free_page(GFP_TEMPORARY); -- cgit v1.2.3 From acbef7b7662953cec96c243db4009ac561d88989 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 5 May 2016 16:22:29 -0700 Subject: modpost: fix module autoloading for OF devices with generic compatible property Since the wildcard at the end of OF module aliases is gone, autoloading of modules that don't match a device's last (most generic) compatible value fails. For example the CODA960 VPU on i.MX6Q has the SoC specific compatible "fsl,imx6q-vpu" and the generic compatible "cnm,coda960". Since the driver currently only works with knowledge about the SoC specific integration, it doesn't list "cnm,cod960" in the module device table. This results in the device compatible "of:NvpuTCfsl,imx6q-vpuCcnm,coda960" not matching the module alias "of:N*T*Cfsl,imx6q-vpu" anymore, whereas before commit 2f632369ab79 ("modpost: don't add a trailing wildcard for OF module aliases") it matched the module alias "of:N*T*Cfsl,imx6q-vpu*". This patch adds two module aliases for each compatible, one without the wildcard and one with "C*" appended. $ modinfo coda | grep imx6q alias: of:N*T*Cfsl,imx6q-vpuC* alias: of:N*T*Cfsl,imx6q-vpu Fixes: 2f632369ab79 ("modpost: don't add a trailing wildcard for OF module aliases") Link: http://lkml.kernel.org/r/1462203339-15340-1-git-send-email-p.zabel@pengutronix.de Signed-off-by: Philipp Zabel Cc: Javier Martinez Canillas Cc: Brian Norris Cc: Sjoerd Simons Cc: Rusty Russell Cc: Greg Kroah-Hartman Cc: [4.5+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/mod/file2alias.c | 69 +++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 161dd0d67da8..a9155077feef 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -371,6 +371,49 @@ static void do_usb_table(void *symval, unsigned long size, do_usb_entry_multi(symval + i, mod); } +static void do_of_entry_multi(void *symval, struct module *mod) +{ + char alias[500]; + int len; + char *tmp; + + DEF_FIELD_ADDR(symval, of_device_id, name); + DEF_FIELD_ADDR(symval, of_device_id, type); + DEF_FIELD_ADDR(symval, of_device_id, compatible); + + len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*", + (*type)[0] ? *type : "*"); + + if (compatible[0]) + sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "", + *compatible); + + /* Replace all whitespace with underscores */ + for (tmp = alias; tmp && *tmp; tmp++) + if (isspace(*tmp)) + *tmp = '_'; + + buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); + strcat(alias, "C"); + add_wildcard(alias); + buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); +} + +static void do_of_table(void *symval, unsigned long size, + struct module *mod) +{ + unsigned int i; + const unsigned long id_size = SIZE_of_device_id; + + device_id_check(mod->name, "of", size, id_size, symval); + + /* Leave last one: it's the terminator. */ + size -= id_size; + + for (i = 0; i < size; i += id_size) + do_of_entry_multi(symval + i, mod); +} + /* Looks like: hid:bNvNpN */ static int do_hid_entry(const char *filename, void *symval, char *alias) @@ -684,30 +727,6 @@ static int do_pcmcia_entry(const char *filename, } ADD_TO_DEVTABLE("pcmcia", pcmcia_device_id, do_pcmcia_entry); -static int do_of_entry (const char *filename, void *symval, char *alias) -{ - int len; - char *tmp; - DEF_FIELD_ADDR(symval, of_device_id, name); - DEF_FIELD_ADDR(symval, of_device_id, type); - DEF_FIELD_ADDR(symval, of_device_id, compatible); - - len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*", - (*type)[0] ? *type : "*"); - - if (compatible[0]) - sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "", - *compatible); - - /* Replace all whitespace with underscores */ - for (tmp = alias; tmp && *tmp; tmp++) - if (isspace (*tmp)) - *tmp = '_'; - - return 1; -} -ADD_TO_DEVTABLE("of", of_device_id, do_of_entry); - static int do_vio_entry(const char *filename, void *symval, char *alias) { @@ -1348,6 +1367,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, /* First handle the "special" cases */ if (sym_is(name, namelen, "usb")) do_usb_table(symval, sym->st_size, mod); + if (sym_is(name, namelen, "of")) + do_of_table(symval, sym->st_size, mod); else if (sym_is(name, namelen, "pnp")) do_pnp_device_entry(symval, sym->st_size, mod); else if (sym_is(name, namelen, "pnp_card")) -- cgit v1.2.3 From 172400c69cb0d0d684b7cd75ac75872b3d7c61a1 Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Thu, 5 May 2016 16:22:32 -0700 Subject: mm: fix kcompactd hang during memory offlining Assume memory47 is the last online block left in node1. This will hang: # echo offline > /sys/devices/system/node/node1/memory47/state After a couple of minutes, the following pops up in dmesg: INFO: task bash:957 blocked for more than 120 seconds. Not tainted 4.6.0-rc6+ #6 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. bash D ffff8800b7adbaf8 0 957 951 0x00000000 Call Trace: schedule+0x35/0x80 schedule_timeout+0x1ac/0x270 wait_for_completion+0xe1/0x120 kthread_stop+0x4f/0x110 kcompactd_stop+0x26/0x40 __offline_pages.constprop.28+0x7e6/0x840 offline_pages+0x11/0x20 memory_block_action+0x73/0x1d0 memory_subsys_offline+0x47/0x60 device_offline+0x86/0xb0 store_mem_state+0xda/0xf0 dev_attr_store+0x18/0x30 sysfs_kf_write+0x37/0x40 kernfs_fop_write+0x11d/0x170 __vfs_write+0x37/0x120 vfs_write+0xa9/0x1a0 SyS_write+0x55/0xc0 entry_SYSCALL_64_fastpath+0x1a/0xa4 kcompactd is waiting for kcompactd_max_order > 0 when it's woken up to actually exit. Check kthread_should_stop() to break out of the wait. Fixes: 698b1b306 ("mm, compaction: introduce kcompactd"). Reported-by: Reza Arbab Tested-by: Reza Arbab Cc: Andrea Arcangeli Cc: "Kirill A. Shutemov" Cc: Rik van Riel Cc: Joonsoo Kim Cc: Mel Gorman Cc: David Rientjes Cc: Michal Hocko Cc: Johannes Weiner Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/compaction.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mm/compaction.c b/mm/compaction.c index 4a0d4b8ccde8..8fa254043801 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -1733,7 +1733,7 @@ void compaction_unregister_node(struct node *node) static inline bool kcompactd_work_requested(pg_data_t *pgdat) { - return pgdat->kcompactd_max_order > 0; + return pgdat->kcompactd_max_order > 0 || kthread_should_stop(); } static bool kcompactd_node_suitable(pg_data_t *pgdat) @@ -1797,6 +1797,8 @@ static void kcompactd_do_work(pg_data_t *pgdat) INIT_LIST_HEAD(&cc.freepages); INIT_LIST_HEAD(&cc.migratepages); + if (kthread_should_stop()) + return; status = compact_zone(zone, &cc); if (zone_watermark_ok(zone, cc.order, low_wmark_pages(zone), -- cgit v1.2.3 From 7c31190bcfdbff225950902a9f226e4eb79ca94f Mon Sep 17 00:00:00 2001 From: Joonsoo Kim Date: Thu, 5 May 2016 16:22:35 -0700 Subject: lib/stackdepot: avoid to return 0 handle Recently, we allow to save the stacktrace whose hashed value is 0. It causes the problem that stackdepot could return 0 even if in success. User of stackdepot cannot distinguish whether it is success or not so we need to solve this problem. In this patch, 1 bit are added to handle and make valid handle none 0 by setting this bit. After that, valid handle will not be 0 and 0 handle will represent failure correctly. Fixes: 33334e25769c ("lib/stackdepot.c: allow the stack trace hash to be zero") Link: http://lkml.kernel.org/r/1462252403-1106-1-git-send-email-iamjoonsoo.kim@lge.com Signed-off-by: Joonsoo Kim Cc: Alexander Potapenko Cc: Andrey Ryabinin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/stackdepot.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/stackdepot.c b/lib/stackdepot.c index 9e0b0315a724..53ad6c0831ae 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -42,12 +42,14 @@ #define DEPOT_STACK_BITS (sizeof(depot_stack_handle_t) * 8) +#define STACK_ALLOC_NULL_PROTECTION_BITS 1 #define STACK_ALLOC_ORDER 2 /* 'Slab' size order for stack depot, 4 pages */ #define STACK_ALLOC_SIZE (1LL << (PAGE_SHIFT + STACK_ALLOC_ORDER)) #define STACK_ALLOC_ALIGN 4 #define STACK_ALLOC_OFFSET_BITS (STACK_ALLOC_ORDER + PAGE_SHIFT - \ STACK_ALLOC_ALIGN) -#define STACK_ALLOC_INDEX_BITS (DEPOT_STACK_BITS - STACK_ALLOC_OFFSET_BITS) +#define STACK_ALLOC_INDEX_BITS (DEPOT_STACK_BITS - \ + STACK_ALLOC_NULL_PROTECTION_BITS - STACK_ALLOC_OFFSET_BITS) #define STACK_ALLOC_SLABS_CAP 1024 #define STACK_ALLOC_MAX_SLABS \ (((1LL << (STACK_ALLOC_INDEX_BITS)) < STACK_ALLOC_SLABS_CAP) ? \ @@ -59,6 +61,7 @@ union handle_parts { struct { u32 slabindex : STACK_ALLOC_INDEX_BITS; u32 offset : STACK_ALLOC_OFFSET_BITS; + u32 valid : STACK_ALLOC_NULL_PROTECTION_BITS; }; }; @@ -136,6 +139,7 @@ static struct stack_record *depot_alloc_stack(unsigned long *entries, int size, stack->size = size; stack->handle.slabindex = depot_index; stack->handle.offset = depot_offset >> STACK_ALLOC_ALIGN; + stack->handle.valid = 1; memcpy(stack->entries, entries, size * sizeof(unsigned long)); depot_offset += required_size; -- cgit v1.2.3 From 7322dd755e7dd34bc5359aa27abeed1687e0f628 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 5 May 2016 16:22:39 -0700 Subject: byteswap: try to avoid __builtin_constant_p gcc bug This is another attempt to avoid a regression in wwn_to_u64() after that started using get_unaligned_be64(), which in turn ran into a bug on gcc-4.9 through 6.1. The regression got introduced due to the combination of two separate workarounds (commits e3bde9568d99: "include/linux/unaligned: force inlining of byteswap operations" and ef3fb2422ffe: "scsi: fc: use get/put_unaligned64 for wwn access") that each try to sidestep distinct problems with gcc behavior (code growth and increased stack usage). Unfortunately after both have been applied, a more serious gcc bug has been uncovered, leading to incorrect object code that discards part of a function and causes undefined behavior. As part of this problem is how __builtin_constant_p gets evaluated on an argument passed by reference into an inline function, this avoids the use of __builtin_constant_p() for all architectures that set CONFIG_ARCH_USE_BUILTIN_BSWAP. Most architectures do not set ARCH_SUPPORTS_OPTIMIZED_INLINING, which means they probably do not suffer from the problem in the qla2xxx driver, but they might still run into it elsewhere. Both of the original workarounds were only merged in the 4.6 kernel, and the bug that is fixed by this patch should only appear if both are there, so we probably don't need to backport the fix. On the other hand, it works by simplifying the code path and should not have any negative effects. [arnd@arndb.de: fix older gcc warnings] (http://lkml.kernel.org/r/12243652.bxSxEgjgfk@wuerfel) Link: https://lkml.org/lkml/headers/2016/4/12/1103 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66122 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70232 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70646 Fixes: e3bde9568d99 ("include/linux/unaligned: force inlining of byteswap operations") Fixes: ef3fb2422ffe ("scsi: fc: use get/put_unaligned64 for wwn access") Link: http://lkml.kernel.org/r/1780465.XdtPJpi8Tt@wuerfel Signed-off-by: Arnd Bergmann Reviewed-by: Josh Poimboeuf Tested-by: Josh Poimboeuf # on gcc-5.3 Tested-by: Quinn Tran Cc: Martin Jambor Cc: "Martin K. Petersen" Cc: James Bottomley Cc: Denys Vlasenko Cc: Thomas Graf Cc: Peter Zijlstra Cc: David Rientjes Cc: Ingo Molnar Cc: Himanshu Madhani Cc: Jan Hubicka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/uapi/linux/swab.h | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/include/uapi/linux/swab.h b/include/uapi/linux/swab.h index 3f10e5317b46..8f3a8f606fd9 100644 --- a/include/uapi/linux/swab.h +++ b/include/uapi/linux/swab.h @@ -45,9 +45,7 @@ static inline __attribute_const__ __u16 __fswab16(__u16 val) { -#ifdef __HAVE_BUILTIN_BSWAP16__ - return __builtin_bswap16(val); -#elif defined (__arch_swab16) +#if defined (__arch_swab16) return __arch_swab16(val); #else return ___constant_swab16(val); @@ -56,9 +54,7 @@ static inline __attribute_const__ __u16 __fswab16(__u16 val) static inline __attribute_const__ __u32 __fswab32(__u32 val) { -#ifdef __HAVE_BUILTIN_BSWAP32__ - return __builtin_bswap32(val); -#elif defined(__arch_swab32) +#if defined(__arch_swab32) return __arch_swab32(val); #else return ___constant_swab32(val); @@ -67,9 +63,7 @@ static inline __attribute_const__ __u32 __fswab32(__u32 val) static inline __attribute_const__ __u64 __fswab64(__u64 val) { -#ifdef __HAVE_BUILTIN_BSWAP64__ - return __builtin_bswap64(val); -#elif defined (__arch_swab64) +#if defined (__arch_swab64) return __arch_swab64(val); #elif defined(__SWAB_64_THRU_32__) __u32 h = val >> 32; @@ -102,28 +96,40 @@ static inline __attribute_const__ __u32 __fswahb32(__u32 val) * __swab16 - return a byteswapped 16-bit value * @x: value to byteswap */ +#ifdef __HAVE_BUILTIN_BSWAP16__ +#define __swab16(x) (__u16)__builtin_bswap16((__u16)(x)) +#else #define __swab16(x) \ (__builtin_constant_p((__u16)(x)) ? \ ___constant_swab16(x) : \ __fswab16(x)) +#endif /** * __swab32 - return a byteswapped 32-bit value * @x: value to byteswap */ +#ifdef __HAVE_BUILTIN_BSWAP32__ +#define __swab32(x) (__u32)__builtin_bswap32((__u32)(x)) +#else #define __swab32(x) \ (__builtin_constant_p((__u32)(x)) ? \ ___constant_swab32(x) : \ __fswab32(x)) +#endif /** * __swab64 - return a byteswapped 64-bit value * @x: value to byteswap */ +#ifdef __HAVE_BUILTIN_BSWAP64__ +#define __swab64(x) (__u64)__builtin_bswap64((__u64)(x)) +#else #define __swab64(x) \ (__builtin_constant_p((__u64)(x)) ? \ ___constant_swab64(x) : \ __fswab64(x)) +#endif /** * __swahw32 - return a word-swapped 32-bit value -- cgit v1.2.3 From 43a3e837e22818c2c79dad95745a6b54d4e232f7 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 5 May 2016 20:07:14 -0700 Subject: mailmap: add John Paul Adrian Glaubitz Apparently patchwork ended up truncating the full name. Signed-off-by: Linus Torvalds --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index c156a8b4d845..08b80428f583 100644 --- a/.mailmap +++ b/.mailmap @@ -69,6 +69,7 @@ Jean Tourrilhes Jeff Garzik Jens Axboe Jens Osterkamp +John Paul Adrian Glaubitz John Stultz -- cgit v1.2.3 From 886123fb3a8656699dff40afa0573df359abeb18 Mon Sep 17 00:00:00 2001 From: Chen Yu Date: Fri, 6 May 2016 11:33:39 +0800 Subject: x86/tsc: Read all ratio bits from MSR_PLATFORM_INFO Currently we read the tsc radio: ratio = (MSR_PLATFORM_INFO >> 8) & 0x1f; Thus we get bit 8-12 of MSR_PLATFORM_INFO, however according to the SDM (35.5), the ratio bits are bit 8-15. Ignoring the upper bits can result in an incorrect tsc ratio, which causes the TSC calibration and the Local APIC timer frequency to be incorrect. Fix this problem by masking 0xff instead. [ tglx: Massaged changelog ] Fixes: 7da7c1561366 "x86, tsc: Add static (MSR) TSC calibration on Intel Atom SoCs" Signed-off-by: Chen Yu Cc: "Rafael J. Wysocki" Cc: stable@vger.kernel.org Cc: Bin Gao Cc: Len Brown Link: http://lkml.kernel.org/r/1462505619-5516-1-git-send-email-yu.c.chen@intel.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/tsc_msr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c index 92ae6acac8a7..6aa0f4d9eea6 100644 --- a/arch/x86/kernel/tsc_msr.c +++ b/arch/x86/kernel/tsc_msr.c @@ -92,7 +92,7 @@ unsigned long try_msr_calibrate_tsc(void) if (freq_desc_tables[cpu_index].msr_plat) { rdmsr(MSR_PLATFORM_INFO, lo, hi); - ratio = (lo >> 8) & 0x1f; + ratio = (lo >> 8) & 0xff; } else { rdmsr(MSR_IA32_PERF_STATUS, lo, hi); ratio = (hi >> 8) & 0x1f; -- cgit v1.2.3 From f0b22d1bb2a37a665a969e95785c75a4f49d1499 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Wed, 27 Apr 2016 04:56:11 +0300 Subject: parisc: fix a bug when syscall number of tracee is __NR_Linux_syscalls Do not load one entry beyond the end of the syscall table when the syscall number of a traced process equals to __NR_Linux_syscalls. Similar bug with regular processes was fixed by commit 3bb457af4fa8 ("[PARISC] Fix bug when syscall nr is __NR_Linux_syscalls"). This bug was found by strace test suite. Cc: stable@vger.kernel.org Signed-off-by: Dmitry V. Levin Acked-by: Helge Deller Signed-off-by: Helge Deller --- arch/parisc/kernel/syscall.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index c976ebfe2269..57b4836b7ecd 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -344,7 +344,7 @@ tracesys_next: #endif cmpib,COND(=),n -1,%r20,tracesys_exit /* seccomp may have returned -1 */ - comiclr,>>= __NR_Linux_syscalls, %r20, %r0 + comiclr,>> __NR_Linux_syscalls, %r20, %r0 b,n .Ltracesys_nosys LDREGX %r20(%r19), %r19 -- cgit v1.2.3 From 44549e8f5eea4e0a41b487b63e616cb089922b99 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 8 May 2016 14:38:32 -0700 Subject: Linux 4.6-rc7 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7466de60ddc7..acf6155421cc 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc7 NAME = Charred Weasel # *DOCUMENTATION* -- cgit v1.2.3 From 54d5ca871e72f2bb172ec9323497f01cd5091ec7 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 11 May 2016 01:16:37 +0200 Subject: vfs: add vfs_select_inode() helper Signed-off-by: Miklos Szeredi Cc: # v4.2+ --- fs/open.c | 12 ++++-------- include/linux/dcache.h | 12 ++++++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/fs/open.c b/fs/open.c index 17cb6b1dab75..081d3d6df74b 100644 --- a/fs/open.c +++ b/fs/open.c @@ -840,16 +840,12 @@ EXPORT_SYMBOL(file_path); int vfs_open(const struct path *path, struct file *file, const struct cred *cred) { - struct dentry *dentry = path->dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = vfs_select_inode(path->dentry, file->f_flags); - file->f_path = *path; - if (dentry->d_flags & DCACHE_OP_SELECT_INODE) { - inode = dentry->d_op->d_select_inode(dentry, file->f_flags); - if (IS_ERR(inode)) - return PTR_ERR(inode); - } + if (IS_ERR(inode)) + return PTR_ERR(inode); + file->f_path = *path; return do_dentry_open(file, inode, NULL, cred); } diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 4bb4de8d95ea..7e9422cb5989 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -565,4 +565,16 @@ static inline struct dentry *d_real(struct dentry *dentry) return dentry; } +static inline struct inode *vfs_select_inode(struct dentry *dentry, + unsigned open_flags) +{ + struct inode *inode = d_inode(dentry); + + if (inode && unlikely(dentry->d_flags & DCACHE_OP_SELECT_INODE)) + inode = dentry->d_op->d_select_inode(dentry, open_flags); + + return inode; +} + + #endif /* __LINUX_DCACHE_H */ -- cgit v1.2.3 From 9409e22acdfc9153f88d9b1ed2bd2a5b34d2d3ca Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 11 May 2016 01:16:37 +0200 Subject: vfs: rename: check backing inode being equal If a file is renamed to a hardlink of itself POSIX specifies that rename(2) should do nothing and return success. This condition is checked in vfs_rename(). However it won't detect hard links on overlayfs where these are given separate inodes on the overlayfs layer. Overlayfs itself detects this condition and returns success without doing anything, but then vfs_rename() will proceed as if this was a successful rename (detach_mounts(), d_move()). The correct thing to do is to detect this condition before even calling into overlayfs. This patch does this by calling vfs_select_inode() to get the underlying inodes. Signed-off-by: Miklos Szeredi Cc: # v4.2+ --- fs/namei.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index 1d9ca2d5dff6..3ef87d673bbe 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4213,7 +4213,11 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, bool new_is_dir = false; unsigned max_links = new_dir->i_sb->s_max_links; - if (source == target) + /* + * Check source == target. + * On overlayfs need to look at underlying inodes. + */ + if (vfs_select_inode(old_dentry, 0) == vfs_select_inode(new_dentry, 0)) return 0; error = may_delete(old_dir, old_dentry, is_dir); -- cgit v1.2.3 From 3c9fe8cdff1b889a059a30d22f130372f2b3885f Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 11 May 2016 01:16:37 +0200 Subject: vfs: add lookup_hash() helper Overlayfs needs lookup without inode_permission() and already has the name hash (in form of dentry->d_name on overlayfs dentry). It also doesn't support filesystems with d_op->d_hash() so basically it only needs the actual hashed lookup from lookup_one_len_unlocked() So add a new helper that does unlocked lookup of a hashed name. Signed-off-by: Miklos Szeredi --- fs/namei.c | 33 ++++++++++++++++++++++++++++----- include/linux/namei.h | 2 ++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 3ef87d673bbe..1a1ea79a7ba0 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2266,6 +2266,33 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, } EXPORT_SYMBOL(vfs_path_lookup); +/** + * lookup_hash - lookup single pathname component on already hashed name + * @name: name and hash to lookup + * @base: base directory to lookup from + * + * The name must have been verified and hashed (see lookup_one_len()). Using + * this after just full_name_hash() is unsafe. + * + * This function also doesn't check for search permission on base directory. + * + * Use lookup_one_len_unlocked() instead, unless you really know what you are + * doing. + * + * Do not hold i_mutex; this helper takes i_mutex if necessary. + */ +struct dentry *lookup_hash(const struct qstr *name, struct dentry *base) +{ + struct dentry *ret; + + ret = lookup_dcache(name, base, 0); + if (!ret) + ret = lookup_slow(name, base, 0); + + return ret; +} +EXPORT_SYMBOL(lookup_hash); + /** * lookup_one_len - filesystem helper to lookup single pathname component * @name: pathname component to lookup @@ -2337,7 +2364,6 @@ struct dentry *lookup_one_len_unlocked(const char *name, struct qstr this; unsigned int c; int err; - struct dentry *ret; this.name = name; this.len = len; @@ -2369,10 +2395,7 @@ struct dentry *lookup_one_len_unlocked(const char *name, if (err) return ERR_PTR(err); - ret = lookup_dcache(&this, base, 0); - if (!ret) - ret = lookup_slow(&this, base, 0); - return ret; + return lookup_hash(&this, base); } EXPORT_SYMBOL(lookup_one_len_unlocked); diff --git a/include/linux/namei.h b/include/linux/namei.h index 77d01700daf7..ec5ec2818a28 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -79,6 +79,8 @@ extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int); extern struct dentry *lookup_one_len(const char *, struct dentry *, int); extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int); +struct qstr; +extern struct dentry *lookup_hash(const struct qstr *, struct dentry *); extern int follow_down_one(struct path *); extern int follow_down(struct path *); -- cgit v1.2.3 From 38b78a5f18584db6fa7441e0f4531b283b0e6725 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 11 May 2016 01:16:37 +0200 Subject: ovl: ignore permissions on underlying lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generally permission checking is not necessary when overlayfs looks up a dentry on one of the underlying layers, since search permission on base directory was already checked in ovl_permission(). More specifically using lookup_one_len() causes a problem when the lower directory lacks search permission for a specific user while the upper directory does have search permission. Since lookups are cached, this causes inconsistency in behavior: success depends on who did the first lookup. So instead use lookup_hash() which doesn't do the permission check. Reported-by: Ignacy Gawędzki Signed-off-by: Miklos Szeredi --- fs/overlayfs/super.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 5d972e6cd3fe..791235e03d17 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -411,9 +411,7 @@ static inline struct dentry *ovl_lookup_real(struct dentry *dir, { struct dentry *dentry; - inode_lock(dir->d_inode); - dentry = lookup_one_len(name->name, dir, name->len); - inode_unlock(dir->d_inode); + dentry = lookup_hash(name, dir); if (IS_ERR(dentry)) { if (PTR_ERR(dentry) == -ENOENT) -- cgit v1.2.3