From de3b7a06dfe15bda3e66a52285d422b954bb4832 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Thu, 4 Dec 2014 09:46:20 +0100 Subject: xfrm6: Fix transport header offset in _decode_session6. skb->transport_header might not be valid when we do a reverse decode because the ipv6 tunnel error handlers don't update it to the inner transport header. This leads to a wrong offset calculation and to wrong layer 4 informations. We fix this by using the size of the ipv6 header as the first offset. Signed-off-by: Steffen Klassert diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 5f98364..aa48302 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -130,8 +130,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) { struct flowi6 *fl6 = &fl->u.ip6; int onlyproto = 0; - u16 offset = skb_network_header_len(skb); const struct ipv6hdr *hdr = ipv6_hdr(skb); + u16 offset = sizeof(*hdr); struct ipv6_opt_hdr *exthdr; const unsigned char *nh = skb_network_header(skb); u8 nexthdr = nh[IP6CB(skb)->nhoff]; -- cgit v0.10.2 From f855691975bb06373a98711e4cfe2c224244b536 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Mon, 8 Dec 2014 07:56:18 +0100 Subject: xfrm6: Fix the nexthdr offset in _decode_session6. xfrm_decode_session() was originally designed for the usage in the receive path where the correct nexthdr offset is stored in IP6CB(skb)->nhoff. Over time this function spread to code that is used in the output path (netfilter, vti) where IP6CB(skb)->nhoff is not set. As a result, we get a wrong nexthdr and the upper layer flow informations are wrong. This can leed to incorrect policy lookups. Signed-off-by: Steffen Klassert diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index aa48302..48bf5a0 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -134,8 +134,14 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) u16 offset = sizeof(*hdr); struct ipv6_opt_hdr *exthdr; const unsigned char *nh = skb_network_header(skb); - u8 nexthdr = nh[IP6CB(skb)->nhoff]; + u16 nhoff = IP6CB(skb)->nhoff; int oif = 0; + u8 nexthdr; + + if (!nhoff) + nhoff = offsetof(struct ipv6hdr, nexthdr); + + nexthdr = nh[nhoff]; if (skb_dst(skb)) oif = skb_dst(skb)->dev->ifindex; -- cgit v0.10.2 From 2eacc608b3bf3519fc353c558454873f4589146d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 26 Nov 2014 11:35:35 +0100 Subject: iio: ad799x: Fix ad7991/ad7995/ad7999 config setup The ad7991/ad7995/ad7999 does not have a configuration register like the other devices that can be written and read. The configuration is written as part of the conversion sequence. Fixes: 0f7ddcc1bff1 ("iio:adc:ad799x: Write default config on probe and reset alert status on probe") Signed-off-by: Lars-Peter Clausen Tested-by: Mike Looijmans Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index e37412d..b99de00 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -143,9 +143,15 @@ static int ad799x_write_config(struct ad799x_state *st, u16 val) case ad7998: return i2c_smbus_write_word_swapped(st->client, AD7998_CONF_REG, val); - default: + case ad7992: + case ad7993: + case ad7994: return i2c_smbus_write_byte_data(st->client, AD7998_CONF_REG, val); + default: + /* Will be written when doing a conversion */ + st->config = val; + return 0; } } @@ -155,8 +161,13 @@ static int ad799x_read_config(struct ad799x_state *st) case ad7997: case ad7998: return i2c_smbus_read_word_swapped(st->client, AD7998_CONF_REG); - default: + case ad7992: + case ad7993: + case ad7994: return i2c_smbus_read_byte_data(st->client, AD7998_CONF_REG); + default: + /* No readback support */ + return st->config; } } -- cgit v0.10.2 From d034f53cc6c5c09a4e10cb9716986f3844c58514 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 17 Dec 2014 14:40:42 +0100 Subject: ARM: shmobile: r8a7740: Instantiate GIC from C board code in legacy builds As of commit 9a1091ef0017c40a ("irqchip: gic: Support hierarchy irq domain."), armadillo-legacy hangs during boot with: sh-tmu.0: ch0: used for clock events sh-tmu.0: ch0: used for periodic clock events sh-tmu.0: ch0: failed to request irq 230 sh-tmu.0: ch1: used as clock source sh-cmt-48.1: ch0: failed to request irq 90 sh-cmt-48.1: ch0: registration failed earlytimer: unable to probe sh-cmt-48 early. Calibrating delay loop... This happens because the IRQ numbers of the GIC are now virtual, and no longer match the hardcoded hardware IRQ numbers in the platform board code. To fix this, instantiate the GIC from platform board code when compiling a legacy kernel, like is done on sh73a0 for kzm9g-legacy. Signed-off-by: Geert Uytterhoeven Acked-by: Marc Zyngier Signed-off-by: Simon Horman diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 0bfe226..e76e2f8 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -793,7 +793,14 @@ void __init r8a7740_init_irq_of(void) void __iomem *intc_msk_base = ioremap_nocache(0xe6900040, 0x10); void __iomem *pfc_inta_ctrl = ioremap_nocache(0xe605807c, 0x4); +#ifdef CONFIG_ARCH_SHMOBILE_LEGACY + void __iomem *gic_dist_base = ioremap_nocache(0xc2800000, 0x1000); + void __iomem *gic_cpu_base = ioremap_nocache(0xc2000000, 0x1000); + + gic_init(0, 29, gic_dist_base, gic_cpu_base); +#else irqchip_init(); +#endif /* route signals to GIC */ iowrite32(0x0, pfc_inta_ctrl); -- cgit v0.10.2 From 6618e478954d2866754798c3b07805dc9dbb2fc4 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Wed, 10 Dec 2014 12:55:29 -0800 Subject: ARM: dts: rockchip: bump sd card pin drive strength up on rk3288-evb It seems that ever since (536f6b9 mmc: dw_mmc: Reset DMA before enabling IDMAC) landed upstream that SD cards have been very unhappy on rk3288-evb. They were a little unhappy before that change, but after that change they're REALLY unhappy. It turns out that the above fix happens to fix a corruption when reading card information during probe time. Without the fix we didn't detect that high speed SD cards could actually support high speed. With the fix we suddenly detect that they're high speed and we try to use them at 50MHz. That doesn't work so well on EVB with the default drive strength (maybe because there are two physical SD card slots hooked up to the same pin?). Fix the problem by bumping up the drive strength of the sdmmc lines. Signed-off-by: Doug Anderson Fixes: 536f6b91d21b ("mmc: dw_mmc: Reset DMA before enabling IDMAC") Signed-off-by: Heiko Stuebner diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi index 3e067dd..6194d67 100644 --- a/arch/arm/boot/dts/rk3288-evb.dtsi +++ b/arch/arm/boot/dts/rk3288-evb.dtsi @@ -155,6 +155,15 @@ }; &pinctrl { + pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma { + drive-strength = <8>; + }; + + pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma { + bias-pull-up; + drive-strength = <8>; + }; + backlight { bl_en: bl-en { rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>; @@ -173,6 +182,27 @@ }; }; + sdmmc { + /* + * Default drive strength isn't enough to achieve even + * high-speed mode on EVB board so bump up to 8ma. + */ + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_8ma>, + <6 17 RK_FUNC_1 &pcfg_pull_up_drv_8ma>, + <6 18 RK_FUNC_1 &pcfg_pull_up_drv_8ma>, + <6 19 RK_FUNC_1 &pcfg_pull_up_drv_8ma>; + }; + + sdmmc_clk: sdmmc-clk { + rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none_drv_8ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_8ma>; + }; + }; + usb { host_vbus_drv: host-vbus-drv { rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>; -- cgit v0.10.2 From caa6934ac70b1dd7d1d4939961da5b23f305d968 Mon Sep 17 00:00:00 2001 From: Julien CHAUVEAU Date: Fri, 12 Dec 2014 22:05:52 +0100 Subject: clk: rockchip: add CLK_IGNORE_UNUSED flag to fix rk3066/rk3188 USB Host This patch adds CLK_IGNORE_UNUSED flag to hclk_usb_peri, hclk_usbotg0 and hclk_usbotg1 because these clocks must remain enabled to use the USB controllers in host mode. This fixes a regression introduced by commit 78eaf6095cc7 ("clk: rockchip: disable unused clocks"). Signed-off-by: Julien CHAUVEAU Fixes: 78eaf6095cc7 ("clk: rockchip: disable unused clocks") Reviewed-by: Romain Perier Tested-by: Romain Perier Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index c540789..5d33cad 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -430,8 +430,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS), GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), - GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 5, GFLAGS), - GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 13, GFLAGS), + GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 5, GFLAGS), + GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS), GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS), GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS), GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS), @@ -592,7 +592,8 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS), GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), - GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), + GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(5), 14, GFLAGS), GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS), @@ -680,7 +681,8 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), - GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), + GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(7), 3, GFLAGS), GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS), -- cgit v0.10.2 From 5039d16abe250102c021557184950c47566170a4 Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Fri, 12 Dec 2014 17:50:39 +0000 Subject: clk: rockchip: Fix clock gate for rk3188 hclk_emem_peri Do not disable clock gate "hclk_emem_peri", otherwise EMAC clocks no longer work and it breaks ethernet on RK3066 and RK3188. It fixes a regression introduced by commit 78eaf6095cc7 ("clk: rockchip: disable unused clocks"). Signed-off-by: Romain Perier Fixes: 78eaf6095cc7 ("clk: rockchip: disable unused clocks") Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 5d33cad..b32fcda 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -427,7 +427,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { /* hclk_peri gates */ GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS), - GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS), + GATE(0, "hclk_emem_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 7, GFLAGS), GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 5, GFLAGS), -- cgit v0.10.2 From 0ce3c066c49aa0bc3b98c0293f8f28d683dec768 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 22 Dec 2014 20:57:13 +0530 Subject: MAINTAINERS: dmaengine: fix the header file for dmaengine The headers were listed as include/linux/dma* which is wrong as we have other files in include/linux/dma* which have nothing to do with dmaengine so update it to include/linux/dmaengine.h Signed-off-by: Vinod Koul diff --git a/MAINTAINERS b/MAINTAINERS index ddb9ac8..5c24ae7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3182,7 +3182,7 @@ L: dmaengine@vger.kernel.org Q: https://patchwork.kernel.org/project/linux-dmaengine/list/ S: Maintained F: drivers/dma/ -F: include/linux/dma* +F: include/linux/dmaengine.h F: Documentation/dmaengine/ T: git git://git.infradead.org/users/vkoul/slave-dma.git -- cgit v0.10.2 From 449a7e99fd00c2c9416ef06e3f38e226a3ab1e8a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 26 Nov 2014 08:01:36 -0600 Subject: usb: musb: debugfs: cope with blackfin's oddities Blackfin's MUSB implementation lacks a bunch of registers which they end up not defining a macro for. In order to avoid build breaks, let's ifdef out some of the registers from our regdump debugfs utility so that we don't try to use those on Blackfin builds. Reported-by: Fengguang Wu Signed-off-by: Felipe Balbi diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index ad3701a..54e8cde 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -59,20 +59,12 @@ static const struct musb_register_map musb_regmap[] = { { "RxMaxPp", MUSB_RXMAXP, 16 }, { "RxCSR", MUSB_RXCSR, 16 }, { "RxCount", MUSB_RXCOUNT, 16 }, - { "ConfigData", MUSB_CONFIGDATA,8 }, { "IntrRxE", MUSB_INTRRXE, 16 }, { "IntrTxE", MUSB_INTRTXE, 16 }, { "IntrUsbE", MUSB_INTRUSBE, 8 }, { "DevCtl", MUSB_DEVCTL, 8 }, - { "BabbleCtl", MUSB_BABBLE_CTL,8 }, - { "TxFIFOsz", MUSB_TXFIFOSZ, 8 }, - { "RxFIFOsz", MUSB_RXFIFOSZ, 8 }, - { "TxFIFOadd", MUSB_TXFIFOADD, 16 }, - { "RxFIFOadd", MUSB_RXFIFOADD, 16 }, { "VControl", 0x68, 32 }, { "HWVers", 0x69, 16 }, - { "EPInfo", MUSB_EPINFO, 8 }, - { "RAMInfo", MUSB_RAMINFO, 8 }, { "LinkInfo", MUSB_LINKINFO, 8 }, { "VPLen", MUSB_VPLEN, 8 }, { "HS_EOF1", MUSB_HS_EOF1, 8 }, @@ -103,6 +95,16 @@ static const struct musb_register_map musb_regmap[] = { { "DMA_CNTLch7", 0x274, 16 }, { "DMA_ADDRch7", 0x278, 32 }, { "DMA_COUNTch7", 0x27C, 32 }, +#ifndef CONFIG_BLACKFIN + { "ConfigData", MUSB_CONFIGDATA,8 }, + { "BabbleCtl", MUSB_BABBLE_CTL,8 }, + { "TxFIFOsz", MUSB_TXFIFOSZ, 8 }, + { "RxFIFOsz", MUSB_RXFIFOSZ, 8 }, + { "TxFIFOadd", MUSB_TXFIFOADD, 16 }, + { "RxFIFOadd", MUSB_RXFIFOADD, 16 }, + { "EPInfo", MUSB_EPINFO, 8 }, + { "RAMInfo", MUSB_RAMINFO, 8 }, +#endif { } /* Terminating Entry */ }; -- cgit v0.10.2 From b1d347830d811f3648a52d28700896c6c404d609 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 26 Nov 2014 08:01:37 -0600 Subject: usb: musb: blackfin: fix build break commit cc92f681 (usb: musb: Populate new IO functions for blackfin) added a typo which prevented MUSB's blackfin glue layer from being built. Due to lack of tests and compilers for that architecture, the typo ended up being merged and causing a build regression. Fix that here Cc: Tony Lindgren Reported-by: Fengguang Wu Signed-off-by: Felipe Balbi diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index a441a2d..1782501 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -63,7 +63,7 @@ static void bfin_writew(void __iomem *addr, unsigned offset, u16 data) bfin_write16(addr + offset, data); } -static void binf_writel(void __iomem *addr, unsigned offset, u32 data) +static void bfin_writel(void __iomem *addr, unsigned offset, u32 data) { bfin_write16(addr + offset, (u16)data); } -- cgit v0.10.2 From e87c3f80ad0490d26ffe04754b7d094463b40f30 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Thu, 27 Nov 2014 22:25:45 +0100 Subject: usb: musb: Fix a few off-by-one lengths !strncmp(buf, "force host", 9) is true if and only if buf starts with "force hos". This was obviously not what was intended. The same error exists for "force full-speed", "force high-speed" and "test packet". Using strstarts avoids the error-prone hardcoding of the prefix length. For consistency, also change the other occurences of the !strncmp idiom. Signed-off-by: Rasmus Villemoes Signed-off-by: Felipe Balbi diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index f64fd96..c39a16a 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -628,9 +628,9 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) ret = of_property_read_string_index(np, "dma-names", i, &str); if (ret) goto err; - if (!strncmp(str, "tx", 2)) + if (strstarts(str, "tx")) is_tx = 1; - else if (!strncmp(str, "rx", 2)) + else if (strstarts(str, "rx")) is_tx = 0; else { dev_err(dev, "Wrong dmatype %s\n", str); diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 54e8cde..48131aa 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -199,30 +199,30 @@ static ssize_t musb_test_mode_write(struct file *file, if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) return -EFAULT; - if (!strncmp(buf, "force host", 9)) + if (strstarts(buf, "force host")) test = MUSB_TEST_FORCE_HOST; - if (!strncmp(buf, "fifo access", 11)) + if (strstarts(buf, "fifo access")) test = MUSB_TEST_FIFO_ACCESS; - if (!strncmp(buf, "force full-speed", 15)) + if (strstarts(buf, "force full-speed")) test = MUSB_TEST_FORCE_FS; - if (!strncmp(buf, "force high-speed", 15)) + if (strstarts(buf, "force high-speed")) test = MUSB_TEST_FORCE_HS; - if (!strncmp(buf, "test packet", 10)) { + if (strstarts(buf, "test packet")) { test = MUSB_TEST_PACKET; musb_load_testpacket(musb); } - if (!strncmp(buf, "test K", 6)) + if (strstarts(buf, "test K")) test = MUSB_TEST_K; - if (!strncmp(buf, "test J", 6)) + if (strstarts(buf, "test J")) test = MUSB_TEST_J; - if (!strncmp(buf, "test SE0 NAK", 12)) + if (strstarts(buf, "test SE0 NAK")) test = MUSB_TEST_SE0_NAK; musb_writeb(musb->mregs, MUSB_TESTMODE, test); -- cgit v0.10.2 From 4fde6204df052bb89ba3d915ed6ed9f306f3cfa1 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 1 Dec 2014 16:09:27 +0800 Subject: usb: gadget: f_uac1: access freed memory at f_audio_free_inst At f_audio_free_inst, it tries to access struct gaudio *card which is freed at f_audio_free, it causes below oops if the audio device is not there (do unload module may trigger the same problem). The gaudio_cleanup is related to function, so it is better move to f_audio_free. root@freescale ~$ modprobe g_audio [ 751.968931] g_audio gadget: unable to open sound control device file: /dev/snd/controlC0 [ 751.977134] g_audio gadget: we need at least one control device [ 751.988633] Unable to handle kernel paging request at virtual address 455f448e [ 751.995963] pgd = bd42c000 [ 751.998681] [455f448e] *pgd=00000000 [ 752.002383] Internal error: Oops: 5 [#1] SMP ARM [ 752.007008] Modules linked in: usb_f_uac1 g_audio(+) usb_f_mass_storage libcomposite configfs [last unloaded: g_mass_storage] [ 752.018427] CPU: 0 PID: 692 Comm: modprobe Not tainted 3.18.0-rc4-00345-g842f57b #10 [ 752.026176] task: bdb3ba80 ti: bd41a000 task.ti: bd41a000 [ 752.031590] PC is at filp_close+0xc/0x84 [ 752.035530] LR is at gaudio_cleanup+0x28/0x54 [usb_f_uac1] [ 752.041023] pc : [<800ec94c>] lr : [<7f03c63c>] psr: 20000013 [ 752.041023] sp : bd41bcc8 ip : bd41bce8 fp : bd41bce4 [ 752.052504] r10: 7f036234 r9 : 7f036220 r8 : 7f036500 [ 752.057732] r7 : bd456480 r6 : 7f036500 r5 : 7f03626c r4 : bd441000 [ 752.064264] r3 : 7f03b3dc r2 : 7f03cab0 r1 : 00000000 r0 : 455f4456 [ 752.070798] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user [ 752.077938] Control: 10c5387d Table: bd42c04a DAC: 00000015 [ 752.083688] Process modprobe (pid: 692, stack limit = 0xbd41a240) [ 752.089786] Stack: (0xbd41bcc8 to 0xbd41c000) [ 752.094152] bcc0: 7f03b3dc bd441000 7f03626c 7f036500 bd41bcfc bd41bce8 [ 752.102337] bce0: 7f03c63c 800ec94c 7f03b3dc bdaa6b00 bd41bd14 bd41bd00 7f03b3f4 7f03c620 [ 752.110521] bd00: 7f03b3dc 7f03cbd4 bd41bd2c bd41bd18 7f00f88c 7f03b3e8 00000000 fffffffe [ 752.118705] bd20: bd41bd5c bd41bd30 7f0380d8 7f00f874 7f038000 bd456480 7f036364 be392240 [ 752.126889] bd40: 00000000 7f00f620 7f00f638 bd41a008 bd41bd94 bd41bd60 7f00f6d4 7f03800c [ 752.135073] bd60: 00000001 00000000 8047438c be3a4000 7f036364 7f036364 7f00db28 7f00f620 [ 752.143257] bd80: 7f00f638 bd41a008 bd41bdb4 bd41bd98 804742ac 7f00f644 00000000 809adde0 [ 752.151442] bda0: 7f036364 7f036364 bd41bdcc bd41bdb8 804743c8 80474284 7f03633c 7f036200 [ 752.159626] bdc0: bd41bdf4 bd41bdd0 7f00d5b4 8047435c bd41a000 80974060 7f038158 00000000 [ 752.167811] bde0: 80974060 bdaa9940 bd41be04 bd41bdf8 7f03816c 7f00d518 bd41be8c bd41be08 [ 752.175995] be00: 80008a5c 7f038164 be001f00 7f0363c4 bd41bf48 00000000 bd41be54 bd41be28 [ 752.184179] be20: 800e9498 800e8e74 00000002 00000003 bd4129c0 c0a07000 00000001 7f0363c4 [ 752.192363] be40: bd41bf48 00000000 bd41be74 bd41be58 800de780 800e9320 bd41a000 7f0363d0 [ 752.200547] be60: 00000000 bd41a000 7f0363d0 00000000 bd41beec 7f0363c4 bd41bf48 00000000 [ 752.208731] be80: bd41bf44 bd41be90 80093e54 800089e0 ffff8000 00007fff 80091390 0000065f [ 752.216915] bea0: 00000000 c0a0834c bd41bf7c 00000086 bd41bf50 00000000 7f03651c 00000086 [ 752.225099] bec0: bd41a010 00c28758 800ddcc4 800ddae0 000000d2 bd412a00 bd41bf24 00000000 [ 752.233283] bee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 752.241467] bf00: 00000000 00000000 00000000 00000000 00000000 00000000 bd41bf44 000025b0 [ 752.249651] bf20: 00c28a08 00c28758 00000080 8000edc4 bd41a000 00000000 bd41bfa4 bd41bf48 [ 752.257835] bf40: 800943e4 800932ec c0a07000 000025b0 c0a07f8c c0a07ea4 c0a08e5c 0000051c [ 752.266019] bf60: 0000088c 00000000 00000000 00000000 00000018 00000019 00000010 0000000b [ 752.274203] bf80: 00000009 00000000 00000000 000025b0 00000000 00c28758 00000000 bd41bfa8 [ 752.282387] bfa0: 8000ec00 8009430c 000025b0 00000000 00c28a08 000025b0 00c28758 00c28980 [ 752.290571] bfc0: 000025b0 00000000 00c28758 00000080 000a6a78 00000007 00c28718 00c28980 [ 752.298756] bfe0: 7ebc1af0 7ebc1ae0 0001a32c 76e9c490 60000010 00c28a08 22013510 ecebffff [ 752.306933] Backtrace: [ 752.309414] [<800ec940>] (filp_close) from [<7f03c63c>] (gaudio_cleanup+0x28/0x54 [usb_f_uac1]) [ 752.318115] r6:7f036500 r5:7f03626c r4:bd441000 r3:7f03b3dc [ 752.323851] [<7f03c614>] (gaudio_cleanup [usb_f_uac1]) from [<7f03b3f4>] (f_audio_free_inst+0x18/0x68 [usb_f_uac1]) [ 752.334288] r4:bdaa6b00 r3:7f03b3dc [ 752.337931] [<7f03b3dc>] (f_audio_free_inst [usb_f_uac1]) from [<7f00f88c>] (usb_put_function_instance+0x24/0x30 [libcomposite]) [ 752.349498] r4:7f03cbd4 r3:7f03b3dc [ 752.353127] [<7f00f868>] (usb_put_function_instance [libcomposite]) from [<7f0380d8>] (audio_bind+0xd8/0xfc [g_audio]) [ 752.363824] r4:fffffffe r3:00000000 [ 752.367456] [<7f038000>] (audio_bind [g_audio]) from [<7f00f6d4>] (composite_bind+0x9c/0x1e8 [libcomposite]) [ 752.377284] r10:bd41a008 r9:7f00f638 r8:7f00f620 r7:00000000 r6:be392240 r5:7f036364 [ 752.385193] r4:bd456480 r3:7f038000 [ 752.388825] [<7f00f638>] (composite_bind [libcomposite]) from [<804742ac>] (udc_bind_to_driver+0x34/0xd8) [ 752.398394] r10:bd41a008 r9:7f00f638 r8:7f00f620 r7:7f00db28 r6:7f036364 r5:7f036364 [ 752.406302] r4:be3a4000 [ 752.408860] [<80474278>] (udc_bind_to_driver) from [<804743c8>] (usb_gadget_probe_driver+0x78/0xa8) [ 752.417908] r6:7f036364 r5:7f036364 r4:809adde0 r3:00000000 [ 752.423649] [<80474350>] (usb_gadget_probe_driver) from [<7f00d5b4>] (usb_composite_probe+0xa8/0xd4 [libcomposite]) [ 752.434086] r5:7f036200 r4:7f03633c [ 752.437713] [<7f00d50c>] (usb_composite_probe [libcomposite]) from [<7f03816c>] (audio_driver_init+0x14/0x1c [g_audio]) [ 752.448498] r9:bdaa9940 r8:80974060 r7:00000000 r6:7f038158 r5:80974060 r4:bd41a000 [ 752.456330] [<7f038158>] (audio_driver_init [g_audio]) from [<80008a5c>] (do_one_initcall+0x88/0x1d4) [ 752.465564] [<800089d4>] (do_one_initcall) from [<80093e54>] (load_module+0xb74/0x1020) [ 752.473571] r10:00000000 r9:bd41bf48 r8:7f0363c4 r7:bd41beec r6:00000000 r5:7f0363d0 [ 752.481478] r4:bd41a000 [ 752.484037] [<800932e0>] (load_module) from [<800943e4>] (SyS_init_module+0xe4/0xf8) [ 752.491781] r10:00000000 r9:bd41a000 r8:8000edc4 r7:00000080 r6:00c28758 r5:00c28a08 [ 752.499689] r4:000025b0 [ 752.502252] [<80094300>] (SyS_init_module) from [<8000ec00>] (ret_fast_syscall+0x0/0x48) [ 752.510345] r6:00c28758 r5:00000000 r4:000025b0 [ 752.515013] Code: 808475b4 e1a0c00d e92dd878 e24cb004 (e5904038) [ 752.521223] ---[ end trace 70babe34de4ab99b ]--- Segmentation fault Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index f7b2032..e971584 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -897,7 +897,6 @@ static void f_audio_free_inst(struct usb_function_instance *f) struct f_uac1_opts *opts; opts = container_of(f, struct f_uac1_opts, func_inst); - gaudio_cleanup(opts->card); if (opts->fn_play_alloc) kfree(opts->fn_play); if (opts->fn_cap_alloc) @@ -935,6 +934,7 @@ static void f_audio_free(struct usb_function *f) struct f_audio *audio = func_to_audio(f); struct f_uac1_opts *opts; + gaudio_cleanup(&audio->card); opts = container_of(f->fi, struct f_uac1_opts, func_inst); kfree(audio); mutex_lock(&opts->lock); -- cgit v0.10.2 From c0442479652b99b62dd1ffccb34231caff25751c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 1 Dec 2014 11:10:15 -0800 Subject: usb: musb: Fix randconfig build issues for Kconfig options Commit 82c02f58ba3a ("usb: musb: Allow multiple glue layers to be built in") enabled selecting multiple glue layers, which in turn exposed things more for randconfig builds. If NOP_USB_XCEIV is built-in and TUSB6010 is a loadable module, we will get: drivers/built-in.o: In function `tusb_remove': tusb6010.c:(.text+0x16a817): undefined reference to `usb_phy_generic_unregister' drivers/built-in.o: In function `tusb_probe': tusb6010.c:(.text+0x16b24e): undefined reference to `usb_phy_generic_register' make: *** [vmlinux] Error 1 Let's fix this the same way as commit 70c1ff4b3c86 ("usb: musb: tusb-dma can't be built-in if tusb is not"). And while at it, let's not allow selecting the glue layers except on platforms really using them unless COMPILE_TEST is specified: - TUSB6010 is in practise only used on omaps - DSPS is only used on TI platforms - UX500 is only used on STE platforms Cc: Linus Walleij Reported-by: Jim Davis Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 9d68372..b005010 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -72,6 +72,8 @@ config USB_MUSB_DA8XX config USB_MUSB_TUSB6010 tristate "TUSB6010" + depends on ARCH_OMAP2PLUS || COMPILE_TEST + depends on NOP_USB_XCEIV = USB_MUSB_HDRC # both built-in or both modules config USB_MUSB_OMAP2PLUS tristate "OMAP2430 and onwards" @@ -85,6 +87,7 @@ config USB_MUSB_AM35X config USB_MUSB_DSPS tristate "TI DSPS platforms" select USB_MUSB_AM335X_CHILD + depends on ARCH_OMAP2PLUS || COMPILE_TEST depends on OF_IRQ config USB_MUSB_BLACKFIN @@ -93,6 +96,7 @@ config USB_MUSB_BLACKFIN config USB_MUSB_UX500 tristate "Ux500 platforms" + depends on ARCH_U8500 || COMPILE_TEST config USB_MUSB_JZ4740 tristate "JZ4740" -- cgit v0.10.2 From c9b3bde03b95cf1cab068f773435cfee271baf0b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 7 Dec 2014 20:21:00 +0100 Subject: usb: gadget: fix misspelling of current function in string Replace a misspelled function name by %s and then __func__. This was done using Coccinelle, including the use of Levenshtein distance, as proposed by Rasmus Villemoes. Signed-off-by: Julia Lawall Signed-off-by: Felipe Balbi diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 6e04e30..a1bc3e3 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -399,8 +399,9 @@ static int hidg_setup(struct usb_function *f, value = __le16_to_cpu(ctrl->wValue); length = __le16_to_cpu(ctrl->wLength); - VDBG(cdev, "hid_setup crtl_request : bRequestType:0x%x bRequest:0x%x " - "Value:0x%x\n", ctrl->bRequestType, ctrl->bRequest, value); + VDBG(cdev, + "%s crtl_request : bRequestType:0x%x bRequest:0x%x Value:0x%x\n", + __func__, ctrl->bRequestType, ctrl->bRequest, value); switch ((ctrl->bRequestType << 8) | ctrl->bRequest) { case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a904403..259b656 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -520,7 +520,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req) req = midi_alloc_ep_req(ep, midi->buflen); if (!req) { - ERROR(midi, "gmidi_transmit: alloc_ep_request failed\n"); + ERROR(midi, "%s: alloc_ep_request failed\n", __func__); return; } req->length = 0; -- cgit v0.10.2 From 62f4f0651ce8ef966a0e5b6db6a7a524c268fdd2 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Tue, 9 Dec 2014 14:41:45 +0100 Subject: usb: dwc2: gadget: kill requests with 'force' in s3c_hsotg_udc_stop() This makes us sure that all requests are completed before we unbind gadget. There are assumptions in gadget API that all requests have to be completed and leak of complete can break some usb function drivers. For example unbind of ECM function can cause NULL pointer dereference: [ 26.396595] configfs-gadget gadget: unbind function 'cdc_ethernet'/e79c4c00 [ 26.414999] Unable to handle kernel NULL pointer dereference at virtual address 00000000 (...) [ 26.452223] PC is at ecm_unbind+0x6c/0x9c [ 26.456209] LR is at ecm_unbind+0x68/0x9c (...) [ 26.603696] [] (ecm_unbind) from [] (purge_configs_funcs+0x94/0xd8) [ 26.611674] [] (purge_configs_funcs) from [] (configfs_composite_unbind+0x14/0x34) [ 26.620961] [] (configfs_composite_unbind) from [] (usb_gadget_remove_driver+0x68/0x9c) [ 26.630683] [] (usb_gadget_remove_driver) from [] (usb_gadget_unregister_driver+0x64/0x94) [ 26.640664] [] (usb_gadget_unregister_driver) from [] (unregister_gadget+0x20/0x3c) [ 26.650038] [] (unregister_gadget) from [] (gadget_dev_desc_UDC_store+0x80/0xb8) [ 26.659152] [] (gadget_dev_desc_UDC_store) from [] (gadget_info_attr_store+0x1c/0x28) [ 26.668703] [] (gadget_info_attr_store) from [] (configfs_write_file+0xe8/0x148) [ 26.677818] [] (configfs_write_file) from [] (vfs_write+0xb0/0x1a0) [ 26.685801] [] (vfs_write) from [] (SyS_write+0x44/0x84) [ 26.692834] [] (SyS_write) from [] (ret_fast_syscall+0x0/0x30) [ 26.700381] Code: e30409f8 e34c0069 eb07b88d e59430a8 (e5930000) [ 26.706485] ---[ end trace f62a082b323838a2 ]--- It's because in some cases request is still running on endpoint during unbind and kill_all_requests() called from s3c_hsotg_udc_stop() function doesn't cause call of complete() of request. Missing complete() call causes ecm->notify_req equals NULL in ecm_unbind() function, and this is reason of this bug. Similar breaks can be observed in another usb function drivers. This patch fixes this bug forcing usb request completion in when s3c_hsotg_ep_disable() is called from s3c_hsotg_udc_stop(). Acked-by: Paul Zimmerman Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 200168e..7924200 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2567,7 +2567,7 @@ error: * s3c_hsotg_ep_disable - disable given endpoint * @ep: The endpoint to disable. */ -static int s3c_hsotg_ep_disable(struct usb_ep *ep) +static int s3c_hsotg_ep_disable_force(struct usb_ep *ep, bool force) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hsotg = hs_ep->parent; @@ -2588,7 +2588,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) spin_lock_irqsave(&hsotg->lock, flags); /* terminate all requests with shutdown */ - kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); + kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, force); hsotg->fifo_map &= ~(1<fifo_index); hs_ep->fifo_index = 0; @@ -2609,6 +2609,10 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) return 0; } +static int s3c_hsotg_ep_disable(struct usb_ep *ep) +{ + return s3c_hsotg_ep_disable_force(ep, false); +} /** * on_list - check request is on the given endpoint * @ep: The endpoint to check. @@ -2924,7 +2928,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) /* all endpoints should be shutdown */ for (ep = 1; ep < hsotg->num_of_eps; ep++) - s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); + s3c_hsotg_ep_disable_force(&hsotg->eps[ep].ep, true); spin_lock_irqsave(&hsotg->lock, flags); -- cgit v0.10.2 From 68693b8ea4e284c46bff919ac62bd9ccdfdbb6ba Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 11 Dec 2014 18:14:18 +0100 Subject: usb: musb: stuff leak of struct usb_hcd since the split of host+gadget mode in commit 74c2e9360058 ("usb: musb: factor out hcd initalization") we leak the usb_hcd struct. We call now musb_host_cleanup() which does basically usb_remove_hcd() and also sets the hcd variable to NULL. Doing so makes the finall call to musb_host_free() basically a nop and the usb_hcd remains around for ever without anowner. This patch drops that NULL assignment for that reason. Fixes: 74c2e9360058 ("usb: musb: factor out hcd initalization") Cc: # v3.11+ Cc: Daniel Mack Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 23d474d..883a9ad 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2663,7 +2663,6 @@ void musb_host_cleanup(struct musb *musb) if (musb->port_mode == MUSB_PORT_MODE_GADGET) return; usb_remove_hcd(musb->hcd); - musb->hcd = NULL; } void musb_host_free(struct musb *musb) -- cgit v0.10.2 From b44be2462dbe3e23f0aedff64de52a1e8e47a1cd Mon Sep 17 00:00:00 2001 From: Mario Schuknecht Date: Tue, 16 Dec 2014 08:58:57 +0100 Subject: usb: gadget: gadgetfs: Free memory allocated by memdup_user() Commit 3b74c73f8d6f053f422e85fce955b61fb181cfe7 switched over to memdup_user() in ep_write() function and removed kfree (kbuf). memdup_user() function allocates memory which is never freed. Fixes: 3b74c73 (usb: gadget: inode: switch over to memdup_user()) Cc: # v3.15+ Signed-off-by: Mario Schuknecht Signed-off-by: Felipe Balbi diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index c744e49..0804861 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -449,6 +449,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) data->name, len, (int) value); free1: mutex_unlock(&data->lock); + kfree (kbuf); return value; } -- cgit v0.10.2 From 84a2b61b6eb94036093531cdabc448dddfbae45a Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Thu, 18 Dec 2014 16:39:14 +0200 Subject: usb: dwc3: pci: add support for Intel Sunrise Point PCH Add PCI IDs for Intel Sunrise Point PCH. Signed-off-by: Heikki Krogerus Signed-off-by: Felipe Balbi diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 7c4faf7..b642a2f 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -33,6 +33,8 @@ #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e #define PCI_DEVICE_ID_INTEL_BSW 0x22B7 +#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 +#define PCI_DEVICE_ID_INTEL_SPTH 0xa130 struct dwc3_pci { struct device *dev; @@ -219,6 +221,8 @@ static const struct pci_device_id dwc3_pci_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, { } /* Terminating Entry */ }; -- cgit v0.10.2 From f40afdddeb6c54ffd1e2920a5e93e363d6748db6 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Wed, 17 Dec 2014 17:18:48 +0800 Subject: usb: gadget: udc: atmel: change setting for DMA According to the datasheet, when transfer using DMA, the control setting for IN packet only need END_BUF_EN, END_BUF_IE, CH_EN, while for OUT packet, need more two bits END_TR_EN and END_TR_IE to be configured. Fixes: 914a3f3b3754 (USB: add atmel_usba_udc driver) Cc: # 2.6.24+ Acked-by: Nicolas Ferre Signed-off-by: Bo Shen Signed-off-by: Felipe Balbi diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index ce88237..63e90f5 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -716,10 +716,10 @@ static int queue_dma(struct usba_udc *udc, struct usba_ep *ep, req->using_dma = 1; req->ctrl = USBA_BF(DMA_BUF_LEN, req->req.length) | USBA_DMA_CH_EN | USBA_DMA_END_BUF_IE - | USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE; + | USBA_DMA_END_BUF_EN; - if (ep->is_in) - req->ctrl |= USBA_DMA_END_BUF_EN; + if (!ep->is_in) + req->ctrl |= USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE; /* * Add this request to the queue and submit for DMA if -- cgit v0.10.2 From 6785a1034461c2d2c205215f63a50a740896e55b Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Wed, 17 Dec 2014 17:18:49 +0800 Subject: usb: gadget: udc: atmel: fix possible IN hang issue When receive data, the RXRDY in status register set by hardware after a new packet has been stored in the endpoint FIFO. When it is copied from FIFO, this bit is cleared which make the FIFO can be accessed again. In the receive_data() function, this bit RXRDY has been cleared. So, after the receive_data() function return, this bit should not be cleared again, or else it may cause the accessing FIFO corrupt, which will make the data loss. Fixes: 914a3f3b3754 (USB: add atmel_usba_udc driver) Cc: # 2.6.24+ Acked-by: Nicolas Ferre Signed-off-by: Bo Shen Signed-off-by: Felipe Balbi diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 63e90f5..93328ea 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -1563,7 +1563,6 @@ static void usba_ep_irq(struct usba_udc *udc, struct usba_ep *ep) if ((epstatus & epctrl) & USBA_RX_BK_RDY) { DBG(DBG_BUS, "%s: RX data ready\n", ep->ep.name); receive_data(ep); - usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); } } -- cgit v0.10.2 From 574732c73d155320f9358d9ee5d84beb0f4ecee2 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 23 Dec 2014 15:05:36 +1030 Subject: param: initialize store function to NULL if not available. I rebased Kees' 'param: do not set store func without write perm' on top of my 'params: cleanup sysfs allocation'. However, my patch uses krealloc which doesn't zero memory, leaving .store unset. Reported-by: Sasha Levin Cc: Kees Cook Signed-off-by: Rusty Russell diff --git a/kernel/params.c b/kernel/params.c index 0af9b2c..bd65d136 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -648,6 +648,8 @@ static __modinit int add_sysfs_param(struct module_kobject *mk, /* Do not allow runtime DAC changes to make param writable. */ if ((kp->perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0) mk->mp->attrs[mk->mp->num].mattr.store = param_attr_store; + else + mk->mp->attrs[mk->mp->num].mattr.store = NULL; mk->mp->attrs[mk->mp->num].mattr.attr.name = (char *)name; mk->mp->attrs[mk->mp->num].mattr.attr.mode = kp->perm; mk->mp->num++; -- cgit v0.10.2 From 4e038e8919e072c9fa1b5462a7c89d8c95ac8657 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 17 Dec 2014 02:55:23 +0300 Subject: phy: miphy28lp: unlock on error in miphy28lp_init() We need to unlock before returning the -EINVAL here. Signed-off-by: Dan Carpenter Acked-by: Gabriel Fernandez Signed-off-by: Kishon Vijay Abraham I diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index e34da13..27fa62c 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c @@ -1050,7 +1050,8 @@ static int miphy28lp_init(struct phy *phy) ret = miphy28lp_init_usb3(miphy_phy); break; default: - return -EINVAL; + ret = -EINVAL; + break; } mutex_unlock(&miphy_dev->miphy_mutex); -- cgit v0.10.2 From 372400344afb60e275a271f3f5ccce17af0e45cb Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 17 Dec 2014 15:39:37 +0100 Subject: phy-sun4i-usb: Change disconnect threshold value for sun6i The allwinner SDK uses a value of 3 for the disconnect threshold setting on sun6i, do the same in the kernel. In my previous experience with sun5i problems getting the threshold right is important to avoid usb2 devices being unplugged sometimes going unnoticed. Signed-off-by: Hans de Goede Signed-off-by: Kishon Vijay Abraham I diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index fb02a67..a2b08f3c 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c @@ -244,7 +244,8 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) else data->num_phys = 3; - if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy")) + if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy") || + of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy")) data->disc_thresh = 3; else data->disc_thresh = 2; -- cgit v0.10.2 From 0bc09f9cdc589e0b54724096138996a00b19babb Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Tue, 16 Dec 2014 14:52:50 +0530 Subject: phy: phy-ti-pipe3: fix inconsistent enumeration of PCIe gen2 cards Prior to DRA74x silicon rev 1.1, pcie_pcs register bits 8-15 and bits 16-23 were used to configure RC delay count for phy1 and phy2 respectively. phyid was used as index to distinguish the phys and to configure the delay values appropriately. As of DRA74x silicon rev 1.1, pcie_pcs register definition has changed. Bits 16-23 are used to configure delay values for *both* phy1 and phy2. Hence phyid is no longer required. So, drop id field from ti_pipe3 structure and its subsequent references for configuring pcie_pcs register. Also, pcie_pcs register now needs to be configured with delay value of 0x96 at bit positions 16-23. See register description of CTRL_CORE_PCIE_PCS in ARM572x TRM, SPRUHZ6, October 2014, section 18.5.2.2, table 18-1804. This is needed to ensure Gen2 cards are enumerated consistently. DRA72x silicon behaves same way as DRA74x rev 1.1 as far as this functionality is considered. Test results on DRA74x and DRA72x EVMs: Before patch ------------ DRA74x ES 1.0: Gen1 cards work, Gen2 cards do not work (expected result due to silicon errata) DRA74x ES 1.1: Gen1 cards work, Gen2 cards do not work sometimes due to incorrect programming of register DRA72x: Gen1 cards work, Gen2 cards do not work sometimes due to incorrect programming of register After patch ----------- DRA74x ES 1.0: Gen1 cards work, Gen2 cards do not work (expected result due to silicon errata) DRA74x ES 1.1: Gen1 cards work, Gen2 cards work consistently. DRA72x: Gen1 and Gen2 cards enumerate consistently. Signed-off-by: Vignesh R Signed-off-by: Kishon Vijay Abraham I diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c index c96e818..efe724f 100644 --- a/drivers/phy/phy-omap-control.c +++ b/drivers/phy/phy-omap-control.c @@ -29,10 +29,9 @@ /** * omap_control_pcie_pcs - set the PCS delay count * @dev: the control module device - * @id: index of the pcie PHY (should be 1 or 2) * @delay: 8 bit delay value */ -void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) +void omap_control_pcie_pcs(struct device *dev, u8 delay) { u32 val; struct omap_control_phy *control_phy; @@ -55,8 +54,8 @@ void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) val = readl(control_phy->pcie_pcs); val &= ~(OMAP_CTRL_PCIE_PCS_MASK << - (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT)); - val |= delay << (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); + OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); + val |= (delay << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); writel(val, control_phy->pcie_pcs); } EXPORT_SYMBOL_GPL(omap_control_pcie_pcs); diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 1387b4d..465de2c 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -82,7 +82,6 @@ struct ti_pipe3 { struct clk *refclk; struct clk *div_clk; struct pipe3_dpll_map *dpll_map; - u8 id; }; static struct pipe3_dpll_map dpll_map_usb[] = { @@ -217,8 +216,13 @@ static int ti_pipe3_init(struct phy *x) u32 val; int ret = 0; + /* + * Set pcie_pcs register to 0x96 for proper functioning of phy + * as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table + * 18-1804. + */ if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { - omap_control_pcie_pcs(phy->control_dev, phy->id, 0xF1); + omap_control_pcie_pcs(phy->control_dev, 0x96); return 0; } @@ -347,8 +351,6 @@ static int ti_pipe3_probe(struct platform_device *pdev) } if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - if (of_property_read_u8(node, "id", &phy->id) < 0) - phy->id = 1; clk = devm_clk_get(phy->dev, "dpll_ref"); if (IS_ERR(clk)) { diff --git a/include/linux/phy/omap_control_phy.h b/include/linux/phy/omap_control_phy.h index e9e6cfb..eb7d4a1 100644 --- a/include/linux/phy/omap_control_phy.h +++ b/include/linux/phy/omap_control_phy.h @@ -66,7 +66,7 @@ enum omap_control_usb_mode { #define OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF 0x0 #define OMAP_CTRL_PCIE_PCS_MASK 0xff -#define OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT 0x8 +#define OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT 16 #define OMAP_CTRL_USB2_PHY_PD BIT(28) @@ -79,7 +79,7 @@ enum omap_control_usb_mode { void omap_control_phy_power(struct device *dev, int on); void omap_control_usb_set_mode(struct device *dev, enum omap_control_usb_mode mode); -void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay); +void omap_control_pcie_pcs(struct device *dev, u8 delay); #else static inline void omap_control_phy_power(struct device *dev, int on) @@ -91,7 +91,7 @@ static inline void omap_control_usb_set_mode(struct device *dev, { } -static inline void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) +static inline void omap_control_pcie_pcs(struct device *dev, u8 delay) { } #endif -- cgit v0.10.2 From c818a94c77a9980709197c53368aa83451fd659f Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 4 Dec 2014 13:06:07 +0100 Subject: usb: phy: Restore deferred probing path Commit 1290a958d48e ("usb: phy: propagate __of_usb_find_phy()'s error on failure") broke platforms that rely on deferred probing to order probing of PHY and host controller drivers. The reason is that the commit simply propagates errors from __of_usb_find_phy(), which returns -ENODEV if no PHY has been registered yet for a given device tree node. The only case in which -EPROBE_DEFER would now be returned is if try_module_get() did fail, which does not make sense. The correct thing to do is to return -EPROBE_DEFER if a PHY hasn't been registered yet. The only condition under which it makes sense to return -ENODEV is if the device tree node representing the PHY has been disabled (via the status property) because in that case the PHY will never be registered. This patch addresses the problem by making __of_usb_find_phy() return an appropriate error code while keeping in line with the above-mentioned commit to propagate error codes rather than overwriting them. At the same time the check for a valid PHY is decoupled from the check for the try_module_get() call and a separate error code is returned if the latter fails. Fixes: 1290a95 (usb: phy: propagate __of_usb_find_phy()'s error on failure) Signed-off-by: Thierry Reding Signed-off-by: Felipe Balbi diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index b4066a0..2f9735b 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -59,6 +59,9 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node) { struct usb_phy *phy; + if (!of_device_is_available(node)) + return ERR_PTR(-ENODEV); + list_for_each_entry(phy, &phy_list, head) { if (node != phy->dev->of_node) continue; @@ -66,7 +69,7 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node) return phy; } - return ERR_PTR(-ENODEV); + return ERR_PTR(-EPROBE_DEFER); } static void devm_usb_phy_release(struct device *dev, void *res) @@ -190,10 +193,13 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, spin_lock_irqsave(&phy_lock, flags); phy = __of_usb_find_phy(node); - if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { - if (!IS_ERR(phy)) - phy = ERR_PTR(-EPROBE_DEFER); + if (IS_ERR(phy)) { + devres_free(ptr); + goto err1; + } + if (!try_module_get(phy->dev->driver->owner)) { + phy = ERR_PTR(-ENODEV); devres_free(ptr); goto err1; } -- cgit v0.10.2 From 12551f0239b50c88352e3292dd7703382addbf5e Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 24 Dec 2014 14:31:06 +0100 Subject: clk: rockchip: fix rk3066 pll lock bit location The bit locations indicating the locking status of the plls on rk3066 are shifted by one to the right when compared to the rk3188, bits [7:4] instead of [8:5] on the rk3188, thus indicating the locking state of the wrong pll or a completely different information in case of the gpll. The recently introduced pll init code exposed that problem on some rk3066 boards when it tried to bring the boot-pll value in line with the value from the rate table. Fix this by defining separate pll definitions for rk3066 with the correct locking indices. Signed-off-by: Heiko Stuebner Fixes: 2c14736c75db ("clk: rockchip: add clock driver for rk3188 and rk3066 clocks") Tested-by: FUKAUMI Naoki Cc: stable@vger.kernel.org diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index b32fcda..7eb684c 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -210,6 +210,17 @@ PNAME(mux_sclk_hsadc_p) = { "hsadc_src", "hsadc_frac", "ext_hsadc" }; PNAME(mux_mac_p) = { "gpll", "dpll" }; PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" }; +static struct rockchip_pll_clock rk3066_pll_clks[] __initdata = { + [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), + RK2928_MODE_CON, 0, 5, 0, rk3188_pll_rates), + [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), + RK2928_MODE_CON, 4, 4, 0, NULL), + [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), + RK2928_MODE_CON, 8, 6, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), + [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), + RK2928_MODE_CON, 12, 7, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), +}; + static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates), @@ -737,8 +748,8 @@ static void __init rk3188_common_clk_init(struct device_node *np) static void __init rk3066a_clk_init(struct device_node *np) { rk3188_common_clk_init(np); - rockchip_clk_register_plls(rk3188_pll_clks, - ARRAY_SIZE(rk3188_pll_clks), + rockchip_clk_register_plls(rk3066_pll_clks, + ARRAY_SIZE(rk3066_pll_clks), RK3066_GRF_SOC_STATUS); rockchip_clk_register_branches(rk3066a_clk_branches, ARRAY_SIZE(rk3066a_clk_branches)); -- cgit v0.10.2 From 9880d4277f6aab6b21404c824f9d9c652ba518ac Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 18 Dec 2014 20:06:57 +0100 Subject: clk: rockchip: fix rk3288 cpuclk core dividers Commit 0e5bdb3f9fa5 (clk: rockchip: switch to using the new cpuclk type for armclk) didn't take into account that the divider used on rk3288 are of the (n+1) type. The rk3066 and rk3188 socs use more complex divider types making it necessary for the list-elements to be the real register-values to write. Therefore reduce divider values in the table accordingly so that they really are the values that should be written to the registers and match the dividers actually specified for the rk3288. Reported-by: Sonny Rao Fixes: 0e5bdb3f9fa5 ("clk: rockchip: switch to using the new cpuclk type for armclk") Signed-off-by: Heiko Stuebner Reviewed-by: Doug Anderson Cc: stable@vger.kernel.org diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index ac6be7c..11194b8 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -145,20 +145,20 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = { } static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = { - RK3288_CPUCLK_RATE(1800000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1704000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1608000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1512000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1416000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1200000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE(1008000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 816000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 696000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 600000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 408000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 312000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 216000000, 2, 4, 2, 4, 4), - RK3288_CPUCLK_RATE( 126000000, 2, 4, 2, 4, 4), + RK3288_CPUCLK_RATE(1800000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1704000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1608000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1512000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1416000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1200000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE(1008000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 816000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 696000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 600000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 408000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 312000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 216000000, 1, 3, 1, 3, 3), + RK3288_CPUCLK_RATE( 126000000, 1, 3, 1, 3, 3), }; static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = { -- cgit v0.10.2 From 4fe6be0fe0c8bec2fdeafe11e7202679cd68e0b2 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Mon, 24 Nov 2014 17:17:24 +0800 Subject: ARM: ls1021a: dtsi: add 'big-endian' property for scfg node On LS1021A SoC, the scfg device is in BE mode. Signed-off-by: Xiubo Li Signed-off-by: Shawn Guo diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 657da14..c70bb27 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -142,6 +142,7 @@ scfg: scfg@1570000 { compatible = "fsl,ls1021a-scfg", "syscon"; reg = <0x0 0x1570000 0x0 0x10000>; + big-endian; }; clockgen: clocking@1ee1000 { -- cgit v0.10.2 From b2faf1a1aff945ec2abf2efdd9002c96b25378e8 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 28 Nov 2014 16:23:46 +0100 Subject: ARM: dts: imx6qdl: Fix CODA960 interrupt order Commit a04a0b6fed4f ("ARM: dts: imx6qdl: Enable CODA960 VPU") lost the fix for the CODA960 interrupt order during a rebase before being applied. This patch adds the missing bit and brings the interrupts and interrupt-names properties back in sync. Signed-off-by: Philipp Zabel Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 4fc03b7..2109d07 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -335,8 +335,8 @@ vpu: vpu@02040000 { compatible = "cnm,coda960"; reg = <0x02040000 0x3c000>; - interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <0 12 IRQ_TYPE_LEVEL_HIGH>, + <0 3 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "bit", "jpeg"; clocks = <&clks IMX6QDL_CLK_VPU_AXI>, <&clks IMX6QDL_CLK_MMDC_CH0_AXI>, -- cgit v0.10.2 From 81ef447950bf0955aca46f4a7617d8ce435cf0ce Mon Sep 17 00:00:00 2001 From: Gary Bisson Date: Wed, 3 Dec 2014 15:03:51 -0800 Subject: ARM: clk-imx6q: fix video divider for rev T0 1.0 The post dividers do not work on i.MX6Q rev T0 1.0 so they must be fixed to 1. As the table index was wrong, a divider a of 4 could still be requested which implied the clock not to be set properly. This is the root cause of the HDMI not working at high resolution on rev T0 1.0 of the SoC. Signed-off-by: Gary Bisson Cc: Signed-off-by: Shawn Guo diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 5951660..2daef61 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -144,7 +144,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) post_div_table[1].div = 1; post_div_table[2].div = 1; video_div_table[1].div = 1; - video_div_table[2].div = 1; + video_div_table[3].div = 1; } clk[IMX6QDL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); -- cgit v0.10.2 From 7a87e9cbc3a2f0ff0955815335e08c9862359130 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 5 Dec 2014 16:16:07 -0200 Subject: ARM: dts: imx25: Fix the SPI1 clocks From Documentation/devicetree/bindings/clock/imx25-clock.txt: cspi1_ipg 78 cspi2_ipg 79 cspi3_ipg 80 , so fix the SPI1 clocks accordingly to avoid a kernel hang when trying to access SPI1. Signed-off-by: Fabio Estevam Cc: Signed-off-by: Shawn Guo diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index 58d3c3c..d238676 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -162,7 +162,7 @@ #size-cells = <0>; compatible = "fsl,imx25-cspi", "fsl,imx35-cspi"; reg = <0x43fa4000 0x4000>; - clocks = <&clks 62>, <&clks 62>; + clocks = <&clks 78>, <&clks 78>; clock-names = "ipg", "per"; interrupts = <14>; status = "disabled"; -- cgit v0.10.2 From c957e8f084e0d21febcd6b8a0ea9631eccc92f36 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 29 Dec 2014 10:33:36 +0200 Subject: spi/pxa2xx: Clear cur_chip pointer before starting next message Once the current message is finished, the driver notifies SPI core about this by calling spi_finalize_current_message(). This function queues next message to be transferred. If there are more messages in the queue, it is possible that the driver is asked to transfer the next message at this point. When spi_finalize_current_message() returns the driver clears the drv_data->cur_chip pointer to NULL. The problem is that if the driver already started the next message clearing drv_data->cur_chip will cause NULL pointer dereference which crashes the kernel like: BUG: unable to handle kernel NULL pointer dereference at 0000000000000048 IP: [] cs_deassert+0x18/0x70 [spi_pxa2xx_platform] PGD 78bb8067 PUD 37712067 PMD 0 Oops: 0000 [#1] SMP Modules linked in: CPU: 1 PID: 11 Comm: ksoftirqd/1 Tainted: G O 3.18.0-rc4-mjo #5 Hardware name: Intel Corp. VALLEYVIEW B3 PLATFORM/NOTEBOOK, BIOS MNW2CRB1.X64.0071.R30.1408131301 08/13/2014 task: ffff880077f9f290 ti: ffff88007a820000 task.ti: ffff88007a820000 RIP: 0010:[] [] cs_deassert+0x18/0x70 [spi_pxa2xx_platform] RSP: 0018:ffff88007a823d08 EFLAGS: 00010202 RAX: 0000000000000008 RBX: ffff8800379a4430 RCX: 0000000000000026 RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffff8800379a4430 RBP: ffff88007a823d18 R08: 00000000ffffffff R09: 000000007a9bc65a R10: 000000000000028f R11: 0000000000000005 R12: ffff880070123e98 R13: ffff880070123de8 R14: 0000000000000100 R15: ffffc90004888000 FS: 0000000000000000(0000) GS:ffff880079a80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000048 CR3: 000000007029b000 CR4: 00000000001007e0 Stack: ffff88007a823d58 ffff8800379a4430 ffff88007a823d48 ffffffffa0022c89 0000000000000000 ffff8800379a4430 0000000000000000 0000000000000006 ffff88007a823da8 ffffffffa0023be0 ffff88007a823dd8 ffffffff81076204 Call Trace: [] giveback+0x69/0xa0 [spi_pxa2xx_platform] [] pump_transfers+0x710/0x740 [spi_pxa2xx_platform] [] ? pick_next_task_fair+0x744/0x830 [] tasklet_action+0xa9/0xe0 [] __do_softirq+0xee/0x280 [] run_ksoftirqd+0x20/0x40 [] smpboot_thread_fn+0xff/0x1b0 [] ? SyS_setgroups+0x150/0x150 [] kthread+0xcd/0xf0 [] ? kthread_create_on_node+0x180/0x180 [] ret_from_fork+0x7c/0xb0 Fix this by clearing drv_data->cur_chip before we call spi_finalize_current_message(). Reported-by: Martin Oldfield Signed-off-by: Mika Westerberg Acked-by: Robert Jarzmik Signed-off-by: Mark Brown Cc: stable@vger.kernel.org diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 05c623c..23822e7 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -546,8 +546,8 @@ static void giveback(struct driver_data *drv_data) cs_deassert(drv_data); } - spi_finalize_current_message(drv_data->master); drv_data->cur_chip = NULL; + spi_finalize_current_message(drv_data->master); } static void reset_sccr1(struct driver_data *drv_data) -- cgit v0.10.2 From 65de7654d39c70c2b942f801cea01590cf7e3458 Mon Sep 17 00:00:00 2001 From: Fabien Proriol Date: Thu, 1 Jan 2015 12:46:48 +0000 Subject: iio: iio: Fix iio_channel_read return if channel havn't info When xilinx-xadc is used with hwmon driver to read voltage, offset used for temperature is always applied whatever the channel. iio_channel_read must return an error to avoid offset for channel without IIO_CHAN_INFO_OFFSET property. Signed-off-by: Fabien Proriol Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index f084610..d33590e 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -426,6 +426,9 @@ static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, if (val2 == NULL) val2 = &unused; + if(!iio_channel_has_info(chan->channel, info)) + return -EINVAL; + if (chan->indio_dev->info->read_raw_multi) { ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev, chan->channel, INDIO_MAX_RAW_ELEMENTS, -- cgit v0.10.2 From 90441b4dbe90ba0c38111ea89fa093a8c9627801 Mon Sep 17 00:00:00 2001 From: Preston Fick Date: Sat, 27 Dec 2014 01:32:41 -0600 Subject: USB: cp210x: fix ID for production CEL MeshConnect USB Stick Fixing typo for MeshConnect IDs. The original PID (0x8875) is not in production and is not needed. Instead it has been changed to the official production PID (0x8857). Signed-off-by: Preston Fick Cc: stable Signed-off-by: Johan Hovold diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 6c4eb3c..fb8d3fa 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -120,7 +120,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ - { USB_DEVICE(0x10C4, 0x8875) }, /* CEL MeshConnect USB Stick */ + { USB_DEVICE(0x10C4, 0x8857) }, /* CEL MeshConnect USB Stick */ { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ -- cgit v0.10.2 From b5122236bba8d7ef62153da5b55cc65d0944c61e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 22 Dec 2014 18:39:39 +0100 Subject: USB: keyspan: fix null-deref at probe Fix null-pointer dereference during probe if the interface-status completion handler is called before the individual ports have been set up. Fixes: f79b2d0fe81e ("USB: keyspan: fix NULL-pointer dereferences and memory leaks") Reported-by: Richard Tested-by: Richard Cc: stable Signed-off-by: Johan Hovold diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 077c714..e07b15e 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -410,6 +410,8 @@ static void usa26_instat_callback(struct urb *urb) } port = serial->port[msg->port]; p_priv = usb_get_serial_port_data(port); + if (!p_priv) + goto resubmit; /* Update handshaking pin state information */ old_dcd_state = p_priv->dcd_state; @@ -420,7 +422,7 @@ static void usa26_instat_callback(struct urb *urb) if (old_dcd_state != p_priv->dcd_state) tty_port_tty_hangup(&port->port, true); - +resubmit: /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) @@ -527,6 +529,8 @@ static void usa28_instat_callback(struct urb *urb) } port = serial->port[msg->port]; p_priv = usb_get_serial_port_data(port); + if (!p_priv) + goto resubmit; /* Update handshaking pin state information */ old_dcd_state = p_priv->dcd_state; @@ -537,7 +541,7 @@ static void usa28_instat_callback(struct urb *urb) if (old_dcd_state != p_priv->dcd_state && old_dcd_state) tty_port_tty_hangup(&port->port, true); - +resubmit: /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) @@ -607,6 +611,8 @@ static void usa49_instat_callback(struct urb *urb) } port = serial->port[msg->portNumber]; p_priv = usb_get_serial_port_data(port); + if (!p_priv) + goto resubmit; /* Update handshaking pin state information */ old_dcd_state = p_priv->dcd_state; @@ -617,7 +623,7 @@ static void usa49_instat_callback(struct urb *urb) if (old_dcd_state != p_priv->dcd_state && old_dcd_state) tty_port_tty_hangup(&port->port, true); - +resubmit: /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) @@ -855,6 +861,8 @@ static void usa90_instat_callback(struct urb *urb) port = serial->port[0]; p_priv = usb_get_serial_port_data(port); + if (!p_priv) + goto resubmit; /* Update handshaking pin state information */ old_dcd_state = p_priv->dcd_state; @@ -865,7 +873,7 @@ static void usa90_instat_callback(struct urb *urb) if (old_dcd_state != p_priv->dcd_state && old_dcd_state) tty_port_tty_hangup(&port->port, true); - +resubmit: /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) @@ -926,6 +934,8 @@ static void usa67_instat_callback(struct urb *urb) port = serial->port[msg->port]; p_priv = usb_get_serial_port_data(port); + if (!p_priv) + goto resubmit; /* Update handshaking pin state information */ old_dcd_state = p_priv->dcd_state; @@ -934,7 +944,7 @@ static void usa67_instat_callback(struct urb *urb) if (old_dcd_state != p_priv->dcd_state && old_dcd_state) tty_port_tty_hangup(&port->port, true); - +resubmit: /* Resubmit urb so we continue receiving */ err = usb_submit_urb(urb, GFP_ATOMIC); if (err != 0) -- cgit v0.10.2 From 68ed7e1c3d236e9e1e60ed6cae22f2c1c4ba2952 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 2 Jan 2015 10:05:13 -0800 Subject: serial: fix parisc boot hang This is a partial revert of 2f2dafe (serial: serial_core.c: printk replacement) which gets us booting again. The real problem seems to be the _emit path in early boot. However, until we can root cause it, we need at least to get boot working. Fixes: 2f2dafe77df2c78e189a9fa6b1879dffd06ae5a1 Cc: stable@vger.kernel.org Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 57ca61b..984605b 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2164,7 +2164,9 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) break; } - dev_info(port->dev, "%s%d at %s (irq = %d, base_baud = %d) is a %s\n", + printk(KERN_INFO "%s%s%s%d at %s (irq = %d, base_baud = %d) is a %s\n", + port->dev ? dev_name(port->dev) : "", + port->dev ? ": " : "", drv->dev_name, drv->tty_driver->name_base + port->line, address, port->irq, port->uartclk / 16, uart_type(port)); -- cgit v0.10.2 From 7c168ed898931f6c3314d696e63cf993378ca192 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 16 Dec 2014 17:30:28 -0200 Subject: ARM: imx6sx: Set PLL2 as parent of QSPI clocks The default qspi2_clk_sel field of register CCM_CS2CDR contains '110' which is marked as 'reserved', so we can't rely on the default value. Provide a proper parent for QSPI clocks to avoid a kernel oops: [ 1.037920] Division by zero in kernel. [ 1.041807] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.18.0-rc7-next-20141204-00002-g5aa23e1 #2143 [ 1.050967] Hardware name: Freescale i.MX6 SoloX (Device Tree) [ 1.056853] Backtrace: [ 1.059360] [<80011ea0>] (dump_backtrace) from [<8001203c>] (show_stack+0x18/0x1c) [ 1.066982] r6:00000000 r5:00000000 r4:00000000 r3:00000000 [ 1.072754] [<80012024>] (show_stack) from [<806b7100>] (dump_stack+0x88/0xa4) [ 1.080038] [<806b7078>] (dump_stack) from [<80011d20>] (__div0+0x18/0x20) [ 1.086958] r5:be018500 r4:be017c00 [ 1.090600] [<80011d08>] (__div0) from [<802aa418>] (Ldiv0+0x8/0x10) [ 1.097012] [<80504fbc>] (clk_divider_set_rate) from [<80503ddc>] (clk_change_rate+0x14c/0x17c) [ 1.105759] r7:00000000 r6:00000000 r5:be018500 r4:00000000 [ 1.111516] [<80503c90>] (clk_change_rate) from [<80503ea0>] (clk_set_rate+0x94/0x98) [ 1.119391] r8:be7e0368 r7:00000000 r6:be11a000 r5:be018500 r4:00000000 r3:00000000 [ 1.127290] [<80503e0c>] (clk_set_rate) from [<80410558>] (fsl_qspi_probe+0x23c/0x75c) [ 1.135260] r5:be11a010 r4:be350010 [ 1.138900] [<8041031c>] (fsl_qspi_probe) from [<80385a18>] (platform_drv_probe+0x50/0xac) Signed-off-by: Fabio Estevam Cc: Signed-off-by: Shawn Guo diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c index 17354a1..5a3e5a1 100644 --- a/arch/arm/mach-imx/clk-imx6sx.c +++ b/arch/arm/mach-imx/clk-imx6sx.c @@ -558,6 +558,9 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]); clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]); + clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]); + clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]); + /* Set initial power mode */ imx6q_set_lpm(WAIT_CLOCKED); } -- cgit v0.10.2 From 8c38d28ba8da98f7102c31d35359b4dbe9d1f329 Mon Sep 17 00:00:00 2001 From: Tobias Jakobi Date: Wed, 22 Oct 2014 03:37:08 +0200 Subject: clocksource: exynos_mct: Fix bitmask regression for exynos4_mct_write EXYNOS4_MCT_L_MASK is defined as 0xffffff00, so applying this bitmask produces a number outside the range 0x00 to 0xff, which always results in execution of the default switch statement. Obviously this is wrong and git history shows that the bitmask inversion was incorrectly set during a refactoring of the MCT code. Fix this by putting the inversion at the correct position again. Cc: stable@vger.kernel.org Acked-by: Kukjin Kim Reported-by: GP Orcullo Reviewed-by: Doug Anderson Signed-off-by: Tobias Jakobi Signed-off-by: Daniel Lezcano diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 9403061..83564c9 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -97,8 +97,8 @@ static void exynos4_mct_write(unsigned int value, unsigned long offset) writel_relaxed(value, reg_base + offset); if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) { - stat_addr = (offset & ~EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET; - switch (offset & EXYNOS4_MCT_L_MASK) { + stat_addr = (offset & EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET; + switch (offset & ~EXYNOS4_MCT_L_MASK) { case MCT_L_TCON_OFFSET: mask = 1 << 3; /* L_TCON write status */ break; -- cgit v0.10.2 From ff4bcc84a9e720ffa6cb7cf01e9e938568147cd6 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Mon, 8 Dec 2014 13:42:02 -0800 Subject: clocksource: kona: fix __iomem annotation It makes no sense to hide the __iomem annotation from the function that uses it, especially since it causes a sparse warning: drivers/clocksource/bcm_kona_timer.c:118:38: warning: incorrect type in argument 1 (different address spaces) drivers/clocksource/bcm_kona_timer.c:118:38: expected void *timer_base drivers/clocksource/bcm_kona_timer.c:118:38: got void [noderef] *static [toplevel] tmr_regs Signed-off-by: Olof Johansson Acked-by: Florian Fainelli Signed-off-by: Daniel Lezcano diff --git a/drivers/clocksource/bcm_kona_timer.c b/drivers/clocksource/bcm_kona_timer.c index 0595dc6..f1e33d0 100644 --- a/drivers/clocksource/bcm_kona_timer.c +++ b/drivers/clocksource/bcm_kona_timer.c @@ -68,9 +68,8 @@ static void kona_timer_disable_and_clear(void __iomem *base) } static void -kona_timer_get_counter(void *timer_base, uint32_t *msw, uint32_t *lsw) +kona_timer_get_counter(void __iomem *timer_base, uint32_t *msw, uint32_t *lsw) { - void __iomem *base = IOMEM(timer_base); int loop_limit = 4; /* @@ -86,9 +85,9 @@ kona_timer_get_counter(void *timer_base, uint32_t *msw, uint32_t *lsw) */ while (--loop_limit) { - *msw = readl(base + KONA_GPTIMER_STCHI_OFFSET); - *lsw = readl(base + KONA_GPTIMER_STCLO_OFFSET); - if (*msw == readl(base + KONA_GPTIMER_STCHI_OFFSET)) + *msw = readl(timer_base + KONA_GPTIMER_STCHI_OFFSET); + *lsw = readl(timer_base + KONA_GPTIMER_STCLO_OFFSET); + if (*msw == readl(timer_base + KONA_GPTIMER_STCHI_OFFSET)) break; } if (!loop_limit) { -- cgit v0.10.2 From f2a5473861cf69c03d0f0ee5d0ea1b853b9e582e Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 16 Dec 2014 18:48:54 +0900 Subject: clocksource: sh_tmu: Set cpu_possible_mask to fix SMP broadcast Update the TMU driver to use cpu_possible_mask as cpumask to make r8a7779 SMP work as expected with or without the ARM TWD timer. Signed-off-by: Magnus Damm Signed-off-by: Daniel Lezcano diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 0f665b8..f150ca82 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -428,7 +428,7 @@ static void sh_tmu_register_clockevent(struct sh_tmu_channel *ch, ced->features = CLOCK_EVT_FEAT_PERIODIC; ced->features |= CLOCK_EVT_FEAT_ONESHOT; ced->rating = 200; - ced->cpumask = cpumask_of(0); + ced->cpumask = cpu_possible_mask; ced->set_next_event = sh_tmu_clock_event_next; ced->set_mode = sh_tmu_clock_event_mode; ced->suspend = sh_tmu_clock_event_suspend; -- cgit v0.10.2 From 5c0b8e0de76a86edb99e46612fd9d341b4c4fa0a Mon Sep 17 00:00:00 2001 From: Suman Tripathi Date: Mon, 29 Dec 2014 08:52:46 +0530 Subject: ahci_xgene: Fix the endianess issue in APM X-Gene SoC AHCI SATA controller driver. This patch fixes the big endian mode issue with function xgene_ahci_read_id. Signed-off-by: Suman Tripathi Signed-off-by: Tejun Heo diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index feeb8f1..f190b92 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -188,7 +188,7 @@ static unsigned int xgene_ahci_read_id(struct ata_device *dev, * * Clear reserved bit 8 (DEVSLP bit) as we don't support DEVSLP */ - id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8); + id[ATA_ID_FEATURE_SUPP] &= cpu_to_le16(~(1 << 8)); return 0; } -- cgit v0.10.2 From 1102407bb714dcebb43f385335bcb72f6b8843bc Mon Sep 17 00:00:00 2001 From: Suman Tripathi Date: Mon, 29 Dec 2014 08:52:47 +0530 Subject: ahci_xgene: Fix the DMA state machine lockup for the ATA_CMD_PACKET PIO mode command. This patch addresses the issue with ATA_CMD_PACKET pio mode command for enumeration and device detection with ATAPI devices. The X-Gene AHCI controller has an errata in which it cannot clear the BSY bit after the PIO setup FIS. The dma state machine enters CMFatalErrorUpdate state and locks up. Signed-off-by: Suman Tripathi Signed-off-by: Tejun Heo diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index f190b92..cbcd208 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -125,10 +125,11 @@ static int xgene_ahci_restart_engine(struct ata_port *ap) * xgene_ahci_qc_issue - Issue commands to the device * @qc: Command to issue * - * Due to Hardware errata for IDENTIFY DEVICE command, the controller cannot - * clear the BSY bit after receiving the PIO setup FIS. This results in the dma - * state machine goes into the CMFatalErrorUpdate state and locks up. By - * restarting the dma engine, it removes the controller out of lock up state. + * Due to Hardware errata for IDENTIFY DEVICE command and PACKET + * command of ATAPI protocol set, the controller cannot clear the BSY bit + * after receiving the PIO setup FIS. This results in the DMA state machine + * going into the CMFatalErrorUpdate state and locks up. By restarting the + * DMA engine, it removes the controller out of lock up state. */ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) { @@ -137,7 +138,8 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) struct xgene_ahci_context *ctx = hpriv->plat_data; int rc = 0; - if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA)) + if (unlikely((ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA) || + (ctx->last_cmd[ap->port_no] == ATA_CMD_PACKET))) xgene_ahci_restart_engine(ap); rc = ahci_qc_issue(qc); -- cgit v0.10.2 From 36aae28e3df4127e296f2680d65cb6310ce61021 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Dec 2014 17:16:31 +0200 Subject: libata: export ata_get_cmd_descript() The driver sata_dwc_460ex is using this symbol. To build it as a module we have to have the symbol exported. This patch adds EXPORT_SYMBOL_GPL() macro for that. tj: Updated to use EXPORT_SYMBOL_GPL() instead of EXPORT_SYMBOL() as the only known user is an in-tree driver. Suggested by Sergei. Signed-off-by: Andy Shevchenko Signed-off-by: Tejun Heo Cc: Sergei Shtylyov diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 3dbec89..8d00c26 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2389,6 +2389,7 @@ const char *ata_get_cmd_descript(u8 command) return NULL; } +EXPORT_SYMBOL_GPL(ata_get_cmd_descript); /** * ata_eh_link_report - report error handling to user -- cgit v0.10.2 From d297933cc7fcfbaaf2d37570baac73287bf0357d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 5 Jan 2015 09:32:56 +0800 Subject: spi: dw: Fix detecting FIFO depth Current code tries to find the highest valid fifo depth by checking the value it wrote to DW_SPI_TXFLTR. There are a few problems in current code: 1) There is an off-by-one in dws->fifo_len setting because it assumes the latest register write fails so the latest valid value should be fifo - 1. 2) We know the depth could be from 2 to 256 from HW spec, so it is not necessary to test fifo == 257. In the case fifo is 257, it means the latest valid setting is fifo = 256. So after the for loop iteration, we should check fifo == 2 case instead of fifo == 257 if detecting the FIFO depth fails. This patch fixes above issues. Signed-off-by: Axel Lin Reviewed-and-tested-by: Andy Shevchenko Signed-off-by: Mark Brown Cc: stable@vger.kernel.org diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index d0d5542..1a0f266 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -621,13 +621,13 @@ static void spi_hw_init(struct dw_spi *dws) if (!dws->fifo_len) { u32 fifo; - for (fifo = 2; fifo <= 257; fifo++) { + for (fifo = 2; fifo <= 256; fifo++) { dw_writew(dws, DW_SPI_TXFLTR, fifo); if (fifo != dw_readw(dws, DW_SPI_TXFLTR)) break; } - dws->fifo_len = (fifo == 257) ? 0 : fifo; + dws->fifo_len = (fifo == 2) ? 0 : fifo - 1; dw_writew(dws, DW_SPI_TXFLTR, 0); } } -- cgit v0.10.2 From ebc3193ae0df723f4d8abd06890cd77354493c79 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 3 Jan 2015 22:56:56 +0100 Subject: thermal: of: Remove bogus type qualifier for of_thermal_get_trip_points() With gcc 4.1.2, 4.2, and 4.2.4 (4.4 and later are OK): drivers/thermal/thermal_core.h:110: warning: type qualifiers ignored on function return type Signed-off-by: Geert Uytterhoeven Fixes: ce8be7785922de0e ("thermal: of: Extend of-thermal to export table of trip points") Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index e145b66..d717f3d 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c @@ -149,7 +149,7 @@ EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid); * * Return: pointer to trip points table, NULL otherwise */ -const struct thermal_trip * const +const struct thermal_trip * of_thermal_get_trip_points(struct thermal_zone_device *tz) { struct __thermal_zone *data = tz->devdata; diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 9083e75..0531c75 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -91,7 +91,7 @@ int of_parse_thermal_zones(void); void of_thermal_destroy_zones(void); int of_thermal_get_ntrips(struct thermal_zone_device *); bool of_thermal_is_trip_valid(struct thermal_zone_device *, int); -const struct thermal_trip * const +const struct thermal_trip * of_thermal_get_trip_points(struct thermal_zone_device *); #else static inline int of_parse_thermal_zones(void) { return 0; } @@ -105,7 +105,7 @@ static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, { return 0; } -static inline const struct thermal_trip * const +static inline const struct thermal_trip * of_thermal_get_trip_points(struct thermal_zone_device *tz) { return NULL; -- cgit v0.10.2 From 67bf9cda4b498b8cea4a40be67a470afe57d2e88 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Jan 2015 17:48:51 +0200 Subject: spi: dw-mid: fix FIFO size The FIFO size is 40 accordingly to the specifications, but this means 0x40, i.e. 64 bytes. This patch fixes the typo and enables FIFO size autodetection for Intel MID devices. Fixes: 7063c0d942a1 (spi/dw_spi: add DMA support) Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown Cc: stable@vger.kernel.org diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 7281316..a67d37c 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -271,7 +271,6 @@ int dw_spi_mid_init(struct dw_spi *dws) iounmap(clk_reg); dws->num_cs = 16; - dws->fifo_len = 40; /* FIFO has 40 words buffer */ #ifdef CONFIG_SPI_DW_MID_DMA dws->dma_priv = kzalloc(sizeof(struct mid_dma), GFP_KERNEL); -- cgit v0.10.2 From 531ff13eaf1a61c9468a0622e464a1293abb1024 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Sat, 3 Jan 2015 13:13:30 -0600 Subject: MAINTAINERS: Add linux-omap to list of reviewers for TI Thermal Add linux-omap mailing list to the TI THERMAL list for wider review. Reported-by: Pavel Machek Signed-off-by: Nishanth Menon Signed-off-by: Eduardo Valentin diff --git a/MAINTAINERS b/MAINTAINERS index ddb9ac8..dc9efd5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9533,6 +9533,7 @@ F: drivers/platform/x86/thinkpad_acpi.c TI BANDGAP AND THERMAL DRIVER M: Eduardo Valentin L: linux-pm@vger.kernel.org +L: linux-omap@vger.kernel.org S: Supported F: drivers/thermal/ti-soc-thermal/ -- cgit v0.10.2 From 5a723e81923410f0d3ae4c38974607b13befdda9 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Mon, 5 Jan 2015 17:48:13 -0400 Subject: MAINTAINERS: update ti-soc-thermal status Changing to Maintained. Signed-off-by: Eduardo Valentin diff --git a/MAINTAINERS b/MAINTAINERS index dc9efd5..bc91817 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9534,7 +9534,7 @@ TI BANDGAP AND THERMAL DRIVER M: Eduardo Valentin L: linux-pm@vger.kernel.org L: linux-omap@vger.kernel.org -S: Supported +S: Maintained F: drivers/thermal/ti-soc-thermal/ TI CLOCK DRIVER -- cgit v0.10.2 From 572b24e6d85d98cdc552f07e9fb9870d9460d81b Mon Sep 17 00:00:00 2001 From: Lennart Sorensen Date: Mon, 5 Jan 2015 15:45:45 -0800 Subject: ARM: omap5/dra7xx: Fix frequency typos The switch statement of the possible list of SYSCLK1 frequencies is missing a 0 in 4 out of the 7 frequencies. Fixes: fa6d79d27614 ("ARM: OMAP: Add initialisation for the real-time counter") Cc: stable@vger.kernel.org # v3.7+ Signed-off-by: Len Sorensen Reviewed-by: Lokesh Vutla Acked-by: Nishanth Menon Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 4f61148..fb0cb2b 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -513,11 +513,11 @@ static void __init realtime_counter_init(void) rate = clk_get_rate(sys_clk); /* Numerator/denumerator values refer TRM Realtime Counter section */ switch (rate) { - case 1200000: + case 12000000: num = 64; den = 125; break; - case 1300000: + case 13000000: num = 768; den = 1625; break; @@ -529,11 +529,11 @@ static void __init realtime_counter_init(void) num = 192; den = 625; break; - case 2600000: + case 26000000: num = 384; den = 1625; break; - case 2700000: + case 27000000: num = 256; den = 1125; break; -- cgit v0.10.2 From afc9d590b8a150cfeaac0078ef5de6fb21a5ea6a Mon Sep 17 00:00:00 2001 From: Lennart Sorensen Date: Mon, 5 Jan 2015 15:45:45 -0800 Subject: ARM: dra7xx: Fix counter frequency drift for AM572x errata i856 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), but can also be 19.2 or 27MHz which result in much larger drift. Since this is used to drive the master counter at 32.768KHz * 375 / 2 = 6.144MHz, the emulated speed for 20MHz is of by 570ppm, or about 43 seconds per day, and more than the 500ppm NTP is able to tolerate. Checking the CTRL_CORE_BOOTSTRAP register can determine if the CPU is using the real 32.768KHz crystal or the emulated SYSCLK1/610, and by known that the real counter frequency can be determined and used. The real speed is then SYSCLK1 / 610 * 375 / 2 or SYSCLK1 * 75 / 244. Signed-off-by: Len Sorensen Tested-by: Lokesh Vutla Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index a3c0133..a80ac2d 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -286,6 +286,10 @@ #define OMAP5XXX_CONTROL_STATUS 0x134 #define OMAP5_DEVICETYPE_MASK (0x7 << 6) +/* DRA7XX CONTROL CORE BOOTSTRAP */ +#define DRA7_CTRL_CORE_BOOTSTRAP 0x6c4 +#define DRA7_SPEEDSELECT_MASK (0x3 << 8) + /* * REVISIT: This list of registers is not comprehensive - there are more * that should be added. diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index fb0cb2b..7d45c84 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -54,6 +54,7 @@ #include "soc.h" #include "common.h" +#include "control.h" #include "powerdomain.h" #include "omap-secure.h" @@ -496,7 +497,8 @@ static void __init realtime_counter_init(void) void __iomem *base; static struct clk *sys_clk; unsigned long rate; - unsigned int reg, num, den; + unsigned int reg; + unsigned long long num, den; base = ioremap(REALTIME_COUNTER_BASE, SZ_32); if (!base) { @@ -511,6 +513,35 @@ static void __init realtime_counter_init(void) } rate = clk_get_rate(sys_clk); + + if (soc_is_dra7xx()) { + /* + * Errata i856 says the 32.768KHz crystal does not start at + * power on, so the CPU falls back to an emulated 32KHz clock + * based on sysclk / 610 instead. This causes the master counter + * frequency to not be 6.144MHz but at sysclk / 610 * 375 / 2 + * (OR sysclk * 75 / 244) + * + * This affects at least the DRA7/AM572x 1.0, 1.1 revisions. + * Of course any board built without a populated 32.768KHz + * crystal would also need this fix even if the CPU is fixed + * later. + * + * Either case can be detected by using the two speedselect bits + * If they are not 0, then the 32.768KHz clock driving the + * coarse counter that corrects the fine counter every time it + * ticks is actually rate/610 rather than 32.768KHz and we + * should compensate to avoid the 570ppm (at 20MHz, much worse + * at other rates) too fast system time. + */ + reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP); + if (reg & DRA7_SPEEDSELECT_MASK) { + num = 75; + den = 244; + goto sysclk1_based; + } + } + /* Numerator/denumerator values refer TRM Realtime Counter section */ switch (rate) { case 12000000: @@ -545,6 +576,7 @@ static void __init realtime_counter_init(void) break; } +sysclk1_based: /* Program numerator and denumerator registers */ reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) & NUMERATOR_DENUMERATOR_MASK; @@ -556,7 +588,7 @@ static void __init realtime_counter_init(void) reg |= den; writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); - arch_timer_freq = (rate / den) * num; + arch_timer_freq = DIV_ROUND_UP_ULL(rate * num, den); set_cntfreq(); iounmap(base); -- cgit v0.10.2 From 999f934de195a1506089b52c77429fdba25da688 Mon Sep 17 00:00:00 2001 From: Lennart Sorensen Date: Mon, 5 Jan 2015 15:45:45 -0800 Subject: ARM: omap5/dra7xx: Enable booting secondary CPU in HYP mode If the boot loader enables HYP mode on the boot CPU, the secondary CPU also needs to call into the ROM to switch to HYP mode before booting. The firmwares on the omap5 and dra7xx unfortunately do not take care of this, so it has to be handled by the kernel. This patch is based on "[PATCH 2/2] ARM: OMAP5: Add HYP mode entry support for secondary CPUs" by Santosh Shilimkar , except this version does not require a compile time CONFIG to control if it should enable HYP mode or not, it simply does it based on the mode of the boot CPU, so it works whether the CPU boots in SVC or HYP mode, and should even work as a guest kernel inside kvm if qemu decides to support emulating the omap5 or dra7xx. Cc: stable@vger.kernel.org #v3.16+ Signed-off-by: Len Sorensen Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 377eea8..db57741 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -249,6 +249,7 @@ extern void omap4_cpu_die(unsigned int cpu); extern struct smp_operations omap4_smp_ops; extern void omap5_secondary_startup(void); +extern void omap5_secondary_hyp_startup(void); #endif #if defined(CONFIG_SMP) && defined(CONFIG_PM) diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 4993d4b..6d1dffc 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -22,6 +22,7 @@ /* Physical address needed since MMU not enabled yet on secondary core */ #define AUX_CORE_BOOT0_PA 0x48281800 +#define API_HYP_ENTRY 0x102 /* * OMAP5 specific entry point for secondary CPU to jump from ROM @@ -41,6 +42,26 @@ wait: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0 b secondary_startup ENDPROC(omap5_secondary_startup) /* + * Same as omap5_secondary_startup except we call into the ROM to + * enable HYP mode first. This is called instead of + * omap5_secondary_startup if the primary CPU was put into HYP mode by + * the boot loader. + */ +ENTRY(omap5_secondary_hyp_startup) +wait_2: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0 + ldr r0, [r2] + mov r0, r0, lsr #5 + mrc p15, 0, r4, c0, c0, 5 + and r4, r4, #0x0f + cmp r0, r4 + bne wait_2 + ldr r12, =API_HYP_ENTRY + adr r0, hyp_boot + smc #0 +hyp_boot: + b secondary_startup +ENDPROC(omap5_secondary_hyp_startup) +/* * OMAP4 specific entry point for secondary CPU to jump from ROM * code. This routine also provides a holding flag into which * secondary core is held until we're ready for it to initialise. diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 256e84e..5305ec7 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -22,6 +22,7 @@ #include #include +#include #include "omap-secure.h" #include "omap-wakeupgen.h" @@ -227,8 +228,16 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) if (omap_secure_apis_support()) omap_auxcoreboot_addr(virt_to_phys(startup_addr)); else - writel_relaxed(virt_to_phys(omap5_secondary_startup), - base + OMAP_AUX_CORE_BOOT_1); + /* + * If the boot CPU is in HYP mode then start secondary + * CPU in HYP mode as well. + */ + if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE) + writel_relaxed(virt_to_phys(omap5_secondary_hyp_startup), + base + OMAP_AUX_CORE_BOOT_1); + else + writel_relaxed(virt_to_phys(omap5_secondary_startup), + base + OMAP_AUX_CORE_BOOT_1); } -- cgit v0.10.2 From 71c4f6027da75c6c1fd92e05b63108a09ec2b109 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 5 Jan 2015 15:45:45 -0800 Subject: ARM: OMAP2+: Fix n900 board name for legacy user space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit N900 legacy user space apps need the board name in /proc/cpuinfo to work properly for the Hardware entry. For other boards this should not be an issues and they can use the generic Hardware entry. Let's fix the issue by adding a custom DT_MACHINE_START for n900. Tested-by: Pali Rohár Acked-by: Pavel Machek Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 608079a..b61c049 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -77,6 +77,24 @@ MACHINE_END #endif #ifdef CONFIG_ARCH_OMAP3 +/* Some boards need board name for legacy userspace in /proc/cpuinfo */ +static const char *const n900_boards_compat[] __initconst = { + "nokia,omap3-n900", + NULL, +}; + +DT_MACHINE_START(OMAP3_N900_DT, "Nokia RX-51 board") + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3430_init_early, + .init_machine = omap_generic_init, + .init_late = omap3_init_late, + .init_time = omap3_sync32k_timer_init, + .dt_compat = n900_boards_compat, + .restart = omap3xxx_restart, +MACHINE_END + +/* Generic omap3 boards, most boards can use these */ static const char *const omap3_boards_compat[] __initconst = { "ti,omap3430", "ti,omap3", -- cgit v0.10.2 From 40d1746d2eeec5e05956d749cca6364573b472b6 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 5 Jan 2015 15:45:45 -0800 Subject: ARM: omap2plus_defconfig: use CONFIG_CPUFREQ_DT CONFIG_GENERIC_CPUFREQ_CPU0 disappeared with commit bbcf071969b20f ("cpufreq: cpu0: rename driver and internals to 'cpufreq_dt'") Use the renamed CONFIG_CPUFREQ_DT generic driver. It looks like with v3.18-rc1, commit bbcf071969b20f and fdc509b15eb3eb came in via different trees causing the resultant v3.18-rc1 to be non-functional for cpufreq as default supported with omap2plus_defconfig. Fixes: fdc509b15eb3eb ("ARM: omap2plus_defconfig: Add cpufreq to defconfig") Cc: # 3.18 Signed-off-by: Nishanth Menon Acked-by: Viresh Kumar Signed-off-by: Tony Lindgren diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index c2c3a85..667d9d5 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -68,7 +68,7 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_GENERIC_CPUFREQ_CPU0=y +CONFIG_CPUFREQ_DT=y # CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set CONFIG_CPU_IDLE=y CONFIG_BINFMT_MISC=y -- cgit v0.10.2 From 69d2626f97b7f017ee4416b7dc071e9499c2c944 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Mon, 5 Jan 2015 15:45:45 -0800 Subject: ARM: dts: dra7-evm: fix qspi device tree partition size 64KiB is allocated for qspi dtb partition which is not sufficient, so updating the partition table size to 512KiB for device tree partition. This also aligns the QSPI partition definitions between kernel and U-Boot. Fixes: dc2dd5b8 ("ARM: dts: dra7: Add qspi device") Signed-off-by: Mugunthan V N Signed-off-by: Tony Lindgren diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index 10b725c..ad4118f 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -499,23 +499,23 @@ }; partition@5 { label = "QSPI.u-boot-spl-os"; - reg = <0x00140000 0x00010000>; + reg = <0x00140000 0x00080000>; }; partition@6 { label = "QSPI.u-boot-env"; - reg = <0x00150000 0x00010000>; + reg = <0x001c0000 0x00010000>; }; partition@7 { label = "QSPI.u-boot-env.backup1"; - reg = <0x00160000 0x0010000>; + reg = <0x001d0000 0x0010000>; }; partition@8 { label = "QSPI.kernel"; - reg = <0x00170000 0x0800000>; + reg = <0x001e0000 0x0800000>; }; partition@9 { label = "QSPI.file-system"; - reg = <0x00970000 0x01690000>; + reg = <0x009e0000 0x01620000>; }; }; }; -- cgit v0.10.2 From 06bed7d18c2c07b3e3eeadf4bd357f6e806618cc Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 2 Jan 2015 15:05:25 -0500 Subject: LOCKD: Fix a race when initialising nlmsvc_timeout This commit fixes a race whereby nlmclnt_init() first starts the lockd daemon, and then calls nlm_bind_host() with the expectation that nlmsvc_timeout has already been initialised. Unfortunately, there is no no synchronisation between lockd() and lockd_up() to guarantee that this is the case. Fix is to move the initialisation of nlmsvc_timeout into lockd_create_svc Fixes: 9a1b6bf818e74 ("LOCKD: Don't call utsname()->nodename...") Cc: Bruce Fields Cc: stable@vger.kernel.org # 3.10.x Signed-off-by: Trond Myklebust diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index e94c887..55505cb 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -138,10 +138,6 @@ lockd(void *vrqstp) dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); - if (!nlm_timeout) - nlm_timeout = LOCKD_DFLT_TIMEO; - nlmsvc_timeout = nlm_timeout * HZ; - /* * The main request loop. We don't terminate until the last * NFS mount or NFS daemon has gone away. @@ -350,6 +346,10 @@ static struct svc_serv *lockd_create_svc(void) printk(KERN_WARNING "lockd_up: no pid, %d users??\n", nlmsvc_users); + if (!nlm_timeout) + nlm_timeout = LOCKD_DFLT_TIMEO; + nlmsvc_timeout = nlm_timeout * HZ; + serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, svc_rpcb_cleanup); if (!serv) { printk(KERN_WARNING "lockd_up: create service failed\n"); -- cgit v0.10.2 From 1fc0703af3143914a389bfa081c7acb09502ed5d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 2 Jan 2015 16:25:08 -0500 Subject: NFSv4.1: Fix client id trunking on Linux Currently, our trunking code will check for session trunking, but will fail to detect client id trunking. This is a problem, because it means that the client will fail to recognise that the two connections represent shared state, even if they do not permit a shared session. By removing the check for the server minor id, and only checking the major id, we will end up doing the right thing in both cases: we close down the new nfs_client and fall back to using the existing one. Fixes: 05f4c350ee02e ("NFS: Discover NFSv4 server trunking when mounting") Cc: Chuck Lever Cc: stable@vger.kernel.org # 3.7.x Tested-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 0331125..d949d0f 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -566,20 +566,14 @@ static bool nfs4_match_clientids(struct nfs_client *a, struct nfs_client *b) } /* - * Returns true if the server owners match + * Returns true if the server major ids match */ static bool -nfs4_match_serverowners(struct nfs_client *a, struct nfs_client *b) +nfs4_check_clientid_trunking(struct nfs_client *a, struct nfs_client *b) { struct nfs41_server_owner *o1 = a->cl_serverowner; struct nfs41_server_owner *o2 = b->cl_serverowner; - if (o1->minor_id != o2->minor_id) { - dprintk("NFS: --> %s server owner minor IDs do not match\n", - __func__); - return false; - } - if (o1->major_id_sz != o2->major_id_sz) goto out_major_mismatch; if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0) @@ -654,7 +648,12 @@ int nfs41_walk_client_list(struct nfs_client *new, if (!nfs4_match_clientids(pos, new)) continue; - if (!nfs4_match_serverowners(pos, new)) + /* + * Note that session trunking is just a special subcase of + * client id trunking. In either case, we want to fall back + * to using the existing nfs_client. + */ + if (!nfs4_check_clientid_trunking(pos, new)) continue; atomic_inc(&pos->cl_count); -- cgit v0.10.2 From ceb3a16c070c403f5f9ca46b46cf2bb79ea11750 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 3 Jan 2015 15:16:04 -0500 Subject: NFSv4: Cache the NFSv4/v4.1 client owner_id in the struct nfs_client Ensure that we cache the NFSv4/v4.1 client owner_id so that we can verify it when we're doing trunking detection. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index d949d0f..6ee9bf6 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -228,6 +228,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp) kfree(clp->cl_serverowner); kfree(clp->cl_serverscope); kfree(clp->cl_implid); + kfree(clp->cl_owner_id); } void nfs4_free_client(struct nfs_client *clp) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e7f8d5f..1fab516 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4917,11 +4917,14 @@ static void nfs4_init_boot_verifier(const struct nfs_client *clp, } static unsigned int -nfs4_init_nonuniform_client_string(const struct nfs_client *clp, +nfs4_init_nonuniform_client_string(struct nfs_client *clp, char *buf, size_t len) { unsigned int result; + if (clp->cl_owner_id != NULL) + return strlcpy(buf, clp->cl_owner_id, len); + rcu_read_lock(); result = scnprintf(buf, len, "Linux NFSv4.0 %s/%s %s", clp->cl_ipaddr, @@ -4930,24 +4933,32 @@ nfs4_init_nonuniform_client_string(const struct nfs_client *clp, rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_PROTO)); rcu_read_unlock(); + clp->cl_owner_id = kstrdup(buf, GFP_KERNEL); return result; } static unsigned int -nfs4_init_uniform_client_string(const struct nfs_client *clp, +nfs4_init_uniform_client_string(struct nfs_client *clp, char *buf, size_t len) { const char *nodename = clp->cl_rpcclient->cl_nodename; + unsigned int result; + + if (clp->cl_owner_id != NULL) + return strlcpy(buf, clp->cl_owner_id, len); if (nfs4_client_id_uniquifier[0] != '\0') - return scnprintf(buf, len, "Linux NFSv%u.%u %s/%s", + result = scnprintf(buf, len, "Linux NFSv%u.%u %s/%s", clp->rpc_ops->version, clp->cl_minorversion, nfs4_client_id_uniquifier, nodename); - return scnprintf(buf, len, "Linux NFSv%u.%u %s", + else + result = scnprintf(buf, len, "Linux NFSv%u.%u %s", clp->rpc_ops->version, clp->cl_minorversion, nodename); + clp->cl_owner_id = kstrdup(buf, GFP_KERNEL); + return result; } /* diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 1e37fbb..ddea982 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -74,6 +74,9 @@ struct nfs_client { /* idmapper */ struct idmap * cl_idmap; + /* Client owner identifier */ + const char * cl_owner_id; + /* Our own IP address, as a null-terminated string. * This is used to generate the mv0 callback address. */ -- cgit v0.10.2 From 55b9df93ddd684cbc4c2dee9b8a99f6e48348212 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 3 Jan 2015 15:35:27 -0500 Subject: NFSv4/v4.1: Verify the client owner id during trunking detection While we normally expect the NFSv4 client to always send the same client owner to all servers, there are a couple of situations where that is not the case: 1) In NFSv4.0, switching between use of '-omigration' and not will cause the kernel to switch between using the non-uniform and uniform client strings. 2) In NFSv4.1, or NFSv4.0 when using uniform client strings, if the uniquifier string is suddenly changed. This patch will catch those situations by checking the client owner id in the trunking detection code, and will do the right thing if it notices that the strings differ. Cc: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 6ee9bf6..b1024bc 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -453,6 +453,14 @@ static void nfs4_swap_callback_idents(struct nfs_client *keep, spin_unlock(&nn->nfs_client_lock); } +static bool nfs4_match_client_owner_id(const struct nfs_client *clp1, + const struct nfs_client *clp2) +{ + if (clp1->cl_owner_id == NULL || clp2->cl_owner_id == NULL) + return true; + return strcmp(clp1->cl_owner_id, clp2->cl_owner_id) == 0; +} + /** * nfs40_walk_client_list - Find server that recognizes a client ID * @@ -511,6 +519,9 @@ int nfs40_walk_client_list(struct nfs_client *new, if (pos->cl_clientid != new->cl_clientid) continue; + if (!nfs4_match_client_owner_id(pos, new)) + continue; + atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); @@ -657,6 +668,13 @@ int nfs41_walk_client_list(struct nfs_client *new, if (!nfs4_check_clientid_trunking(pos, new)) continue; + /* Unlike NFSv4.0, we know that NFSv4.1 always uses the + * uniform string, however someone might switch the + * uniquifier string on us. + */ + if (!nfs4_match_client_owner_id(pos, new)) + continue; + atomic_inc(&pos->cl_count); *result = pos; status = 0; -- cgit v0.10.2 From 7a01edf0058df98d6cc734c5a4ecc51f929a86ec Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 3 Jan 2015 14:45:33 -0500 Subject: NFS: Ignore transport protocol when detecting server trunking Detect server trunking across transport protocols. Otherwise, an RDMA mount and a TCP mount of the same server will end up with separate nfs_clients using the same clientid4. Reported-by: Dai Ngo Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index b1024bc..953daa4 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -492,9 +492,6 @@ int nfs40_walk_client_list(struct nfs_client *new, if (pos->rpc_ops != new->rpc_ops) continue; - if (pos->cl_proto != new->cl_proto) - continue; - if (pos->cl_minorversion != new->cl_minorversion) continue; @@ -627,9 +624,6 @@ int nfs41_walk_client_list(struct nfs_client *new, if (pos->rpc_ops != new->rpc_ops) continue; - if (pos->cl_proto != new->cl_proto) - continue; - if (pos->cl_minorversion != new->cl_minorversion) continue; -- cgit v0.10.2 From 4e379d36c050b0117b5d10048be63a44f5036115 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 19 Dec 2014 12:47:50 -0500 Subject: NFSv4: Remove incorrect check in can_open_delegated() Remove an incorrect check for NFS_DELEGATION_NEED_RECLAIM in can_open_delegated(). We are allowed to cache opens even in a situation where we're doing reboot recovery. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1fab516..c347705 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1117,8 +1117,6 @@ static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode) return 0; if ((delegation->type & fmode) != fmode) return 0; - if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags)) - return 0; if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) return 0; nfs_mark_delegation_referenced(delegation); -- cgit v0.10.2 From 21f621741a770c119e7529a3f5c0e6b7c91383a3 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 6 Jan 2015 10:45:35 +0100 Subject: fuse: fix LOOKUP vs INIT compat handling Analysis from Marc: "Commit 7078187a795f ("fuse: introduce fuse_simple_request() helper") from the above pull request triggers some EIO errors for me in some tests that rely on fuse Looking at the code changes and a bit of debugging info I think there's a general problem here that fuse_get_req checks and possibly waits for fc->initialized, and this was always called first. But this commit changes the ordering and in many places fc->minor is now possibly used before fuse_get_req, and we can't be sure that fc has been initialized. In my case fuse_lookup_init sets req->out.args[0].size to the wrong size because fc->minor at that point is still 0, leading to the EIO error." Fix by moving the compat adjustments into fuse_simple_request() to after fuse_get_req(). This is also more readable than the original, since now compatibility is handled in a single function instead of cluttering each operation. Reported-by: Marc Dionne Tested-by: Marc Dionne Signed-off-by: Miklos Szeredi Fixes: 7078187a795f ("fuse: introduce fuse_simple_request() helper") diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index ba11079..c847d6b 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -511,6 +511,39 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) } EXPORT_SYMBOL_GPL(fuse_request_send); +static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args) +{ + if (fc->minor < 4 && args->in.h.opcode == FUSE_STATFS) + args->out.args[0].size = FUSE_COMPAT_STATFS_SIZE; + + if (fc->minor < 9) { + switch (args->in.h.opcode) { + case FUSE_LOOKUP: + case FUSE_CREATE: + case FUSE_MKNOD: + case FUSE_MKDIR: + case FUSE_SYMLINK: + case FUSE_LINK: + args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; + break; + case FUSE_GETATTR: + case FUSE_SETATTR: + args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; + break; + } + } + if (fc->minor < 12) { + switch (args->in.h.opcode) { + case FUSE_CREATE: + args->in.args[0].size = sizeof(struct fuse_open_in); + break; + case FUSE_MKNOD: + args->in.args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE; + break; + } + } +} + ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) { struct fuse_req *req; @@ -520,6 +553,9 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) if (IS_ERR(req)) return PTR_ERR(req); + /* Needs to be done after fuse_get_req() so that fc->minor is valid */ + fuse_adjust_compat(fc, args); + req->in.h.opcode = args->in.h.opcode; req->in.h.nodeid = args->in.h.nodeid; req->in.numargs = args->in.numargs; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 252b8a5..08e7b1a 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -156,10 +156,7 @@ static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args, args->in.args[0].size = name->len + 1; args->in.args[0].value = name->name; args->out.numargs = 1; - if (fc->minor < 9) - args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; - else - args->out.args[0].size = sizeof(struct fuse_entry_out); + args->out.args[0].size = sizeof(struct fuse_entry_out); args->out.args[0].value = outarg; } @@ -422,16 +419,12 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, args.in.h.opcode = FUSE_CREATE; args.in.h.nodeid = get_node_id(dir); args.in.numargs = 2; - args.in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) : - sizeof(inarg); + args.in.args[0].size = sizeof(inarg); args.in.args[0].value = &inarg; args.in.args[1].size = entry->d_name.len + 1; args.in.args[1].value = entry->d_name.name; args.out.numargs = 2; - if (fc->minor < 9) - args.out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; - else - args.out.args[0].size = sizeof(outentry); + args.out.args[0].size = sizeof(outentry); args.out.args[0].value = &outentry; args.out.args[1].size = sizeof(outopen); args.out.args[1].value = &outopen; @@ -539,10 +532,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, memset(&outarg, 0, sizeof(outarg)); args->in.h.nodeid = get_node_id(dir); args->out.numargs = 1; - if (fc->minor < 9) - args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; - else - args->out.args[0].size = sizeof(outarg); + args->out.args[0].size = sizeof(outarg); args->out.args[0].value = &outarg; err = fuse_simple_request(fc, args); if (err) @@ -592,8 +582,7 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode, inarg.umask = current_umask(); args.in.h.opcode = FUSE_MKNOD; args.in.numargs = 2; - args.in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE : - sizeof(inarg); + args.in.args[0].size = sizeof(inarg); args.in.args[0].value = &inarg; args.in.args[1].size = entry->d_name.len + 1; args.in.args[1].value = entry->d_name.name; @@ -899,10 +888,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat, args.in.args[0].size = sizeof(inarg); args.in.args[0].value = &inarg; args.out.numargs = 1; - if (fc->minor < 9) - args.out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; - else - args.out.args[0].size = sizeof(outarg); + args.out.args[0].size = sizeof(outarg); args.out.args[0].value = &outarg; err = fuse_simple_request(fc, &args); if (!err) { @@ -1574,10 +1560,7 @@ static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args, args->in.args[0].size = sizeof(*inarg_p); args->in.args[0].value = inarg_p; args->out.numargs = 1; - if (fc->minor < 9) - args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; - else - args->out.args[0].size = sizeof(*outarg_p); + args->out.args[0].size = sizeof(*outarg_p); args->out.args[0].value = outarg_p; } diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 6749109..6a20f2f 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -424,8 +424,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) args.in.h.opcode = FUSE_STATFS; args.in.h.nodeid = get_node_id(dentry->d_inode); args.out.numargs = 1; - args.out.args[0].size = - fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg); + args.out.args[0].size = sizeof(outarg); args.out.args[0].value = &outarg; err = fuse_simple_request(fc, &args); if (!err) -- cgit v0.10.2 From 9759bd51899458af4f4bcc11046f01285642ca10 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 6 Jan 2015 10:45:35 +0100 Subject: fuse: add memory barrier to INIT Theoretically we need to order setting of various fields in fc with fc->initialized. No known bug reports related to this yet. Signed-off-by: Miklos Szeredi diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index c847d6b..ed19a7d 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -131,6 +131,13 @@ static void fuse_req_init_context(struct fuse_req *req) req->in.h.pid = current->pid; } +void fuse_set_initialized(struct fuse_conn *fc) +{ + /* Make sure stores before this are seen on another CPU */ + smp_wmb(); + fc->initialized = 1; +} + static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background) { return !fc->initialized || (for_background && fc->blocked); @@ -155,6 +162,8 @@ static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages, if (intr) goto out; } + /* Matches smp_wmb() in fuse_set_initialized() */ + smp_rmb(); err = -ENOTCONN; if (!fc->connected) @@ -253,6 +262,8 @@ struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, atomic_inc(&fc->num_waiting); wait_event(fc->blocked_waitq, fc->initialized); + /* Matches smp_wmb() in fuse_set_initialized() */ + smp_rmb(); req = fuse_request_alloc(0); if (!req) req = get_reserved_req(fc, file); @@ -2163,7 +2174,7 @@ void fuse_abort_conn(struct fuse_conn *fc) if (fc->connected) { fc->connected = 0; fc->blocked = 0; - fc->initialized = 1; + fuse_set_initialized(fc); end_io_requests(fc); end_queued_requests(fc); end_polls(fc); @@ -2182,7 +2193,7 @@ int fuse_dev_release(struct inode *inode, struct file *file) spin_lock(&fc->lock); fc->connected = 0; fc->blocked = 0; - fc->initialized = 1; + fuse_set_initialized(fc); end_queued_requests(fc); end_polls(fc); wake_up_all(&fc->blocked_waitq); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index e0fc672..1cdfb07 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -906,4 +906,6 @@ int fuse_write_inode(struct inode *inode, struct writeback_control *wbc); int fuse_do_setattr(struct inode *inode, struct iattr *attr, struct file *file); +void fuse_set_initialized(struct fuse_conn *fc); + #endif /* _FS_FUSE_I_H */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 6a20f2f..f38256e 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -897,7 +897,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) fc->max_write = max_t(unsigned, 4096, fc->max_write); fc->conn_init = 1; } - fc->initialized = 1; + fuse_set_initialized(fc); wake_up_all(&fc->blocked_waitq); } -- cgit v0.10.2 From 6d40530e4789b3e2f14d61ca57ab02bd5395d5c9 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 6 Jan 2015 19:01:26 +0900 Subject: spi: sh-msiof: fix MDR1_FLD_MASK value Since the FLD bit field is bit[3:2], the MDR1_FLD_MASK value should be 0x0000000c. Signed-off-by: Yoshihiro Shimoda Acked-by: Geert Uytterhoeven Signed-off-by: Mark Brown diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 239be7c..87253ea 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -82,7 +82,7 @@ struct sh_msiof_spi_priv { #define MDR1_SYNCMD_LR 0x30000000 /* L/R mode */ #define MDR1_SYNCAC_SHIFT 25 /* Sync Polarity (1 = Active-low) */ #define MDR1_BITLSB_SHIFT 24 /* MSB/LSB First (1 = LSB first) */ -#define MDR1_FLD_MASK 0x000000c0 /* Frame Sync Signal Interval (0-3) */ +#define MDR1_FLD_MASK 0x0000000c /* Frame Sync Signal Interval (0-3) */ #define MDR1_FLD_SHIFT 2 #define MDR1_XXSTP 0x00000001 /* Transmission/Reception Stop on FIFO */ /* TMDR1 */ -- cgit v0.10.2 From 7a9f0604bd56936b2b18f49824e0e392dc7878c3 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 5 Jan 2015 15:19:08 -0200 Subject: ARM: dts: imx51-babbage: Fix ULPI PHY reset modelling GPIO2_5 is the reset GPIO for the USB3317 ULPI PHY. Instead of modelling it as a regulator, the correct approach is to use the 'reset_gpios' property of the "usb-nop-xceiv" node. GPIO1_7 is the reset GPIO for the USB2517 USB hub. As we currently don't have dt bindings to describe a HUB reset, let's keep using the regulator approach. Rename the regulator to 'reg_hub_reset' to better describe its function and bind it with the USB host1 port instead. USB host support has been introduced by commit 9bf206a9d13be3 ("ARM: dts: imx51-babbage: Add USB Host1 support"), which landed in 3.16 and it seems that USB has only been functional due to previous bootloader initialization. With this patch applied we can get USB host to work without relying on the bootloader. Cc: # 3.16+ Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index 56569ce..649befe 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -127,24 +127,12 @@ #address-cells = <1>; #size-cells = <0>; - reg_usbh1_vbus: regulator@0 { - compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usbh1reg>; - reg = <0>; - regulator-name = "usbh1_vbus"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - gpio = <&gpio2 5 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - reg_usbotg_vbus: regulator@1 { + reg_hub_reset: regulator@0 { compatible = "regulator-fixed"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbotgreg>; - reg = <1>; - regulator-name = "usbotg_vbus"; + reg = <0>; + regulator-name = "hub_reset"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>; @@ -176,6 +164,7 @@ reg = <0>; clocks = <&clks IMX5_CLK_DUMMY>; clock-names = "main_clk"; + reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; }; }; }; @@ -419,7 +408,7 @@ &usbh1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbh1>; - vbus-supply = <®_usbh1_vbus>; + vbus-supply = <®_hub_reset>; fsl,usbphy = <&usbh1phy>; phy_type = "ulpi"; status = "okay"; @@ -429,7 +418,6 @@ dr_mode = "otg"; disable-over-current; phy_type = "utmi_wide"; - vbus-supply = <®_usbotg_vbus>; status = "okay"; }; -- cgit v0.10.2 From d26eef8b725da620980ee20f7812f4488a206483 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 6 Jan 2015 18:50:22 +0800 Subject: Thermal: imx: add clk disable/enable for suspend/resume Thermal sensor's clk is from pll3_usb_otg, per hardware design requirement, need to make sure pll3_usb_otg is disabled before STOP mode is entered, otherwise, all PFDs under it may enter incorrect state, this patch disables pll3_usb_otg before suspend and enables it after resume. Signed-off-by: Anson Huang Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index c1188ac..2ccbc07 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -608,6 +608,7 @@ static int imx_thermal_suspend(struct device *dev) regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); data->mode = THERMAL_DEVICE_DISABLED; + clk_disable_unprepare(data->thermal_clk); return 0; } @@ -617,6 +618,7 @@ static int imx_thermal_resume(struct device *dev) struct imx_thermal_data *data = dev_get_drvdata(dev); struct regmap *map = data->tempmon; + clk_prepare_enable(data->thermal_clk); /* Enabled thermal sensor after resume */ regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); -- cgit v0.10.2 From 1ae78a4870989a354028cb17dabf819b595e70e3 Mon Sep 17 00:00:00 2001 From: David Peterson Date: Tue, 6 Jan 2015 15:00:52 +0000 Subject: USB: cp210x: add IDs for CEL USB sticks and MeshWorks devices Added virtual com port VID/PID entries for CEL USB sticks and MeshWorks devices. Signed-off-by: David Peterson Cc: stable Signed-off-by: Johan Hovold diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index fb8d3fa..f4c56fc 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -120,10 +120,12 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ - { USB_DEVICE(0x10C4, 0x8857) }, /* CEL MeshConnect USB Stick */ + { USB_DEVICE(0x10C4, 0x8856) }, /* CEL EM357 ZigBee USB Stick - LR */ + { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */ { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ + { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ -- cgit v0.10.2 From 7ac72746aa9bb305fa74b44ec73eae99bbbe9b66 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 6 Jan 2015 08:49:57 -0800 Subject: ARM: dts: Revert disabling of smc91x for n900 Revert "ARM: dts: Disable smc91x on n900 until bootloader dependency is removed". We've now fixed the issues that caused problems with uninitialized hardware depending on the bootloader version. Mostly things got fixed with the following commits: 9a894953a97b ("ARM: dts: Fix bootloader version dependencies by muxing n900 smc91x pins") 7d2911c43815 ("net: smc91x: Fix gpios for device tree based booting") Note that this only affects the early development boards with Ethernet that we still have in a few automated boot test systems. And it's also available supposedly in some versions of qemu. Tested-by: Kevin Hilman Tested-by: Aaro Koskinen Signed-off-by: Tony Lindgren diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 53f3ca0..b550c41 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -700,11 +700,9 @@ }; }; + /* Ethernet is on some early development boards and qemu */ ethernet@gpmc { compatible = "smsc,lan91c94"; - - status = "disabled"; - interrupt-parent = <&gpio2>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; /* gpio54 */ reg = <1 0x300 0xf>; /* 16 byte IO range at offset 0x300 */ -- cgit v0.10.2 From 9477e18dd5d6c575ed972d81b7d9d6ff8a83746b Mon Sep 17 00:00:00 2001 From: Javi Merino Date: Tue, 6 Jan 2015 18:14:25 +0000 Subject: Documentation: thermal: document of_cpufreq_cooling_register() Commit 39d99cff76bf ("thermal: cpu_cooling: introduce of_cpufreq_cooling_register") taught the cpu cooling device to register devices that were linked to the device tree but didn't update the cpu-cooling-api documentation. Fix it. Cc: Amit Daniel Kachhap Cc: Jonathan Corbet Cc: Zhang Rui Cc: Eduardo Valentin Signed-off-by: Javi Merino Signed-off-by: Eduardo Valentin diff --git a/Documentation/thermal/cpu-cooling-api.txt b/Documentation/thermal/cpu-cooling-api.txt index fca24c9..753e47c 100644 --- a/Documentation/thermal/cpu-cooling-api.txt +++ b/Documentation/thermal/cpu-cooling-api.txt @@ -3,7 +3,7 @@ CPU cooling APIs How To Written by Amit Daniel Kachhap -Updated: 12 May 2012 +Updated: 6 Jan 2015 Copyright (c) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) @@ -25,7 +25,18 @@ the user. The registration APIs returns the cooling device pointer. clip_cpus: cpumask of cpus where the frequency constraints will happen. -1.1.2 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) +1.1.2 struct thermal_cooling_device *of_cpufreq_cooling_register( + struct device_node *np, const struct cpumask *clip_cpus) + + This interface function registers the cpufreq cooling device with + the name "thermal-cpufreq-%x" linking it with a device tree node, in + order to bind it via the thermal DT code. This api can support multiple + instances of cpufreq cooling devices. + + np: pointer to the cooling device device tree node + clip_cpus: cpumask of cpus where the frequency constraints will happen. + +1.1.3 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) This interface function unregisters the "thermal-cpufreq-%x" cooling device. -- cgit v0.10.2 From 32ac7cb262177f58c7c8846311599460e5e7e3c5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 6 Jan 2015 18:36:44 -0500 Subject: libata: clean up MAINTAINERS entries Make all libata entries start with LIBATA and collect them in one place. Driver specfic ones have the second SATA or PATA prefix. Signed-off-by: Tejun Heo diff --git a/MAINTAINERS b/MAINTAINERS index ddb9ac8..c20aebe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -754,13 +754,6 @@ L: linux-media@vger.kernel.org S: Maintained F: drivers/media/i2c/aptina-pll.* -ARASAN COMPACT FLASH PATA CONTROLLER -M: Viresh Kumar -L: linux-ide@vger.kernel.org -S: Maintained -F: include/linux/pata_arasan_cf_data.h -F: drivers/ata/pata_arasan_cf.c - ARC FRAMEBUFFER DRIVER M: Jaya Kumar S: Maintained @@ -5693,6 +5686,40 @@ F: drivers/lguest/ F: include/linux/lguest*.h F: tools/lguest/ +LIBATA SUBSYSTEM (Serial and Parallel ATA drivers) +M: Tejun Heo +L: linux-ide@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git +S: Maintained +F: drivers/ata/ +F: include/linux/ata.h +F: include/linux/libata.h + +LIBATA PATA ARASAN COMPACT FLASH CONTROLLER +M: Viresh Kumar +L: linux-ide@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git +S: Maintained +F: include/linux/pata_arasan_cf_data.h +F: drivers/ata/pata_arasan_cf.c + +LIBATA SATA AHCI PLATFORM devices support +M: Hans de Goede +M: Tejun Heo +L: linux-ide@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git +S: Maintained +F: drivers/ata/ahci_platform.c +F: drivers/ata/libahci_platform.c +F: include/linux/ahci_platform.h + +LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER +M: Mikael Pettersson +L: linux-ide@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git +S: Maintained +F: drivers/ata/sata_promise.* + LIBLOCKDEP M: Sasha Levin S: Maintained @@ -7566,12 +7593,6 @@ W: http://wireless.kernel.org/en/users/Drivers/p54 S: Obsolete F: drivers/net/wireless/prism54/ -PROMISE SATA TX2/TX4 CONTROLLER LIBATA DRIVER -M: Mikael Pettersson -L: linux-ide@vger.kernel.org -S: Maintained -F: drivers/ata/sata_promise.* - PS3 NETWORK SUPPORT M: Geoff Levand L: netdev@vger.kernel.org @@ -8546,25 +8567,6 @@ S: Maintained F: drivers/misc/phantom.c F: include/uapi/linux/phantom.h -SERIAL ATA (SATA) SUBSYSTEM -M: Tejun Heo -L: linux-ide@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git -S: Supported -F: drivers/ata/ -F: include/linux/ata.h -F: include/linux/libata.h - -SERIAL ATA AHCI PLATFORM devices support -M: Hans de Goede -M: Tejun Heo -L: linux-ide@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git -S: Supported -F: drivers/ata/ahci_platform.c -F: drivers/ata/libahci_platform.c -F: include/linux/ahci_platform.h - SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER M: Jayamohan Kallickal L: linux-scsi@vger.kernel.org -- cgit v0.10.2 From c7fa056c820fef26de34d346b148943e717958a0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 2 Dec 2014 17:29:08 +0100 Subject: ata: add MAINTAINERS entry for libata PATA drivers Add myself as the primary maintainer for libata PATA drivers. The merging process would remain unchanged with patches going through Tejun's tree. Cc: Alan Cox Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Kyungmin Park Signed-off-by: Tejun Heo diff --git a/MAINTAINERS b/MAINTAINERS index c20aebe..5d7b387 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5703,6 +5703,15 @@ S: Maintained F: include/linux/pata_arasan_cf_data.h F: drivers/ata/pata_arasan_cf.c +LIBATA PATA DRIVERS +M: Bartlomiej Zolnierkiewicz +M: Tejun Heo +L: linux-ide@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git +S: Maintained +F: drivers/ata/pata_*.c +F: drivers/ata/ata_generic.c + LIBATA SATA AHCI PLATFORM devices support M: Hans de Goede M: Tejun Heo -- cgit v0.10.2 From 596c4051eb6b0c7f5fc5437c2269b7191b59ff3b Mon Sep 17 00:00:00 2001 From: Yingjoe Chen Date: Wed, 10 Dec 2014 17:55:02 +0800 Subject: irqchip: mtk-sysirq: Use IS_ERR() instead of NULL pointer check Beniamino noticed a bug that an invalid DT file for the mediatek interrupt polarity extension will cause kernel oops. The reason is that the interrupt polarity support for mediatek chips merely checks for NULL pointer instead of a casted error return value in mtk_sysirq_of_init() so any other casted error value passes the NULL pointer check and causes a kernel panic when dereferenced. Use IS_ERR() and return the error value via PTR_ERR(). [ jac: took V2 over V3 for diff formatting, hand-added V3 changes, tweaked subject line. ] Reported-by: Beniamino Galvani Signed-off-by: Yingjoe Chen Link: https://lkml.kernel.org/r/1418205302-22531-1-git-send-email-yingjoe.chen@mediatek.com Signed-off-by: Jason Cooper diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c index 7e342df..0b0d2c0 100644 --- a/drivers/irqchip/irq-mtk-sysirq.c +++ b/drivers/irqchip/irq-mtk-sysirq.c @@ -137,9 +137,9 @@ static int __init mtk_sysirq_of_init(struct device_node *node, return -ENOMEM; chip_data->intpol_base = of_io_request_and_map(node, 0, "intpol"); - if (!chip_data->intpol_base) { + if (IS_ERR(chip_data->intpol_base)) { pr_err("mtk_sysirq: unable to map sysirq register\n"); - ret = -ENOMEM; + ret = PTR_ERR(chip_data->intpol_base); goto out_free; } -- cgit v0.10.2 From 03d3d45be413196790f82d601dc0527539804830 Mon Sep 17 00:00:00 2001 From: Wang Long Date: Thu, 11 Dec 2014 11:03:36 +0000 Subject: irqchip: hip04: Initialize hip04_cpu_map to 0xffff HiP04 GIC extends to support 16 cores, so we should initialize the hip04_cpu_map to 0xffff. Signed-off-by: Wang Long Acked-by: Haojian Zhuang Link: https://lkml.kernel.org/r/1418295816-179583-1-git-send-email-long.wanglong@huawei.com Signed-off-by: Jason Cooper diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c index 29b8f21..6bc2deb 100644 --- a/drivers/irqchip/irq-hip04.c +++ b/drivers/irqchip/irq-hip04.c @@ -381,7 +381,7 @@ hip04_of_init(struct device_node *node, struct device_node *parent) * It will be refined as each CPU probes its ID. */ for (i = 0; i < NR_HIP04_CPU_IF; i++) - hip04_cpu_map[i] = 0xff; + hip04_cpu_map[i] = 0xffff; /* * Find out how many interrupts are supported. -- cgit v0.10.2 From 96555c474b917963da7065f88cdab376c8af0e87 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 17 Dec 2014 14:11:09 +0000 Subject: irqchip: gic-v3-its: Fix use of max with decimal constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit arm64 defconfig spits out the following compiler warning from the ITS driver: In file included from include/linux/bitmap.h:9:0, from drivers/irqchip/irq-gic-v3-its.c:18: drivers/irqchip/irq-gic-v3-its.c: In function ‘its_create_device’: include/linux/kernel.h:716:17: warning: comparison of distinct pointer types lacks a cast (void) (&_max1 == &_max2); \ ^ drivers/irqchip/irq-gic-v3-its.c:1056:12: note: in expansion of macro ‘max’ nr_ites = max(2, roundup_pow_of_two(nvecs)); Fix the warning by specifying the decimal constant `2' explicitly as an unsigned long type. Cc: Marc Zyngier Signed-off-by: Will Deacon Acked-by: Marc Zyngier Link: https://lkml.kernel.org/r/1418825469-30529-1-git-send-email-will.deacon@arm.com Signed-off-by: Jason Cooper diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 86e4684..d8996bd 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1053,7 +1053,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, * of two entries. No, the architecture doesn't let you * express an ITT with a single entry. */ - nr_ites = max(2, roundup_pow_of_two(nvecs)); + nr_ites = max(2UL, roundup_pow_of_two(nvecs)); sz = nr_ites * its->ite_size; sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; itt = kmalloc(sz, GFP_KERNEL); -- cgit v0.10.2 From 4b149e417463bbb6d1d9b805f729627ca2b54495 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 6 Jan 2015 14:38:08 -0600 Subject: irqchip: omap-intc: Fix legacy DMA regression commit 55601c9f2467 (arm: omap: intc: switch over to linear irq domain) introduced a regression with SDMA legacy driver because that driver strictly depends on INTC's IRQs starting at NR_IRQs. Aparently irq_domain_add_linear() won't guarantee that, since we see a 7 IRQs difference when booting with and without the commit cited above. Until arch/arm/plat-omap/dma.c is properly fixed, we must maintain OMAP2/3 using irq_domain_add_legacy(). A FIXME note was added so people know to delete that code once that legacy DMA driver is fixed up. Fixes: 55601c9f2467 (arm: omap: intc: switch over to linear irq domain) Cc: # v3.18 Tested-by: Aaro Koskinen Tested-by: Tony Lindgren Signed-off-by: Felipe Balbi Link: https://lkml.kernel.org/r/1420576688-10604-1-git-send-email-balbi@ti.com Signed-off-by: Jason Cooper diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c index 28718d3..c03f140 100644 --- a/drivers/irqchip/irq-omap-intc.c +++ b/drivers/irqchip/irq-omap-intc.c @@ -263,7 +263,7 @@ static int __init omap_init_irq_of(struct device_node *node) return ret; } -static int __init omap_init_irq_legacy(u32 base) +static int __init omap_init_irq_legacy(u32 base, struct device_node *node) { int j, irq_base; @@ -277,7 +277,7 @@ static int __init omap_init_irq_legacy(u32 base) irq_base = 0; } - domain = irq_domain_add_legacy(NULL, omap_nr_irqs, irq_base, 0, + domain = irq_domain_add_legacy(node, omap_nr_irqs, irq_base, 0, &irq_domain_simple_ops, NULL); omap_irq_soft_reset(); @@ -301,10 +301,26 @@ static int __init omap_init_irq(u32 base, struct device_node *node) { int ret; - if (node) + /* + * FIXME legacy OMAP DMA driver sitting under arch/arm/plat-omap/dma.c + * depends is still not ready for linear IRQ domains; because of that + * we need to temporarily "blacklist" OMAP2 and OMAP3 devices from using + * linear IRQ Domain until that driver is finally fixed. + */ + if (of_device_is_compatible(node, "ti,omap2-intc") || + of_device_is_compatible(node, "ti,omap3-intc")) { + struct resource res; + + if (of_address_to_resource(node, 0, &res)) + return -ENOMEM; + + base = res.start; + ret = omap_init_irq_legacy(base, node); + } else if (node) { ret = omap_init_irq_of(node); - else - ret = omap_init_irq_legacy(base); + } else { + ret = omap_init_irq_legacy(base, NULL); + } if (ret == 0) omap_irq_enable_protection(); -- cgit v0.10.2 From d80c0d14183516f184a5ac88e11008ee4c7d2a2e Mon Sep 17 00:00:00 2001 From: Reinhard Speyerer Date: Tue, 6 Jan 2015 22:06:38 +0100 Subject: USB: qcserial/option: make AT URCs work for Sierra Wireless MC73xx As has been discussed in the thread starting with https://lkml.kernel.org/g/549748e9.d+SiJzqu50f1r4lSAL043YSc@arcor.de Sierra Wireless MC73xx devices with USB VID/PID 0x1199:0x68c0 require the option_send_setup() code to be used on the USB interface for the AT port to make unsolicited response codes work correctly. Move these devices from the qcserial driver where they have been added by commit 70a3615fc07c2330ed7c1e922f3c44f4a67c0762 ("usb: qcserial: add Sierra Wireless MC73xx") to the option driver and add a MC73xx-specific blacklist to ensure that 1. the sendsetup code is not used for the DIAG/DM and NMEA interfaces 2. the option driver does not attach to the QMI/network interfaces Signed-off-by: Reinhard Speyerer Cc: stable Signed-off-by: Johan Hovold diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7a4c21b..efdcee1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -234,6 +234,8 @@ static void option_instat_callback(struct urb *urb); #define QUALCOMM_VENDOR_ID 0x05C6 +#define SIERRA_VENDOR_ID 0x1199 + #define CMOTECH_VENDOR_ID 0x16d8 #define CMOTECH_PRODUCT_6001 0x6001 #define CMOTECH_PRODUCT_CMU_300 0x6002 @@ -512,7 +514,7 @@ enum option_blacklist_reason { OPTION_BLACKLIST_RESERVED_IF = 2 }; -#define MAX_BL_NUM 8 +#define MAX_BL_NUM 11 struct option_blacklist_info { /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */ const unsigned long sendsetup; @@ -601,6 +603,11 @@ static const struct option_blacklist_info telit_le920_blacklist = { .reserved = BIT(1) | BIT(5), }; +static const struct option_blacklist_info sierra_mc73xx_blacklist = { + .sendsetup = BIT(0) | BIT(2), + .reserved = BIT(8) | BIT(10) | BIT(11), +}; + static const struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -1098,6 +1105,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ + { USB_DEVICE_INTERFACE_CLASS(SIERRA_VENDOR_ID, 0x68c0, 0xff), + .driver_info = (kernel_ulong_t)&sierra_mc73xx_blacklist }, /* MC73xx */ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index cb3e147..9c63897 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -142,7 +142,6 @@ static const struct usb_device_id id_table[] = { {DEVICE_SWI(0x0f3d, 0x68a2)}, /* Sierra Wireless MC7700 */ {DEVICE_SWI(0x114f, 0x68a2)}, /* Sierra Wireless MC7750 */ {DEVICE_SWI(0x1199, 0x68a2)}, /* Sierra Wireless MC7710 */ - {DEVICE_SWI(0x1199, 0x68c0)}, /* Sierra Wireless MC73xx */ {DEVICE_SWI(0x1199, 0x901c)}, /* Sierra Wireless EM7700 */ {DEVICE_SWI(0x1199, 0x901f)}, /* Sierra Wireless EM7355 */ {DEVICE_SWI(0x1199, 0x9040)}, /* Sierra Wireless Modem */ -- cgit v0.10.2 From 91d1179212161f220938198b742c328ad38fd0a3 Mon Sep 17 00:00:00 2001 From: Gavin Li Date: Tue, 6 Jan 2015 18:47:23 -0800 Subject: irqchip: atmel-aic-common: Prevent clobbering of priority when changing IRQ type This patch makes the bitmask for AIC_SRCTYPE consistent with that of its valid values, and prevents the priority field at bits 2:0 from being clobbered by an incorrect AND with the AIC_SRCTYPE mask. Signed-off-by: Gavin Li Cc: # v3.17+ Acked-by: Boris Brezillon Acked-by: Nicolas Ferre Link: https://lkml.kernel.org/r/1420598843-8409-1-git-send-email-gavinli@thegavinli.com Signed-off-by: Jason Cooper diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index d111ac7..63cd031 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -28,7 +28,7 @@ #define AT91_AIC_IRQ_MIN_PRIORITY 0 #define AT91_AIC_IRQ_MAX_PRIORITY 7 -#define AT91_AIC_SRCTYPE GENMASK(7, 6) +#define AT91_AIC_SRCTYPE GENMASK(6, 5) #define AT91_AIC_SRCTYPE_LOW (0 << 5) #define AT91_AIC_SRCTYPE_FALLING (1 << 5) #define AT91_AIC_SRCTYPE_HIGH (2 << 5) @@ -74,7 +74,7 @@ int aic_common_set_type(struct irq_data *d, unsigned type, unsigned *val) return -EINVAL; } - *val &= AT91_AIC_SRCTYPE; + *val &= ~AT91_AIC_SRCTYPE; *val |= aic_type; return 0; -- cgit v0.10.2 From 11313746547015ace605c4c347a40350753051e4 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 7 Jan 2015 10:13:10 +0900 Subject: thermal: rcar: fix ENR register value On R-Mobile APE6, since it has 3 thermal zones, ENR register has enable bits in bit 19-16, bit 11-8 and bit 3-0. However, on R-Car gen2, since it has 1 thermal zone, ENR register has enable bits in bit 3-0. (In other words, the write value should always be 0 for bit 31-4 of ENR register.) So, this patch fixes the ENR register value using I/O resource sets. Acked-by: Geert Uytterhoeven Signed-off-by: Yoshihiro Shimoda Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 8803e69..2f3b4ff 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -372,6 +372,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) int i; int ret = -ENODEV; int idle = IDLE_INTERVAL; + u32 enr_bits = 0; common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL); if (!common) @@ -408,9 +409,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) if (IS_ERR(common->base)) return PTR_ERR(common->base); - /* enable temperature comparation */ - rcar_thermal_common_write(common, ENR, 0x00030303); - idle = 0; /* polling delay is not needed */ } @@ -452,8 +450,15 @@ static int rcar_thermal_probe(struct platform_device *pdev) rcar_thermal_irq_enable(priv); list_move_tail(&priv->list, &common->head); + + /* update ENR bits */ + enr_bits |= 3 << (i * 8); } + /* enable temperature comparation */ + if (irq) + rcar_thermal_common_write(common, ENR, enr_bits); + platform_set_drvdata(pdev, common); dev_info(dev, "%d sensor probed\n", i); -- cgit v0.10.2 From cc72f6e227b8091e0b8297a6be266bedcb20a5aa Mon Sep 17 00:00:00 2001 From: John Linville Date: Tue, 6 Jan 2015 14:39:33 -0500 Subject: mac80211: uninitialized return val in __ieee80211_sta_handle_tspec_ac_params The return value should be initialized to false so that there's a valid return value when there are no sessions that need work to be done on them. Luckily, the side effect of using the uninitialized value is an extra harmless driver call. Coverity: CID 1260096 Fixes: 02219b3abca59 ("mac80211: add WMM admission control support") Signed-off-by: John W. Linville [extend commit message] Signed-off-by: Johannes Berg diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2c36c47..837a406 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1643,7 +1643,7 @@ __ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; - bool ret; + bool ret = false; int ac; if (local->hw.queues < IEEE80211_NUM_ACS) -- cgit v0.10.2 From 913015c6df9a18ad27365afed6f409c024002aab Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 7 Jan 2015 10:13:11 +0900 Subject: thermal: rcar: change type of ctemp in rcar_thermal_update_temp() Since the ctemp is used for rcar_thermal_write() in rcar_thermal_update_temp(), the type of 'ctemp' should be "u32" instead of "int". This patch also changes type of the helper variables 'old' and 'new'. Acked-by: Geert Uytterhoeven Signed-off-by: Yoshihiro Shimoda Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 2f3b4ff..70bb02c 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -63,7 +63,7 @@ struct rcar_thermal_priv { struct mutex lock; struct list_head list; int id; - int ctemp; + u32 ctemp; }; #define rcar_thermal_for_each_priv(pos, common) \ @@ -145,7 +145,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) { struct device *dev = rcar_priv_to_dev(priv); int i; - int ctemp, old, new; + u32 ctemp, old, new; int ret = -EINVAL; mutex_lock(&priv->lock); -- cgit v0.10.2 From 20658702e08ecd693236b443837d28863b93e872 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 29 Dec 2014 11:59:59 +0200 Subject: cfg80211: fix deadlock during reg chan check If a P2P GO is active, the cfg80211_reg_can_beacon function will take the wdev lock, in its call to cfg80211_go_permissive_chan. But the wdev lock is already taken by the parent channel-checking function, causing a deadlock. Split the checking code into two parts. The first part will check if the wdev is active and saves the channel under the wdev lock. The second part will check actual channel validity according to type. Signed-off-by: Arik Nemtsov Reviewed-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 7b83098..d39d1cb 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1530,45 +1530,40 @@ static void reg_call_notifier(struct wiphy *wiphy, static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) { - struct ieee80211_channel *ch; struct cfg80211_chan_def chandef; struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - bool ret = true; + enum nl80211_iftype iftype; wdev_lock(wdev); + iftype = wdev->iftype; + /* make sure the interface is active */ if (!wdev->netdev || !netif_running(wdev->netdev)) - goto out; + goto wdev_inactive_unlock; - switch (wdev->iftype) { + switch (iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: if (!wdev->beacon_interval) - goto out; - - ret = cfg80211_reg_can_beacon(wiphy, - &wdev->chandef, wdev->iftype); + goto wdev_inactive_unlock; + chandef = wdev->chandef; break; case NL80211_IFTYPE_ADHOC: if (!wdev->ssid_len) - goto out; - - ret = cfg80211_reg_can_beacon(wiphy, - &wdev->chandef, wdev->iftype); + goto wdev_inactive_unlock; + chandef = wdev->chandef; break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: if (!wdev->current_bss || !wdev->current_bss->pub.channel) - goto out; + goto wdev_inactive_unlock; - ch = wdev->current_bss->pub.channel; - if (rdev->ops->get_channel && - !rdev_get_channel(rdev, wdev, &chandef)) - ret = cfg80211_chandef_usable(wiphy, &chandef, - IEEE80211_CHAN_DISABLED); - else - ret = !(ch->flags & IEEE80211_CHAN_DISABLED); + if (!rdev->ops->get_channel || + rdev_get_channel(rdev, wdev, &chandef)) + cfg80211_chandef_create(&chandef, + wdev->current_bss->pub.channel, + NL80211_CHAN_NO_HT); break; case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: @@ -1581,9 +1576,26 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) break; } -out: wdev_unlock(wdev); - return ret; + + switch (iftype) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_ADHOC: + return cfg80211_reg_can_beacon(wiphy, &chandef, iftype); + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + return cfg80211_chandef_usable(wiphy, &chandef, + IEEE80211_CHAN_DISABLED); + default: + break; + } + + return true; + +wdev_inactive_unlock: + wdev_unlock(wdev); + return true; } static void reg_leave_invalid_chans(struct wiphy *wiphy) -- cgit v0.10.2 From 96ed6046d3bf1113de3bdbd6dbb7f40e6d0ae0ef Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Wed, 31 Dec 2014 16:57:50 +0800 Subject: ARM: dts: berlin: fix io clk and add missing core clk for BG2Q sdhci2 host On BG2Q, the sdhci2 host uses nfcecc for "io" clk and nfc for "core" clk. The shdci2 can't work without this patch due to the "core" clk is gated. Cc: stable@vger.kernel.org # 3.16+ Fixes: 0d859a6a9d14 ("ARM: dts: berlin: add the SDHCI nodes for the BG2Q") Signed-off-by: Jisheng Zhang Signed-off-by: Sebastian Hesselbarth diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi index 35253c9..903f3bb 100644 --- a/arch/arm/boot/dts/berlin2q.dtsi +++ b/arch/arm/boot/dts/berlin2q.dtsi @@ -83,7 +83,8 @@ compatible = "mrvl,pxav3-mmc"; reg = <0xab1000 0x200>; interrupts = ; - clocks = <&chip CLKID_SDIO1XIN>; + clocks = <&chip CLKID_NFC_ECC>, <&chip CLKID_NFC>; + clock-names = "io", "core"; status = "disabled"; }; -- cgit v0.10.2 From 5adba7c2daaecccf377e7ed5a2996caedd5384f1 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Wed, 31 Dec 2014 16:57:51 +0800 Subject: ARM: dts: berlin: add broken-cd and set bus width for eMMC in Marvell DMP DT There's no card detection for the eMMC, so this patch adds the missing broken-cd property. This patch also sets bus width as 8 to add MMC_CAP_8_BIT_DATA in the Host capabilities. Cc: stable@vger.kernel.org # 3.16+ Fixes: 3047086dfd56 ("ARM: dts: berlin: enable SD card reader and eMMC for the BG2Q DMP") Signed-off-by: Jisheng Zhang Signed-off-by: Sebastian Hesselbarth diff --git a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts index 28e7e20..a98ac1b 100644 --- a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts +++ b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts @@ -65,6 +65,8 @@ }; &sdhci2 { + broken-cd; + bus-width = <8>; non-removable; status = "okay"; }; -- cgit v0.10.2 From 5138d5c562e3bfe30964e20ab46eec9f8b89225d Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 26 Dec 2014 16:58:01 +0800 Subject: ARM: dts: berlin: correct BG2Q's SM GPIO location. The gpio4 and gpio5 are in 0xf7fc0000 apb which is located in the SM domain. This patch moves gpio4 and gpio5 to the correct location. This patch also renames them as the following to match the names we internally used in marvell: gpio4 -> sm_gpio1 gpio5 -> sm_gpio0 porte -> portf portf -> porte This also matches what we did for BG2 and BG2CD's SM GPIO. Cc: stable@vger.kernel.org # 3.16+ Fixes: cedf57fc4f2f ("ARM: dts: berlin: add the BG2Q GPIO nodes") Signed-off-by: Jisheng Zhang Signed-off-by: Sebastian Hesselbarth diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi index 903f3bb..e2f61f2 100644 --- a/arch/arm/boot/dts/berlin2q.dtsi +++ b/arch/arm/boot/dts/berlin2q.dtsi @@ -349,36 +349,6 @@ interrupt-parent = <&gic>; interrupts = ; }; - - gpio4: gpio@5000 { - compatible = "snps,dw-apb-gpio"; - reg = <0x5000 0x400>; - #address-cells = <1>; - #size-cells = <0>; - - porte: gpio-port@4 { - compatible = "snps,dw-apb-gpio-port"; - gpio-controller; - #gpio-cells = <2>; - snps,nr-gpios = <32>; - reg = <0>; - }; - }; - - gpio5: gpio@c000 { - compatible = "snps,dw-apb-gpio"; - reg = <0xc000 0x400>; - #address-cells = <1>; - #size-cells = <0>; - - portf: gpio-port@5 { - compatible = "snps,dw-apb-gpio-port"; - gpio-controller; - #gpio-cells = <2>; - snps,nr-gpios = <32>; - reg = <0>; - }; - }; }; chip: chip-control@ea0000 { @@ -467,6 +437,21 @@ ranges = <0 0xfc0000 0x10000>; interrupt-parent = <&sic>; + sm_gpio1: gpio@5000 { + compatible = "snps,dw-apb-gpio"; + reg = <0x5000 0x400>; + #address-cells = <1>; + #size-cells = <0>; + + portf: gpio-port@5 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + reg = <0>; + }; + }; + i2c2: i2c@7000 { compatible = "snps,designware-i2c"; #address-cells = <1>; @@ -517,6 +502,21 @@ status = "disabled"; }; + sm_gpio0: gpio@c000 { + compatible = "snps,dw-apb-gpio"; + reg = <0xc000 0x400>; + #address-cells = <1>; + #size-cells = <0>; + + porte: gpio-port@4 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + reg = <0>; + }; + }; + sysctrl: pin-controller@d000 { compatible = "marvell,berlin2q-system-ctrl"; reg = <0xd000 0x100>; -- cgit v0.10.2 From 4aaa71873ddb9faf4b0c4826579e2f6d18ff9ab4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 7 Jan 2015 15:24:19 +0200 Subject: sata_dwc_460ex: fix resource leak on error path DMA mapped IO should be unmapped on the error path in probe() and unconditionally on remove(). Fixes: 62936009f35a ([libata] Add 460EX on-chip SATA driver, sata_dwc_460ex) Signed-off-by: Andy Shevchenko Signed-off-by: Tejun Heo diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index c7ddef8..8e824817 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -797,7 +797,7 @@ static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq) if (err) { dev_err(host_pvt.dwc_dev, "%s: dma_request_interrupts returns" " %d\n", __func__, err); - goto error_out; + return err; } /* Enabe DMA */ @@ -808,11 +808,6 @@ static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq) sata_dma_regs); return 0; - -error_out: - dma_dwc_exit(hsdev); - - return err; } static int sata_dwc_scr_read(struct ata_link *link, unsigned int scr, u32 *val) @@ -1662,7 +1657,7 @@ static int sata_dwc_probe(struct platform_device *ofdev) char *ver = (char *)&versionr; u8 *base = NULL; int err = 0; - int irq, rc; + int irq; struct ata_host *host; struct ata_port_info pi = sata_dwc_port_info[0]; const struct ata_port_info *ppi[] = { &pi, NULL }; @@ -1725,7 +1720,7 @@ static int sata_dwc_probe(struct platform_device *ofdev) if (irq == NO_IRQ) { dev_err(&ofdev->dev, "no SATA DMA irq\n"); err = -ENODEV; - goto error_out; + goto error_iomap; } /* Get physical SATA DMA register base address */ @@ -1734,14 +1729,16 @@ static int sata_dwc_probe(struct platform_device *ofdev) dev_err(&ofdev->dev, "ioremap failed for AHBDMA register" " address\n"); err = -ENODEV; - goto error_out; + goto error_iomap; } /* Save dev for later use in dev_xxx() routines */ host_pvt.dwc_dev = &ofdev->dev; /* Initialize AHB DMAC */ - dma_dwc_init(hsdev, irq); + err = dma_dwc_init(hsdev, irq); + if (err) + goto error_dma_iomap; /* Enable SATA Interrupts */ sata_dwc_enable_interrupts(hsdev); @@ -1759,9 +1756,8 @@ static int sata_dwc_probe(struct platform_device *ofdev) * device discovery process, invoking our port_start() handler & * error_handler() to execute a dummy Softreset EH session */ - rc = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht); - - if (rc != 0) + err = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht); + if (err) dev_err(&ofdev->dev, "failed to activate host"); dev_set_drvdata(&ofdev->dev, host); @@ -1770,7 +1766,8 @@ static int sata_dwc_probe(struct platform_device *ofdev) error_out: /* Free SATA DMA resources */ dma_dwc_exit(hsdev); - +error_dma_iomap: + iounmap((void __iomem *)host_pvt.sata_dma_regs); error_iomap: iounmap(base); error_kmalloc: @@ -1791,6 +1788,7 @@ static int sata_dwc_remove(struct platform_device *ofdev) /* Free SATA DMA resources */ dma_dwc_exit(hsdev); + iounmap((void __iomem *)host_pvt.sata_dma_regs); iounmap(hsdev->reg_base); kfree(hsdev); kfree(host); -- cgit v0.10.2 From 6ada1fc0e1c4775de0e043e1bd3ae9d065491aa5 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 3 Dec 2014 19:22:48 -0500 Subject: time: settimeofday: Validate the values of tv from user An unvalidated user input is multiplied by a constant, which can result in an undefined behaviour for large values. While this is validated later, we should avoid triggering undefined behaviour. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: stable Signed-off-by: Sasha Levin [jstultz: include trivial milisecond->microsecond correction noticed by Andy] Signed-off-by: John Stultz diff --git a/include/linux/time.h b/include/linux/time.h index 8c42cf8..5989b0e 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -99,6 +99,19 @@ static inline bool timespec_valid_strict(const struct timespec *ts) return true; } +static inline bool timeval_valid(const struct timeval *tv) +{ + /* Dates before 1970 are bogus */ + if (tv->tv_sec < 0) + return false; + + /* Can't have more microseconds then a second */ + if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC) + return false; + + return true; +} + extern struct timespec timespec_trunc(struct timespec t, unsigned gran); #define CURRENT_TIME (current_kernel_time()) diff --git a/kernel/time/time.c b/kernel/time/time.c index a9ae20f..22d5d3b 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -196,6 +196,10 @@ SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv, if (tv) { if (copy_from_user(&user_tv, tv, sizeof(*tv))) return -EFAULT; + + if (!timeval_valid(&user_tv)) + return -EINVAL; + new_ts.tv_sec = user_tv.tv_sec; new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC; } -- cgit v0.10.2 From 5e5aeb4367b450a28f447f6d5ab57d8f2ab16a5f Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 3 Dec 2014 19:25:05 -0500 Subject: time: adjtimex: Validate the ADJ_FREQUENCY values Verify that the frequency value from userspace is valid and makes sense. Unverified values can cause overflows later on. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: stable Signed-off-by: Sasha Levin [jstultz: Fix up bug for negative values and drop redunent cap check] Signed-off-by: John Stultz diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 87a346f..28bf91c 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -633,6 +633,13 @@ int ntp_validate_timex(struct timex *txc) if ((txc->modes & ADJ_SETOFFSET) && (!capable(CAP_SYS_TIME))) return -EPERM; + if (txc->modes & ADJ_FREQUENCY) { + if (LONG_MIN / PPM_SCALE > txc->freq) + return -EINVAL; + if (LONG_MAX / PPM_SCALE < txc->freq) + return -EINVAL; + } + return 0; } -- cgit v0.10.2 From 3dbb3b98e854bceed38fbde930fb8cf8701def73 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 7 Jan 2015 16:56:54 +0200 Subject: spi: dw: amend warning message In case of warning message in ->probe() we have to use HW device name instead of master because last is not defined yet. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 1a0f266..8edcd1b 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -673,7 +673,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) if (dws->dma_ops && dws->dma_ops->dma_init) { ret = dws->dma_ops->dma_init(dws); if (ret) { - dev_warn(&master->dev, "DMA init failed\n"); + dev_warn(dev, "DMA init failed\n"); dws->dma_inited = 0; } } -- cgit v0.10.2 From 4f0d4fac24405098ad2f65f3f996f525e7d04703 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 29 Dec 2014 15:58:04 -0800 Subject: MAINTAINERS: remove Dmitry Torokhov's alternate address I am using gmail.com exclusively and mail.ru was a backup that so far was not needed. To avoid getting 2 copies of the same message let's drop mail.ru from MAINTAINERS file. Signed-off-by: Dmitry Torokhov diff --git a/MAINTAINERS b/MAINTAINERS index f73bb41..494901b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4698,7 +4698,6 @@ F: include/uapi/linux/inotify.h INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS M: Dmitry Torokhov -M: Dmitry Torokhov L: linux-input@vger.kernel.org Q: http://patchwork.kernel.org/project/linux-input/list/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git -- cgit v0.10.2 From b0ddb319db3d7a1943445f0de0a45c07a7f3457a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 6 Jan 2015 14:39:10 +0100 Subject: ARM: shmobile: sh73a0 legacy: Set .control_parent for all irqpin instances The sh73a0 INTC can't mask interrupts properly most likely due to a hardware bug. Set the .control_parent flag to delegate masking to the parent interrupt controller, like was already done for irqpin1. Without this, accessing the three-axis digital accelerometer ADXL345 on kzm9g through /dev/input/event1 causes an interrupt storm, which requires a power-cycle to recover from. This was inspired by a patch for arch/arm/boot/dts/sh73a0.dtsi from Laurent Pinchart . Signed-off-by: Geert Uytterhoeven Fixes: 341eb5465f67437a ("ARM: shmobile: INTC External IRQ pin driver on sh73a0") Signed-off-by: Simon Horman diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index fa7cab8..b5d0cf5 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -579,6 +579,7 @@ static struct platform_device ipmmu_device = { static struct renesas_intc_irqpin_config irqpin0_platform_data = { .irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */ + .control_parent = true, }; static struct resource irqpin0_resources[] = { @@ -640,6 +641,7 @@ static struct platform_device irqpin1_device = { static struct renesas_intc_irqpin_config irqpin2_platform_data = { .irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */ + .control_parent = true, }; static struct resource irqpin2_resources[] = { @@ -670,6 +672,7 @@ static struct platform_device irqpin2_device = { static struct renesas_intc_irqpin_config irqpin3_platform_data = { .irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */ + .control_parent = true, }; static struct resource irqpin3_resources[] = { -- cgit v0.10.2 From 148e9a711e034e06310a8c36b64957934ebe30f2 Mon Sep 17 00:00:00 2001 From: Srihari Vijayaraghavan Date: Wed, 7 Jan 2015 16:25:53 -0800 Subject: Input: i8042 - reset keyboard to fix Elantech touchpad detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On some laptops, keyboard needs to be reset in order to successfully detect touchpad (e.g., some Gigabyte laptop models with Elantech touchpads). Without resettin keyboard touchpad pretends to be completely dead. Based on the original patch by Mateusz JoÅ„czyk this version has been expanded to include DMI based detection & application of the fix automatically on the affected models of laptops. This has been confirmed to fix problem by three users already on three different models of laptops. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=81331 Cc: stable@vger.kernel.org Signed-off-by: Srihari Vijayaraghavan Acked-by: Mateusz JoÅ„czyk Tested-by: Srihari Vijayaraghavan Tested by: Zakariya Dehlawi Tested-by: Guillaum Bouchard Signed-off-by: Dmitry Torokhov diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 10d51c2..8013b4d 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1243,6 +1243,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. i8042.notimeout [HW] Ignore timeout condition signalled by controller i8042.reset [HW] Reset the controller during init and cleanup i8042.unlock [HW] Unlock (ignore) the keylock + i8042.kbdreset [HW] Reset device connected to KBD port i810= [HW,DRM] diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index c66d1b5..97cdc58 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -745,6 +745,35 @@ static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { { } }; +/* + * Some laptops need keyboard reset before probing for the trackpad to get + * it detected, initialised & finally work. + */ +static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = { + { + /* Gigabyte P35 v2 - Elantech touchpad */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"), + }, + }, + { + /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "X3"), + }, + }, + { + /* Gigabyte P34 - Elantech touchpad */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "P34"), + }, + }, + { } +}; + #endif /* CONFIG_X86 */ #ifdef CONFIG_PNP @@ -1040,6 +1069,9 @@ static int __init i8042_platform_init(void) if (dmi_check_system(i8042_dmi_dritek_table)) i8042_dritek = true; + if (dmi_check_system(i8042_dmi_kbdreset_table)) + i8042_kbdreset = true; + /* * A20 was already enabled during early kernel init. But some buggy * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index f5a98af..804d2e0 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -67,6 +67,10 @@ static bool i8042_notimeout; module_param_named(notimeout, i8042_notimeout, bool, 0); MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042"); +static bool i8042_kbdreset; +module_param_named(kbdreset, i8042_kbdreset, bool, 0); +MODULE_PARM_DESC(kbdreset, "Reset device connected to KBD port"); + #ifdef CONFIG_X86 static bool i8042_dritek; module_param_named(dritek, i8042_dritek, bool, 0); @@ -790,6 +794,16 @@ static int __init i8042_check_aux(void) return -1; /* + * Reset keyboard (needed on some laptops to successfully detect + * touchpad, e.g., some Gigabyte laptop models with Elantech + * touchpads). + */ + if (i8042_kbdreset) { + pr_warn("Attempting to reset device connected to KBD port\n"); + i8042_kbd_write(NULL, (unsigned char) 0xff); + } + +/* * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and * used it for a PCI card or somethig else. */ -- cgit v0.10.2 From 6ee0ad2a7f27f7dc365576b748bc98684f02882d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 8 Jan 2015 13:27:15 +0900 Subject: drm/amdkfd: Drop interrupt SW ring buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The work queue couldn't reliably prevent the SW ring buffer from overflowing, so dmesg was spammed by kfd kfd: Interrupt ring overflow, dropping interrupt. messages when running e.g. the Atlantis Substance demo from https://wiki.unrealengine.com/Linux_Demos on Kaveri. Since the SW ring buffer doesn't actually do anything at this point, just remove it for now. When actual interrupt processing code is added to amdkfd, it should try to do things immediately and only defer to work queues when necessary. Signed-off-by: Michel Dänzer Reviewed-by: Christian König Signed-off-by: Oded Gabbay diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index be6246d..307a309 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -8,7 +8,6 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ kfd_process.o kfd_queue.o kfd_mqd_manager.o \ kfd_kernel_queue.o kfd_packet_manager.o \ - kfd_process_queue_manager.o kfd_device_queue_manager.o \ - kfd_interrupt.o + kfd_process_queue_manager.o kfd_device_queue_manager.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 43884eb..633532a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -192,13 +192,6 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto kfd_topology_add_device_error; } - if (kfd_interrupt_init(kfd)) { - dev_err(kfd_device, - "Error initializing interrupts for device (%x:%x)\n", - kfd->pdev->vendor, kfd->pdev->device); - goto kfd_interrupt_error; - } - if (!device_iommu_pasid_init(kfd)) { dev_err(kfd_device, "Error initializing iommuv2 for device (%x:%x)\n", @@ -237,8 +230,6 @@ dqm_start_error: device_queue_manager_error: amd_iommu_free_device(kfd->pdev); device_iommu_pasid_error: - kfd_interrupt_exit(kfd); -kfd_interrupt_error: kfd_topology_remove_device(kfd); kfd_topology_add_device_error: kfd2kgd->fini_sa_manager(kfd->kgd); @@ -254,7 +245,6 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd) if (kfd->init_complete) { device_queue_manager_uninit(kfd->dqm); amd_iommu_free_device(kfd->pdev); - kfd_interrupt_exit(kfd); kfd_topology_remove_device(kfd); } @@ -296,13 +286,5 @@ int kgd2kfd_resume(struct kfd_dev *kfd) /* This is called directly from KGD at ISR. */ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) { - if (kfd->init_complete) { - spin_lock(&kfd->interrupt_lock); - - if (kfd->interrupts_active - && enqueue_ih_ring_entry(kfd, ih_ring_entry)) - schedule_work(&kfd->interrupt_work); - - spin_unlock(&kfd->interrupt_lock); - } + /* Process interrupts / schedule work as necessary */ } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c deleted file mode 100644 index 5b99909..0000000 --- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2014 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * KFD Interrupts. - * - * AMD GPUs deliver interrupts by pushing an interrupt description onto the - * interrupt ring and then sending an interrupt. KGD receives the interrupt - * in ISR and sends us a pointer to each new entry on the interrupt ring. - * - * We generally can't process interrupt-signaled events from ISR, so we call - * out to each interrupt client module (currently only the scheduler) to ask if - * each interrupt is interesting. If they return true, then it requires further - * processing so we copy it to an internal interrupt ring and call each - * interrupt client again from a work-queue. - * - * There's no acknowledgment for the interrupts we use. The hardware simply - * queues a new interrupt each time without waiting. - * - * The fixed-size internal queue means that it's possible for us to lose - * interrupts because we have no back-pressure to the hardware. - */ - -#include -#include -#include "kfd_priv.h" - -#define KFD_INTERRUPT_RING_SIZE 256 - -static void interrupt_wq(struct work_struct *); - -int kfd_interrupt_init(struct kfd_dev *kfd) -{ - void *interrupt_ring = kmalloc_array(KFD_INTERRUPT_RING_SIZE, - kfd->device_info->ih_ring_entry_size, - GFP_KERNEL); - if (!interrupt_ring) - return -ENOMEM; - - kfd->interrupt_ring = interrupt_ring; - kfd->interrupt_ring_size = - KFD_INTERRUPT_RING_SIZE * kfd->device_info->ih_ring_entry_size; - atomic_set(&kfd->interrupt_ring_wptr, 0); - atomic_set(&kfd->interrupt_ring_rptr, 0); - - spin_lock_init(&kfd->interrupt_lock); - - INIT_WORK(&kfd->interrupt_work, interrupt_wq); - - kfd->interrupts_active = true; - - /* - * After this function returns, the interrupt will be enabled. This - * barrier ensures that the interrupt running on a different processor - * sees all the above writes. - */ - smp_wmb(); - - return 0; -} - -void kfd_interrupt_exit(struct kfd_dev *kfd) -{ - /* - * Stop the interrupt handler from writing to the ring and scheduling - * workqueue items. The spinlock ensures that any interrupt running - * after we have unlocked sees interrupts_active = false. - */ - unsigned long flags; - - spin_lock_irqsave(&kfd->interrupt_lock, flags); - kfd->interrupts_active = false; - spin_unlock_irqrestore(&kfd->interrupt_lock, flags); - - /* - * Flush_scheduled_work ensures that there are no outstanding - * work-queue items that will access interrupt_ring. New work items - * can't be created because we stopped interrupt handling above. - */ - flush_scheduled_work(); - - kfree(kfd->interrupt_ring); -} - -/* - * This assumes that it can't be called concurrently with itself - * but only with dequeue_ih_ring_entry. - */ -bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry) -{ - unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr); - unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr); - - if ((rptr - wptr) % kfd->interrupt_ring_size == - kfd->device_info->ih_ring_entry_size) { - /* This is very bad, the system is likely to hang. */ - dev_err_ratelimited(kfd_chardev(), - "Interrupt ring overflow, dropping interrupt.\n"); - return false; - } - - memcpy(kfd->interrupt_ring + wptr, ih_ring_entry, - kfd->device_info->ih_ring_entry_size); - - wptr = (wptr + kfd->device_info->ih_ring_entry_size) % - kfd->interrupt_ring_size; - smp_wmb(); /* Ensure memcpy'd data is visible before wptr update. */ - atomic_set(&kfd->interrupt_ring_wptr, wptr); - - return true; -} - -/* - * This assumes that it can't be called concurrently with itself - * but only with enqueue_ih_ring_entry. - */ -static bool dequeue_ih_ring_entry(struct kfd_dev *kfd, void *ih_ring_entry) -{ - /* - * Assume that wait queues have an implicit barrier, i.e. anything that - * happened in the ISR before it queued work is visible. - */ - - unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr); - unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr); - - if (rptr == wptr) - return false; - - memcpy(ih_ring_entry, kfd->interrupt_ring + rptr, - kfd->device_info->ih_ring_entry_size); - - rptr = (rptr + kfd->device_info->ih_ring_entry_size) % - kfd->interrupt_ring_size; - - /* - * Ensure the rptr write update is not visible until - * memcpy has finished reading. - */ - smp_mb(); - atomic_set(&kfd->interrupt_ring_rptr, rptr); - - return true; -} - -static void interrupt_wq(struct work_struct *work) -{ - struct kfd_dev *dev = container_of(work, struct kfd_dev, - interrupt_work); - - uint32_t ih_ring_entry[DIV_ROUND_UP( - dev->device_info->ih_ring_entry_size, - sizeof(uint32_t))]; - - while (dequeue_ih_ring_entry(dev, ih_ring_entry)) - ; -} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index a5edb29..b3dc13c 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -135,22 +135,10 @@ struct kfd_dev { struct kgd2kfd_shared_resources shared_resources; - void *interrupt_ring; - size_t interrupt_ring_size; - atomic_t interrupt_ring_rptr; - atomic_t interrupt_ring_wptr; - struct work_struct interrupt_work; - spinlock_t interrupt_lock; - /* QCM Device instance */ struct device_queue_manager *dqm; bool init_complete; - /* - * Interrupts of interest to KFD are copied - * from the HW ring into a SW ring. - */ - bool interrupts_active; }; /* KGD2KFD callbacks */ @@ -531,10 +519,7 @@ struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev); struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx); /* Interrupts */ -int kfd_interrupt_init(struct kfd_dev *dev); -void kfd_interrupt_exit(struct kfd_dev *dev); void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry); -bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry); /* Power Management */ void kgd2kfd_suspend(struct kfd_dev *kfd); -- cgit v0.10.2 From cbfc35b90f3b4853d1eb9fcb82e99531d6a1c629 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 5 Jan 2015 19:42:25 -0500 Subject: drm/radeon: fix VM flush on cayman/aruba (v3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to wait for the GPUVM flush to complete. There was some confusion as to how this mechanism was supposed to work. The operation is not atomic. For GPU initiated invalidations you need to read back a VM register to introduce enough latency for the update to complete. v2: drop gart changes v3: just read back rather than polling Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 360de9f..aea48c8 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -2516,6 +2516,16 @@ void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); radeon_ring_write(ring, 1 << vm_id); + /* wait for the invalidate to complete */ + radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); + radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */ + WAIT_REG_MEM_ENGINE(0))); /* me */ + radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); /* ref */ + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, 0x20); /* poll interval */ + /* sync PFP to ME, otherwise we might get invalid PFP reads */ radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); radeon_ring_write(ring, 0x0); diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c index 50f8861..4be2bb7 100644 --- a/drivers/gpu/drm/radeon/ni_dma.c +++ b/drivers/gpu/drm/radeon/ni_dma.c @@ -463,5 +463,11 @@ void cayman_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); radeon_ring_write(ring, 1 << vm_id); + + /* wait for invalidate to complete */ + radeon_ring_write(ring, DMA_SRBM_READ_PACKET); + radeon_ring_write(ring, (0xff << 20) | (VM_INVALIDATE_REQUEST >> 2)); + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, 0); /* value */ } diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 2e12e4d..ad71254 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h @@ -1133,6 +1133,23 @@ #define PACKET3_MEM_SEMAPHORE 0x39 #define PACKET3_MPEG_INDEX 0x3A #define PACKET3_WAIT_REG_MEM 0x3C +#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0) + /* 0 - always + * 1 - < + * 2 - <= + * 3 - == + * 4 - != + * 5 - >= + * 6 - > + */ +#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4) + /* 0 - reg + * 1 - mem + */ +#define WAIT_REG_MEM_ENGINE(x) ((x) << 8) + /* 0 - me + * 1 - pfp + */ #define PACKET3_MEM_WRITE 0x3D #define PACKET3_PFP_SYNC_ME 0x42 #define PACKET3_SURFACE_SYNC 0x43 @@ -1272,6 +1289,13 @@ (1 << 21) | \ (((n) & 0xFFFFF) << 0)) +#define DMA_SRBM_POLL_PACKET ((9 << 28) | \ + (1 << 27) | \ + (1 << 26)) + +#define DMA_SRBM_READ_PACKET ((9 << 28) | \ + (1 << 27)) + /* async DMA Packet types */ #define DMA_PACKET_WRITE 0x2 #define DMA_PACKET_COPY 0x3 -- cgit v0.10.2 From d474ea7e52cbaaae22711d857949ba6018562c29 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 5 Jan 2015 19:54:50 -0500 Subject: drm/radeon: fix VM flush on SI (v3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to wait for the GPUVM flush to complete. There was some confusion as to how this mechanism was supposed to work. The operation is not atomic. For GPU initiated invalidations you need to read back a VM register to introduce enough latency for the update to complete. v2: drop gart changes v3: just read back rather than polling Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 60df444..5d89b87 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -5057,6 +5057,16 @@ void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, 0); radeon_ring_write(ring, 1 << vm_id); + /* wait for the invalidate to complete */ + radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); + radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */ + WAIT_REG_MEM_ENGINE(0))); /* me */ + radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); /* ref */ + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, 0x20); /* poll interval */ + /* sync PFP to ME, otherwise we might get invalid PFP reads */ radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); radeon_ring_write(ring, 0x0); diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index f5cc777..aa7b872 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c @@ -206,6 +206,14 @@ void si_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); radeon_ring_write(ring, 1 << vm_id); + + /* wait for invalidate to complete */ + radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_POLL_REG_MEM, 0, 0, 0, 0)); + radeon_ring_write(ring, VM_INVALIDATE_REQUEST); + radeon_ring_write(ring, 0xff << 16); /* retry */ + radeon_ring_write(ring, 1 << vm_id); /* mask */ + radeon_ring_write(ring, 0); /* value */ + radeon_ring_write(ring, (0 << 28) | 0x20); /* func(always) | poll interval */ } /** diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 4069be89..8499924 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h @@ -1632,6 +1632,23 @@ #define PACKET3_MPEG_INDEX 0x3A #define PACKET3_COPY_DW 0x3B #define PACKET3_WAIT_REG_MEM 0x3C +#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0) + /* 0 - always + * 1 - < + * 2 - <= + * 3 - == + * 4 - != + * 5 - >= + * 6 - > + */ +#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4) + /* 0 - reg + * 1 - mem + */ +#define WAIT_REG_MEM_ENGINE(x) ((x) << 8) + /* 0 - me + * 1 - pfp + */ #define PACKET3_MEM_WRITE 0x3D #define PACKET3_COPY_DATA 0x40 #define PACKET3_CP_DMA 0x41 @@ -1835,6 +1852,7 @@ #define DMA_PACKET_TRAP 0x7 #define DMA_PACKET_SRBM_WRITE 0x9 #define DMA_PACKET_CONSTANT_FILL 0xd +#define DMA_PACKET_POLL_REG_MEM 0xe #define DMA_PACKET_NOP 0xf #define VCE_STATUS 0x20004 -- cgit v0.10.2 From 3a01fd367e09ebf05d75a000407364e7ebe2b678 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 5 Jan 2015 19:59:47 -0500 Subject: drm/radeon: fix VM flush on CIK (v3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to wait for the GPUVM flush to complete. There was some confusion as to how this mechanism was supposed to work. The operation is not atomic. For GPU initiated invalidations you need to read back a VM register to introduce enough latency for the update to complete. v2: drop gart changes v3: just read back rather than polling Reviewed-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 6dcde37..64fdae5 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -6033,6 +6033,17 @@ void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, 0); radeon_ring_write(ring, 1 << vm_id); + /* wait for the invalidate to complete */ + radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); + radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(0) | /* wait */ + WAIT_REG_MEM_FUNCTION(0) | /* always */ + WAIT_REG_MEM_ENGINE(0))); /* me */ + radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); /* ref */ + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, 0x20); /* poll interval */ + /* compute doesn't have PFP */ if (usepfp) { /* sync PFP to ME, otherwise we might get invalid PFP reads */ diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index dde5c7e..a0133c7 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -903,6 +903,9 @@ void cik_sdma_vm_pad_ib(struct radeon_ib *ib) void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, unsigned vm_id, uint64_t pd_addr) { + u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(0) | + SDMA_POLL_REG_MEM_EXTRA_FUNC(0)); /* always */ + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); if (vm_id < 8) { radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); @@ -943,5 +946,12 @@ void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); radeon_ring_write(ring, 1 << vm_id); + + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); + radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); /* reference */ + radeon_ring_write(ring, 0); /* mask */ + radeon_ring_write(ring, (0xfff << 16) | 10); /* retry count, poll interval */ } -- cgit v0.10.2 From 8dfe58b2063811b415626060316672741049d4d4 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 8 Jan 2015 16:46:16 +0200 Subject: drm/amdkfd: Fix sparse warning (different address space) Signed-off-by: Oded Gabbay diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 9c8961d..30c8fda 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -280,7 +280,7 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, q->queue); retval = mqd->load_mqd(mqd, q->mqd, q->pipe, - q->queue, q->properties.write_ptr); + q->queue, (uint32_t __user *) q->properties.write_ptr); if (retval != 0) { deallocate_hqd(dqm, q); mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); -- cgit v0.10.2 From e61f7d1c3c07a7e51036b0796749edb00deff845 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 8 Jan 2015 10:34:27 -0500 Subject: libata: Whitelist SSDs that are known to properly return zeroes after TRIM As defined, the DRAT (Deterministic Read After Trim) and RZAT (Return Zero After Trim) flags in the ATA Command Set are unreliable in the sense that they only define what happens if the device successfully executed the DSM TRIM command. TRIM is only advisory, however, and the device is free to silently ignore all or parts of the request. In practice this renders the DRAT and RZAT flags completely useless and because the results are unpredictable we decided to disable discard in MD for 3.18 to avoid the risk of data corruption. Hardware vendors in the real world obviously need better guarantees than what the standards bodies provide. Unfortuntely those guarantees are encoded in product requirements documents rather than somewhere we can key off of them programatically. So we are compelled to disabling discard_zeroes_data for all devices unless we explicitly have data to support whitelisting them. This patch whitelists SSDs from a few of the main vendors. None of the whitelists are based on written guarantees. They are purely based on empirical evidence collected from internal and external users that have tested or qualified these drives in RAID deployments. The whitelist is only meant as a starting point and is by no means comprehensive: - All intel SSD models except for 510 - Micron M5?0/M600 - Samsung SSDs - Seagate SSDs Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Signed-off-by: Tejun Heo diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5c84fb5..23c2ae0 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4233,10 +4233,33 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, /* devices that don't properly handle queued TRIM commands */ - { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, - { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, - { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, - { "Crucial_CT*M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Micron_M[56]*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Crucial_CT*SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, + + /* + * As defined, the DRAT (Deterministic Read After Trim) and RZAT + * (Return Zero After Trim) flags in the ATA Command Set are + * unreliable in the sense that they only define what happens if + * the device successfully executed the DSM TRIM command. TRIM + * is only advisory, however, and the device is free to silently + * ignore all or parts of the request. + * + * Whitelist drives that are known to reliably return zeroes + * after TRIM. + */ + + /* + * The intel 510 drive has buggy DRAT/RZAT. Explicitly exclude + * that model before whitelisting all other intel SSDs. + */ + { "INTEL*SSDSC2MH*", NULL, 0, }, + + { "INTEL*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "SSD*INTEL*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Samsung*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "SAMSUNG*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "ST[1248][0248]0[FH]*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, /* * Some WD SATA-I drives spin up and down erratically when the link diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e364e86..6abd17a 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2532,13 +2532,15 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) rbuf[15] = lowest_aligned; if (ata_id_has_trim(args->id)) { - rbuf[14] |= 0x80; /* TPE */ + rbuf[14] |= 0x80; /* LBPME */ - if (ata_id_has_zero_after_trim(args->id)) - rbuf[14] |= 0x40; /* TPRZ */ + if (ata_id_has_zero_after_trim(args->id) && + dev->horkage & ATA_HORKAGE_ZERO_AFTER_TRIM) { + ata_dev_info(dev, "Enabling discard_zeroes_data\n"); + rbuf[14] |= 0x40; /* LBPRZ */ + } } } - return 0; } diff --git a/include/linux/libata.h b/include/linux/libata.h index 2d18241..f2b440e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -422,6 +422,7 @@ enum { ATA_HORKAGE_NO_NCQ_TRIM = (1 << 19), /* don't use queued TRIM */ ATA_HORKAGE_NOLPM = (1 << 20), /* don't use LPM */ ATA_HORKAGE_WD_BROKEN_LPM = (1 << 21), /* some WDs have broken LPM */ + ATA_HORKAGE_ZERO_AFTER_TRIM = (1 << 22),/* guarantees zero after trim */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ -- cgit v0.10.2 From e93e54544adf3aa6908b821e896cb17a562cb683 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Fri, 9 Jan 2015 01:08:48 +0900 Subject: arm: dts: Use pmu_system_controller phandle for dp phy DP PHY now require pmu-system-controller to handle PMU register to control PHY's power isolation. Adding the same to dp-phy node. Signed-off-by: Vivek Gautam Reviewed-by: Jingoo Han Tested-by: Javier Martinez Canillas Signed-off-by: Kukjin Kim diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 0a229fc..d75c89d 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -736,7 +736,7 @@ dp_phy: video-phy@10040720 { compatible = "samsung,exynos5250-dp-video-phy"; - reg = <0x10040720 4>; + samsung,pmu-syscon = <&pmu_system_controller>; #phy-cells = <0>; }; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 517e50f..0ac5e08 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -503,8 +503,8 @@ }; dp_phy: video-phy@10040728 { - compatible = "samsung,exynos5250-dp-video-phy"; - reg = <0x10040728 4>; + compatible = "samsung,exynos5420-dp-video-phy"; + samsung,pmu-syscon = <&pmu_system_controller>; #phy-cells = <0>; }; -- cgit v0.10.2 From 83b0302d347a49f951e904184afe57ac3723476e Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Thu, 8 Jan 2015 18:54:25 +0530 Subject: regulator: core: fix race condition in regulator_put() The regulator framework maintains a list of consumer regulators for a regulator device and protects it from concurrent access using the regulator device's mutex lock. In the case of regulator_put() the consumer is removed and regulator device's parameters are updated without holding the regulator device's mutex. This would lead to a race condition between the regulator_put() and any function which traverses the consumer list or modifies regulator device's parameters. Fix this race condition by holding the regulator device's mutex in case of regulator_put. Signed-off-by: Ashay Jaiswal Signed-off-by: Mark Brown Cc: stable@vger.kernel.org diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e225711..9c48fb3 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1488,7 +1488,7 @@ struct regulator *regulator_get_optional(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(regulator_get_optional); -/* Locks held by regulator_put() */ +/* regulator_list_mutex lock held by regulator_put() */ static void _regulator_put(struct regulator *regulator) { struct regulator_dev *rdev; @@ -1503,12 +1503,14 @@ static void _regulator_put(struct regulator *regulator) /* remove any sysfs entries */ if (regulator->dev) sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); + mutex_lock(&rdev->mutex); kfree(regulator->supply_name); list_del(®ulator->list); kfree(regulator); rdev->open_count--; rdev->exclusive = 0; + mutex_unlock(&rdev->mutex); module_put(rdev->owner); } -- cgit v0.10.2 From ad26aa6c60974acf3228ed0ade97ba5793093dbe Mon Sep 17 00:00:00 2001 From: Jonghwa Lee Date: Thu, 8 Jan 2015 11:04:07 +0900 Subject: regulator: s2mps11: Fix wrong calculation of register offset This patch adds missing registers('BUCK7_SW' & 'LDO29_CTRL'). Since BUCK7 has 1 more register (BUCK7_SW) than others, register offset should be added one more for which has bigger address than BUCK7 registers. Fixes: 76b9840b24ae04(regulator: s2mps11: Add support S2MPS13 regulator device) Signed-off-by: Jonghwa Lee Signed-off-by: Chanwoo Choi Signed-off-by: Mark Brown Cc: diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index c1444c3..13ca20e 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -405,6 +405,40 @@ static struct regulator_ops s2mps14_reg_ops; .enable_mask = S2MPS14_ENABLE_MASK \ } +#define regulator_desc_s2mps13_buck7(num, min, step, min_sel) { \ + .name = "BUCK"#num, \ + .id = S2MPS13_BUCK##num, \ + .ops = &s2mps14_reg_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = min, \ + .uV_step = step, \ + .linear_min_sel = min_sel, \ + .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ + .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \ + .vsel_reg = S2MPS13_REG_B1OUT + (num) * 2 - 1, \ + .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ + .enable_reg = S2MPS13_REG_B1CTRL + (num - 1) * 2, \ + .enable_mask = S2MPS14_ENABLE_MASK \ +} + +#define regulator_desc_s2mps13_buck8_10(num, min, step, min_sel) { \ + .name = "BUCK"#num, \ + .id = S2MPS13_BUCK##num, \ + .ops = &s2mps14_reg_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = min, \ + .uV_step = step, \ + .linear_min_sel = min_sel, \ + .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ + .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \ + .vsel_reg = S2MPS13_REG_B1OUT + (num) * 2 - 1, \ + .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ + .enable_reg = S2MPS13_REG_B1CTRL + (num) * 2 - 1, \ + .enable_mask = S2MPS14_ENABLE_MASK \ +} + static const struct regulator_desc s2mps13_regulators[] = { regulator_desc_s2mps13_ldo(1, MIN_800_MV, STEP_12_5_MV, 0x00), regulator_desc_s2mps13_ldo(2, MIN_1400_MV, STEP_50_MV, 0x0C), @@ -452,10 +486,10 @@ static const struct regulator_desc s2mps13_regulators[] = { regulator_desc_s2mps13_buck(4, MIN_500_MV, STEP_6_25_MV, 0x10), regulator_desc_s2mps13_buck(5, MIN_500_MV, STEP_6_25_MV, 0x10), regulator_desc_s2mps13_buck(6, MIN_500_MV, STEP_6_25_MV, 0x10), - regulator_desc_s2mps13_buck(7, MIN_500_MV, STEP_6_25_MV, 0x10), - regulator_desc_s2mps13_buck(8, MIN_1000_MV, STEP_12_5_MV, 0x20), - regulator_desc_s2mps13_buck(9, MIN_1000_MV, STEP_12_5_MV, 0x20), - regulator_desc_s2mps13_buck(10, MIN_500_MV, STEP_6_25_MV, 0x10), + regulator_desc_s2mps13_buck7(7, MIN_500_MV, STEP_6_25_MV, 0x10), + regulator_desc_s2mps13_buck8_10(8, MIN_1000_MV, STEP_12_5_MV, 0x20), + regulator_desc_s2mps13_buck8_10(9, MIN_1000_MV, STEP_12_5_MV, 0x20), + regulator_desc_s2mps13_buck8_10(10, MIN_500_MV, STEP_6_25_MV, 0x10), }; static int s2mps14_regulator_enable(struct regulator_dev *rdev) diff --git a/include/linux/mfd/samsung/s2mps13.h b/include/linux/mfd/samsung/s2mps13.h index ce5dda8..b1fd675 100644 --- a/include/linux/mfd/samsung/s2mps13.h +++ b/include/linux/mfd/samsung/s2mps13.h @@ -59,6 +59,7 @@ enum s2mps13_reg { S2MPS13_REG_B6CTRL, S2MPS13_REG_B6OUT, S2MPS13_REG_B7CTRL, + S2MPS13_REG_B7SW, S2MPS13_REG_B7OUT, S2MPS13_REG_B8CTRL, S2MPS13_REG_B8OUT, @@ -102,6 +103,7 @@ enum s2mps13_reg { S2MPS13_REG_L26CTRL, S2MPS13_REG_L27CTRL, S2MPS13_REG_L28CTRL, + S2MPS13_REG_L29CTRL, S2MPS13_REG_L30CTRL, S2MPS13_REG_L31CTRL, S2MPS13_REG_L32CTRL, -- cgit v0.10.2 From 4369a69ec6ab86821352bd753c68af5880f87956 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 8 Jan 2015 10:46:33 -0500 Subject: drm/radeon: add a dpm quirk list Disable dpm on certain problematic boards rather than disabling dpm for the entire chip family since most boards work fine. https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1386534 https://bugzilla.kernel.org/show_bug.cgi?id=83731 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 32522cc..f7da8fe 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1287,8 +1287,39 @@ dpm_failed: return ret; } +struct radeon_dpm_quirk { + u32 chip_vendor; + u32 chip_device; + u32 subsys_vendor; + u32 subsys_device; +}; + +/* cards with dpm stability problems */ +static struct radeon_dpm_quirk radeon_dpm_quirk_list[] = { + /* TURKS - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1386534 */ + { PCI_VENDOR_ID_ATI, 0x6759, 0x1682, 0x3195 }, + /* TURKS - https://bugzilla.kernel.org/show_bug.cgi?id=83731 */ + { PCI_VENDOR_ID_ATI, 0x6840, 0x1179, 0xfb81 }, + { 0, 0, 0, 0 }, +}; + int radeon_pm_init(struct radeon_device *rdev) { + struct radeon_dpm_quirk *p = radeon_dpm_quirk_list; + bool disable_dpm = false; + + /* Apply dpm quirks */ + while (p && p->chip_device != 0) { + if (rdev->pdev->vendor == p->chip_vendor && + rdev->pdev->device == p->chip_device && + rdev->pdev->subsystem_vendor == p->subsys_vendor && + rdev->pdev->subsystem_device == p->subsys_device) { + disable_dpm = true; + break; + } + ++p; + } + /* enable dpm on rv6xx+ */ switch (rdev->family) { case CHIP_RV610: @@ -1344,6 +1375,8 @@ int radeon_pm_init(struct radeon_device *rdev) (!(rdev->flags & RADEON_IS_IGP)) && (!rdev->smc_fw)) rdev->pm.pm_method = PM_METHOD_PROFILE; + else if (disable_dpm && (radeon_dpm == -1)) + rdev->pm.pm_method = PM_METHOD_PROFILE; else if (radeon_dpm == 0) rdev->pm.pm_method = PM_METHOD_PROFILE; else -- cgit v0.10.2 From 810aa0918b2b032684c8cad13f73d6ba37ad11c0 Mon Sep 17 00:00:00 2001 From: Sam hung Date: Thu, 8 Jan 2015 13:22:43 -0800 Subject: Input: elantech - support new ICs types for version 4 This change allows the driver to recognize newer Elantech touchpads. Cc: stable@vger.kernel.org Signed-off-by: Yi ju Hong Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index f2b9780..77ecf6d 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1520,6 +1520,8 @@ static int elantech_set_properties(struct elantech_data *etd) case 7: case 8: case 9: + case 10: + case 13: etd->hw_version = 4; break; default: -- cgit v0.10.2 From 9333caeaeae4f831054e0e127a6ed3948b604d3e Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 8 Jan 2015 14:53:23 -0800 Subject: Input: I8042 - add Acer Aspire 7738 to the nomux list When KBC is in active multiplexing mode the touchpad on this laptop does not work. Reported-by: Bilal Koc Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 97cdc58..764857b 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -415,6 +415,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { }, }, { + /* Acer Aspire 7738 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"), + }, + }, + { /* Gericom Bellagio */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), -- cgit v0.10.2 From 1018b8b90b1f5cf239d731fb792ddc2b4a2b4ef5 Mon Sep 17 00:00:00 2001 From: Nilesh Javali Date: Wed, 7 Jan 2015 00:49:23 -0500 Subject: MAINTAINERS: Update maintainer list for qla4xxx Signed-off-by: Nilesh Javali Signed-off-by: Christoph Hellwig diff --git a/MAINTAINERS b/MAINTAINERS index ddb9ac8..f6dee56 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7737,8 +7737,7 @@ F: Documentation/scsi/LICENSE.qla2xxx F: drivers/scsi/qla2xxx/ QLOGIC QLA4XXX iSCSI DRIVER -M: Vikas Chaudhary -M: iscsi-driver@qlogic.com +M: QLogic-Storage-Upstream@qlogic.com L: linux-scsi@vger.kernel.org S: Supported F: Documentation/scsi/LICENSE.qla4xxx -- cgit v0.10.2 From 70a0f2c1898c6abf53670e55642b6e840b003892 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 5 Jan 2015 20:29:38 +0100 Subject: scsi: ->queue_rq can't sleep The blk-mq ->queue_rq method is always called from process context, but might have preemption disabled. This means we still always have to use GFP_ATOMIC for memory allocations, and thus need to revert part of commit 3c356bde1 ("scsi: stop passing a gfp_mask argument down the command setup path"). Signed-off-by: Christoph Hellwig Reported-by: Sasha Levin Reviewed-by: Bart Van Assche Tested-by: Alexei Starovoitov diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9ea95dd..6d5c0b8 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -591,7 +591,6 @@ static void scsi_free_sgtable(struct scsi_data_buffer *sdb, bool mq) static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, bool mq) { struct scatterlist *first_chunk = NULL; - gfp_t gfp_mask = mq ? GFP_NOIO : GFP_ATOMIC; int ret; BUG_ON(!nents); @@ -606,7 +605,7 @@ static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, bool mq) } ret = __sg_alloc_table(&sdb->table, nents, SCSI_MAX_SG_SEGMENTS, - first_chunk, gfp_mask, scsi_sg_alloc); + first_chunk, GFP_ATOMIC, scsi_sg_alloc); if (unlikely(ret)) scsi_free_sgtable(sdb, mq); return ret; -- cgit v0.10.2 From 24c498df1c70fa3b8b4df18f4424904bf014c709 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 24 Dec 2014 11:33:17 +0800 Subject: Revert "usb: chipidea: remove duplicate dev_set_drvdata for host_start" This reverts commit 14b4099c074f2ddf4d84b22d370170e61b527529 It moved platform_set_drvdata(pdev, ci) before hcd is created, and the hcd will assign itself as ci controller's drvdata during the hcd creation function (in usb_create_shared_hcd), so it overwrites the real ci's drvdata which we want to use. So, if the controller is at host mode, the system suspend API will get the wrong struct ci_hdrc pointer, and cause the oops. Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 5b9825a..a57dc88 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -669,7 +669,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) if (!ci) return -ENOMEM; - platform_set_drvdata(pdev, ci); ci->dev = dev; ci->platdata = dev_get_platdata(dev); ci->imx28_write_fix = !!(ci->platdata->flags & @@ -783,6 +782,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) } } + platform_set_drvdata(pdev, ci); ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED, ci->platdata->name, ci); if (ret) diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index c1694cf..48731d0 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -91,6 +91,7 @@ static int host_start(struct ci_hdrc *ci) if (!hcd) return -ENOMEM; + dev_set_drvdata(ci->dev, ci); hcd->rsrc_start = ci->hw_bank.phys; hcd->rsrc_len = ci->hw_bank.size; hcd->regs = ci->hw_bank.abs; -- cgit v0.10.2 From f161ead70fa6a62e432dff6e9dab8e3cfbeabea6 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 9 Jan 2015 17:18:28 +0200 Subject: xhci: Check if slot is already in default state before moving it there Solves xhci error cases with debug messages: xhci_hcd 0000:00:14.0: Setup ERROR: setup context command for slot 1. usb 1-6: hub failed to enable device, error -22 xhci will give a context state error if we try to set a slot in default state to the same default state with a special address device command. Turns out this happends in several cases: - retry reading the device rescriptor in hub_port_init() - usb_reset_device() is called for a slot in default state - in resume path, usb_port_resume() calls hub_port_init() The default state is usually reached from most states with a reset device command without any context state errors, but using the address device command with BSA bit set (block set address) only works from the enabled state and will otherwise cause context error. solve this by checking if we are already in the default state before issuing a address device BSA=1 command. Fixes: 48fc7dbd52c0 ("usb: xhci: change enumeration scheme to 'new scheme'") Cc: # v3.14+ Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 01fcbb5..c50d8d2 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3803,6 +3803,15 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, return -EINVAL; } + if (setup == SETUP_CONTEXT_ONLY) { + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); + if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == + SLOT_STATE_DEFAULT) { + xhci_dbg(xhci, "Slot already in default state\n"); + return 0; + } + } + command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); if (!command) return -ENOMEM; -- cgit v0.10.2 From 6d89252a998a695ecb0348fc2d717dc33d90cae9 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 4 Dec 2014 10:21:56 -0500 Subject: USB: EHCI: fix initialization bug in iso_stream_schedule() Commit c3ee9b76aa93 (EHCI: improved logic for isochronous scheduling) introduced the idea of using ehci->last_iso_frame as the origin (or base) for the circular calculations involved in modifying the isochronous schedule. However, the new code it added used ehci->last_iso_frame before the value was properly initialized. This patch rectifies the mistake by moving the initialization lines earlier in iso_stream_schedule(). This fixes Bugzilla #72891. Signed-off-by: Alan Stern Fixes: c3ee9b76aa93 Reported-by: Joe Bryant Tested-by: Joe Bryant Tested-by: Martin Long CC: Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index e113fd7..c399606 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1581,6 +1581,10 @@ iso_stream_schedule ( else next = (now + 2 + 7) & ~0x07; /* full frame cache */ + /* If needed, initialize last_iso_frame so that this URB will be seen */ + if (ehci->isoc_count == 0) + ehci->last_iso_frame = now >> 3; + /* * Use ehci->last_iso_frame as the base. There can't be any * TDs scheduled for earlier than that. @@ -1671,10 +1675,6 @@ iso_stream_schedule ( urb->start_frame = start & (mod - 1); if (!stream->highspeed) urb->start_frame >>= 3; - - /* Make sure scan_isoc() sees these */ - if (ehci->isoc_count == 0) - ehci->last_iso_frame = now >> 3; return status; fail: -- cgit v0.10.2 From c401e7b4a808d50ab53ef45cb8d0b99b238bf2c9 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 4 Dec 2014 10:22:57 -0500 Subject: USB: EHCI: adjust error return code The USB stack uses error code -ENOSPC to indicate that the periodic schedule is too full, with insufficient bandwidth to accommodate a new allocation. It uses -EFBIG to indicate that an isochronous transfer could not be linked into the schedule because it would exceed the number of isochronous packets the host controller driver can handle (generally because the new transfer would extend too far into the future). ehci-hcd uses the wrong error code at one point. This patch fixes it, along with a misleading comment and debugging message. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index c399606..f9a3327 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1604,11 +1604,11 @@ iso_stream_schedule ( */ now2 = (now - base) & (mod - 1); - /* Is the schedule already full? */ + /* Is the schedule about to wrap around? */ if (unlikely(!empty && start < period)) { - ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n", + ehci_dbg(ehci, "request %p would overflow (%u-%u < %u mod %u)\n", urb, stream->next_uframe, base, period, mod); - status = -ENOSPC; + status = -EFBIG; goto fail; } -- cgit v0.10.2 From 7f5c4d631aed243ca89c6673427954210b1628ec Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 5 Dec 2014 11:11:28 +0100 Subject: xhci: Add broken-streams quirk for Fresco Logic FL1000G xhci controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Streams do not work reliabe on Fresco Logic FL1000G xhci controllers, trying to use them results in errors like this: 21:37:33 kernel: xhci_hcd 0000:04:00.0: ERROR Transfer event for disabled endpoint or incorrect stream ring 21:37:33 kernel: xhci_hcd 0000:04:00.0: @00000000368b3570 9067b000 00000000 05000000 01078001 21:37:33 kernel: xhci_hcd 0000:04:00.0: ERROR Transfer event for disabled endpoint or incorrect stream ring 21:37:33 kernel: xhci_hcd 0000:04:00.0: @00000000368b3580 9067b400 00000000 05000000 01038001 As always I've ordered a pci-e addon card with a Fresco Logic controller for myself to see if I can come up with a better fix then the big hammer, in the mean time this will make uas devices work again (in usb-storage mode) for FL1000G users. Reported-by: Marcin ZajÄ…czkowski Cc: stable@vger.kernel.org # 3.15 Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 142b601..7f76c8a 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -82,6 +82,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) "must be suspended extra slowly", pdev->revision); } + if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) + xhci->quirks |= XHCI_BROKEN_STREAMS; /* Fresco Logic confirms: all revisions of this chip do not * support MSI, even though some of them claim to in their PCI * capabilities. -- cgit v0.10.2 From e5797a3d079f3e5049140055d850691b5cc7d10a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 5 Dec 2014 11:11:29 +0100 Subject: uas: Add US_FL_NO_ATA_1X for Seagate devices with usb-id 0bc2:a013 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is yet another Seagate device which needs the US_FL_NO_ATA_1X quirk Reported-by: Marcin ZajÄ…czkowski Cc: stable@vger.kernel.org # 3.16 Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 18a283d..2918376 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -68,6 +68,13 @@ UNUSUAL_DEV(0x0bc2, 0xa003, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_ATA_1X), +/* Reported-by: Marcin ZajÄ…czkowski */ +UNUSUAL_DEV(0x0bc2, 0xa013, 0x0000, 0x9999, + "Seagate", + "Backup Plus", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_ATA_1X), + /* https://bbs.archlinux.org/viewtopic.php?id=183190 */ UNUSUAL_DEV(0x0bc2, 0xab20, 0x0000, 0x9999, "Seagate", -- cgit v0.10.2 From c6fa3945c8b5baf62f2e849104ecd6f3a1e5e407 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 8 Dec 2014 09:50:47 +0100 Subject: uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS566 with usb-id 0bc2:a013 Like the JMicron JMS567 enclosures with the JMS566 choke on report-opcodes, so avoid it. Tested-and-reported-by: Takeo Nakayama Cc: stable@vger.kernel.org # 3.16 Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 2918376..2f0a3d3 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -111,6 +111,13 @@ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_ATA_1X), +/* Reported-by: Takeo Nakayama */ +UNUSUAL_DEV(0x357d, 0x7788, 0x0000, 0x9999, + "JMicron", + "JMS566", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_OPCODES), + /* Reported-by: Hans de Goede */ UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999, "Hitachi", -- cgit v0.10.2 From 36d1ffdb210ec2d0d6a69e9f6466ae8727d34119 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 11 Dec 2014 11:01:11 -0800 Subject: uas: disable UAS on Apricorn SATA dongles The Apricorn SATA dongle will occasionally return "USBSUSBSUSB" in response to SCSI commands when running in UAS mode. Therefore, disable UAS mode on this dongle. Signed-off-by: Darrick J. Wong Acked-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 2f0a3d3..b5e3255 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -40,6 +40,16 @@ * and don't forget to CC: the USB development list */ +/* + * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI + * commands in UAS mode. Observed with the 1.28 firmware; are there others? + */ +UNUSUAL_DEV(0x0984, 0x0301, 0x0128, 0x0128, + "Apricorn", + "", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_UAS), + /* https://bugzilla.kernel.org/show_bug.cgi?id=79511 */ UNUSUAL_DEV(0x0bc2, 0x2312, 0x0000, 0x9999, "Seagate", -- cgit v0.10.2 From f56e67f0a880a5b795cdb5f62614aafe264c5304 Mon Sep 17 00:00:00 2001 From: Vince Hsu Date: Wed, 24 Dec 2014 18:16:30 +0800 Subject: usb: host: ehci-tegra: request deferred probe when failing to get phy The commit 1290a958d48e ("usb: phy: propagate __of_usb_find_phy()'s error on failure") changed the condition to return -EPROBE_DEFER to host driver. Originally the Tegra host driver depended on the returned -EPROBE_DEFER to get the phy device later when booting. Now we have to do that explicitly. Signed-off-by: Vince Hsu Tested-by: Tomeu Vizoso Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 19a9af1..ff9af29 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -451,7 +451,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); if (IS_ERR(u_phy)) { - err = PTR_ERR(u_phy); + err = -EPROBE_DEFER; goto cleanup_clk_en; } hcd->usb_phy = u_phy; -- cgit v0.10.2 From f26d29e34e203296140334087fa3c81168626d76 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 6 Jan 2015 14:49:47 -0500 Subject: usb: gadget: udc: avoid dereference before NULL check in ep_queue Coverity: CID 1260069 Signed-off-by: John W. Linville Cc: Felipe Balbi Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index ff67cea..d4fe8d7 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -718,10 +718,11 @@ static int ep_queue(struct bdc_ep *ep, struct bdc_req *req) struct bdc *bdc; int ret = 0; - bdc = ep->bdc; if (!req || !ep || !ep->usb_ep.desc) return -EINVAL; + bdc = ep->bdc; + req->usb_req.actual = 0; req->usb_req.status = -EINPROGRESS; req->epnum = ep->ep_num; -- cgit v0.10.2 From 078fd7d6308a30121b80c297e9b38a2e53711942 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 8 Jan 2015 15:15:14 +0100 Subject: uas: Do not blacklist ASM1153 disk enclosures Our detection logic to avoid doing UAS on ASM1051 bridge chips causes problems with newer ASM1153 disk enclosures in 2 ways: 1) Some ASM1153 disk enclosures re-use the ASM1051 device-id of 5106, which we assume is always an ASM1051, so remove the quirk for 5106, and instead use the same detection logic as we already use for device-id 55aa, which is used for all of ASM1051, ASM1053 and ASM1153 devices . 2) Our detection logic to differentiate between ASM1051 and ASM1053 sees ASM1153 devices as ASM1051 because they have 32 streams like ASM1051 devs. Luckily the ASM1153 descriptors are not 100% identical, unlike the previous models the ASM1153 has bMaxPower == 0, so use that to differentiate it. Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index 8a6f371..9893d69 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h @@ -69,16 +69,39 @@ static int uas_use_uas_driver(struct usb_interface *intf, return 0; /* - * ASM1051 and older ASM1053 devices have the same usb-id, and UAS is - * broken on the ASM1051, use the number of streams to differentiate. - * New ASM1053-s also support 32 streams, but have a different prod-id. + * ASMedia has a number of usb3 to sata bridge chips, at the time of + * this writing the following versions exist: + * ASM1051 - no uas support version + * ASM1051 - with broken (*) uas support + * ASM1053 - with working uas support + * ASM1153 - with working uas support + * + * Devices with these chips re-use a number of device-ids over the + * entire line, so the device-id is useless to determine if we're + * dealing with an ASM1051 (which we want to avoid). + * + * The ASM1153 can be identified by config.MaxPower == 0, + * where as the ASM105x models have config.MaxPower == 36. + * + * Differentiating between the ASM1053 and ASM1051 is trickier, when + * connected over USB-3 we can look at the number of streams supported, + * ASM1051 supports 32 streams, where as early ASM1053 versions support + * 16 streams, newer ASM1053-s also support 32 streams, but have a + * different prod-id. + * + * (*) ASM1051 chips do work with UAS with some disks (with the + * US_FL_NO_REPORT_OPCODES quirk), but are broken with other disks */ if (le16_to_cpu(udev->descriptor.idVendor) == 0x174c && - le16_to_cpu(udev->descriptor.idProduct) == 0x55aa) { - if (udev->speed < USB_SPEED_SUPER) { + (le16_to_cpu(udev->descriptor.idProduct) == 0x5106 || + le16_to_cpu(udev->descriptor.idProduct) == 0x55aa)) { + if (udev->actconfig->desc.bMaxPower == 0) { + /* ASM1153, do nothing */ + } else if (udev->speed < USB_SPEED_SUPER) { /* No streams info, assume ASM1051 */ flags |= US_FL_IGNORE_UAS; } else if (usb_ss_max_streams(&eps[1]->ss_ep_comp) == 32) { + /* Possibly an ASM1051, disable uas */ flags |= US_FL_IGNORE_UAS; } } diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index b5e3255..542a7d1 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -106,14 +106,6 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_REPORT_OPCODES), -/* Most ASM1051 based devices have issues with uas, blacklist them all */ -/* Reported-by: Hans de Goede */ -UNUSUAL_DEV(0x174c, 0x5106, 0x0000, 0x9999, - "ASMedia", - "ASM1051", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_IGNORE_UAS), - /* Reported-by: Hans de Goede */ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, "VIA", -- cgit v0.10.2 From 3ca8c717429b90f621aed28af029da4c3da378bc Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 8 Jan 2015 15:15:15 +0100 Subject: uas: Add US_FL_NO_ATA_1X for 2 more Seagate disk enclosures Just like all previous UAS capable Seagate disk enclosures, these need the US_FL_NO_ATA_1X to not crash when udev probes them. Cc: stable@vger.kernel.org # 3.16 Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 542a7d1..6df4357 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -85,6 +85,13 @@ UNUSUAL_DEV(0x0bc2, 0xa013, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_ATA_1X), +/* Reported-by: Hans de Goede */ +UNUSUAL_DEV(0x0bc2, 0xa0a4, 0x0000, 0x9999, + "Seagate", + "Backup Plus Desk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_ATA_1X), + /* https://bbs.archlinux.org/viewtopic.php?id=183190 */ UNUSUAL_DEV(0x0bc2, 0xab20, 0x0000, 0x9999, "Seagate", @@ -99,6 +106,13 @@ UNUSUAL_DEV(0x0bc2, 0xab21, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_ATA_1X), +/* Reported-by: G. Richard Bellamy */ +UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999, + "Seagate", + "BUP Fast HDD", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_ATA_1X), + /* Reported-by: Claudio Bizzarri */ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999, "JMicron", -- cgit v0.10.2 From 56abcab833fafcfaeb2f5b25e0364c1dec45f53e Mon Sep 17 00:00:00 2001 From: Arseny Solokha Date: Sat, 6 Dec 2014 09:54:06 +0700 Subject: OHCI: add a quirk for ULi M5237 blocking on reset Commit 8dccddbc2368 ("OHCI: final fix for NVIDIA problems (I hope)") introduced into 3.1.9 broke boot on e.g. Freescale P2020DS development board. The code path that was previously specific to NVIDIA controllers had then become taken for all chips. However, the M5237 installed on the board wedges solid when accessing its base+OHCI_FMINTERVAL register, making it impossible to boot any kernel newer than 3.1.8 on this particular and apparently other similar machines. Don't readl() and writel() base+OHCI_FMINTERVAL on PCI ID 10b9:5237. The patch is suitable for the -next tree as well as all maintained kernels up to 3.2 inclusive. Signed-off-by: Arseny Solokha Acked-by: Alan Stern Cc: stable # 3.2 Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index dd483c1..ce63646 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -567,7 +567,8 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) { void __iomem *base; u32 control; - u32 fminterval; + u32 fminterval = 0; + bool no_fminterval = false; int cnt; if (!mmio_resource_enabled(pdev, 0)) @@ -577,6 +578,13 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) if (base == NULL) return; + /* + * ULi M5237 OHCI controller locks the whole system when accessing + * the OHCI_FMINTERVAL offset. + */ + if (pdev->vendor == PCI_VENDOR_ID_AL && pdev->device == 0x5237) + no_fminterval = true; + control = readl(base + OHCI_CONTROL); /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ @@ -615,7 +623,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) } /* software reset of the controller, preserving HcFmInterval */ - fminterval = readl(base + OHCI_FMINTERVAL); + if (!no_fminterval) + fminterval = readl(base + OHCI_FMINTERVAL); + writel(OHCI_HCR, base + OHCI_CMDSTATUS); /* reset requires max 10 us delay */ @@ -624,7 +634,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) break; udelay(1); } - writel(fminterval, base + OHCI_FMINTERVAL); + + if (!no_fminterval) + writel(fminterval, base + OHCI_FMINTERVAL); /* Now the controller is safely in SUSPEND and nothing can wake it up */ iounmap(base); -- cgit v0.10.2 From 9c9d82492b73991e8e13a6c0af06e44816c31438 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 6 Jan 2015 16:45:07 +0100 Subject: usb: phy: Fix deferred probing Commit 1290a958d48e ("usb: phy: propagate __of_usb_find_phy()'s error on failure") actually broke the deferred probing mechanism, since it now returns EPROBE_DEFER only when the try_module_get call fails, but not when the phy lookup does. All the other similar functions seem to return ENODEV when try_module_get fails, and the error code of either __usb_find_phy or __of_usb_find_phy otherwise. In order to have a consistent behaviour, and a meaningful EPROBE_DEFER, always return EPROBE_DEFER when __(of_)usb_find_phy fails to look up the requested phy, that will be propagated by the caller, and ENODEV if try_module_get fails. Signed-off-by: Maxime Ripard Tested-by: Olof Johansson Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index b4066a0..353c6864 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -34,7 +34,7 @@ static struct usb_phy *__usb_find_phy(struct list_head *list, return phy; } - return ERR_PTR(-ENODEV); + return ERR_PTR(-EPROBE_DEFER); } static struct usb_phy *__usb_find_phy_dev(struct device *dev, @@ -66,7 +66,7 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node) return phy; } - return ERR_PTR(-ENODEV); + return ERR_PTR(-EPROBE_DEFER); } static void devm_usb_phy_release(struct device *dev, void *res) @@ -192,7 +192,7 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, phy = __of_usb_find_phy(node); if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { if (!IS_ERR(phy)) - phy = ERR_PTR(-EPROBE_DEFER); + phy = ERR_PTR(-ENODEV); devres_free(ptr); goto err1; -- cgit v0.10.2 From 72a3c0e4e6624a77ee6eee0903f209185fe20647 Mon Sep 17 00:00:00 2001 From: Sergej Pupykin Date: Tue, 30 Dec 2014 16:16:50 +0300 Subject: tty: Add support for the WCH384 4S multi-IO card WCH384 4S board is a PCI-E card with 4 DB9 COM ports detected as Serial controller: Device 1c00:3470 (rev 10) (prog-if 05 [16850]) Signed-off-by: Sergej Pupykin Acked-by: Zany Yan Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 31feeb2..d1f8dc6 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1815,7 +1815,7 @@ pci_wch_ch353_setup(struct serial_private *priv, } static int -pci_wch_ch382_setup(struct serial_private *priv, +pci_wch_ch38x_setup(struct serial_private *priv, const struct pciserial_board *board, struct uart_8250_port *port, int idx) { @@ -1880,6 +1880,7 @@ pci_wch_ch382_setup(struct serial_private *priv, #define PCIE_VENDOR_ID_WCH 0x1c00 #define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 +#define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 @@ -2571,13 +2572,21 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = pci_wch_ch353_setup, }, - /* WCH CH382 2S1P card (16750 clone) */ + /* WCH CH382 2S1P card (16850 clone) */ { .vendor = PCIE_VENDOR_ID_WCH, .device = PCIE_DEVICE_ID_WCH_CH382_2S1P, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .setup = pci_wch_ch382_setup, + .setup = pci_wch_ch38x_setup, + }, + /* WCH CH384 4S card (16850 clone) */ + { + .vendor = PCIE_VENDOR_ID_WCH, + .device = PCIE_DEVICE_ID_WCH_CH384_4S, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = pci_wch_ch38x_setup, }, /* * ASIX devices with FIFO bug @@ -2876,6 +2885,7 @@ enum pci_board_num_t { pbn_fintek_4, pbn_fintek_8, pbn_fintek_12, + pbn_wch384_4, }; /* @@ -3675,6 +3685,14 @@ static struct pciserial_board pci_boards[] = { .base_baud = 115200, .first_offset = 0x40, }, + + [pbn_wch384_4] = { + .flags = FL_BASE0, + .num_ports = 4, + .base_baud = 115200, + .uart_offset = 8, + .first_offset = 0xC0, + }, }; static const struct pci_device_id blacklist[] = { @@ -3687,6 +3705,7 @@ static const struct pci_device_id blacklist[] = { { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ + { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */ }; /* @@ -5400,6 +5419,10 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_2_115200 }, + { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, pbn_wch384_4 }, + /* * Commtech, Inc. Fastcom adapters */ -- cgit v0.10.2 From 86f2c00f1d8e344965cf8df8572ed5f682956995 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Tue, 30 Dec 2014 10:39:25 -0500 Subject: tty: Prevent hw state corruption in exclusive mode reopen Exclusive mode ttys (TTY_EXCLUSIVE) do not allow further reopens; fail the condition before associating the file pointer and calling the driver open() method. Prevents DTR programming when the tty is already in exclusive mode. Reported-by: Shreyas Bethur Signed-off-by: Peter Hurley Acked-by: Shreyas Bethur Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 4f35b43..51f066a 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1464,6 +1464,9 @@ static int tty_reopen(struct tty_struct *tty) driver->subtype == PTY_TYPE_MASTER) return -EIO; + if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) + return -EBUSY; + tty->count++; WARN_ON(!tty->ldisc); @@ -2106,10 +2109,6 @@ retry_open: retval = -ENODEV; filp->f_flags = saved_flags; - if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && - !capable(CAP_SYS_ADMIN)) - retval = -EBUSY; - if (retval) { #ifdef TTY_DEBUG_HANGUP printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, -- cgit v0.10.2 From 2ce3c10c0c3e0d418c1a7a4c838319ba42c75388 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Tue, 30 Dec 2014 07:17:09 -0500 Subject: Revert "tty: Fix pty master poll() after slave closes v2" This reverts commit c4dc304677e8d566572c4738d95c48be150c6606. This fix is superseded by commit 52bce7f8d4fc633c9a9d0646eef58ba6ae9a3b73, 'pty, n_tty: Simplify input processing on final close'. The final close now waits for input processing to complete before destroying the pty, so poll() does not need to special case this condition. Cc: Francesco Ruggeri Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d2b4967..4ddfa60 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2399,17 +2399,12 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, poll_wait(file, &tty->read_wait, wait); poll_wait(file, &tty->write_wait, wait); - if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) - mask |= POLLHUP; if (input_available_p(tty, 1)) mask |= POLLIN | POLLRDNORM; - else if (mask & POLLHUP) { - tty_flush_to_ldisc(tty); - if (input_available_p(tty, 1)) - mask |= POLLIN | POLLRDNORM; - } if (tty->packet && tty->link->ctrl_status) mask |= POLLPRI | POLLIN | POLLRDNORM; + if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) + mask |= POLLHUP; if (tty_hung_up_p(file)) mask |= POLLHUP; if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) { -- cgit v0.10.2 From 31ec77aca72ee5920ed3ec3d047734dc0bc43342 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 2 Dec 2014 17:49:54 +0900 Subject: serial: samsung: Add the support for Exynos5433 SoC This patch adds new s3c24xx_serial_drv_data structure for Exynos5433 SoC because Exynos5433 has different fifo size from existing Exynos4 SoC. Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: linux-serial@vger.kernel.org Signed-off-by: Chanwoo Choi Acked-by: Inki Dae Acked-by: Geunsik Lim Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 19273e3..107e807 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1757,32 +1757,43 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { #endif #if defined(CONFIG_ARCH_EXYNOS) +#define EXYNOS_COMMON_SERIAL_DRV_DATA \ + .info = &(struct s3c24xx_uart_info) { \ + .name = "Samsung Exynos UART", \ + .type = PORT_S3C6400, \ + .has_divslot = 1, \ + .rx_fifomask = S5PV210_UFSTAT_RXMASK, \ + .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \ + .rx_fifofull = S5PV210_UFSTAT_RXFULL, \ + .tx_fifofull = S5PV210_UFSTAT_TXFULL, \ + .tx_fifomask = S5PV210_UFSTAT_TXMASK, \ + .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \ + .def_clk_sel = S3C2410_UCON_CLKSEL0, \ + .num_clks = 1, \ + .clksel_mask = 0, \ + .clksel_shift = 0, \ + }, \ + .def_cfg = &(struct s3c2410_uartcfg) { \ + .ucon = S5PV210_UCON_DEFAULT, \ + .ufcon = S5PV210_UFCON_DEFAULT, \ + .has_fracval = 1, \ + } \ + static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { - .info = &(struct s3c24xx_uart_info) { - .name = "Samsung Exynos4 UART", - .type = PORT_S3C6400, - .has_divslot = 1, - .rx_fifomask = S5PV210_UFSTAT_RXMASK, - .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, - .rx_fifofull = S5PV210_UFSTAT_RXFULL, - .tx_fifofull = S5PV210_UFSTAT_TXFULL, - .tx_fifomask = S5PV210_UFSTAT_TXMASK, - .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, - .def_clk_sel = S3C2410_UCON_CLKSEL0, - .num_clks = 1, - .clksel_mask = 0, - .clksel_shift = 0, - }, - .def_cfg = &(struct s3c2410_uartcfg) { - .ucon = S5PV210_UCON_DEFAULT, - .ufcon = S5PV210_UFCON_DEFAULT, - .has_fracval = 1, - }, + EXYNOS_COMMON_SERIAL_DRV_DATA, .fifosize = { 256, 64, 16, 16 }, }; + +static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = { + EXYNOS_COMMON_SERIAL_DRV_DATA, + .fifosize = { 64, 256, 16, 256 }, +}; + #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data) +#define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data) #else #define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL +#define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL #endif static struct platform_device_id s3c24xx_serial_driver_ids[] = { @@ -1804,6 +1815,9 @@ static struct platform_device_id s3c24xx_serial_driver_ids[] = { }, { .name = "exynos4210-uart", .driver_data = EXYNOS4210_SERIAL_DRV_DATA, + }, { + .name = "exynos5433-uart", + .driver_data = EXYNOS5433_SERIAL_DRV_DATA, }, { }, }; @@ -1823,6 +1837,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = { .data = (void *)S5PV210_SERIAL_DRV_DATA }, { .compatible = "samsung,exynos4210-uart", .data = (void *)EXYNOS4210_SERIAL_DRV_DATA }, + { .compatible = "samsung,exynos5433-uart", + .data = (void *)EXYNOS5433_SERIAL_DRV_DATA }, {}, }; MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); -- cgit v0.10.2 From 95bbbe9a6663635b6cdef20c01c0ea32ec6987e4 Mon Sep 17 00:00:00 2001 From: Gabriele Mazzotta Date: Thu, 8 Jan 2015 19:41:34 +0100 Subject: ahci: Use dev_info() to inform about the lack of Device Sleep support According to the Serial ATA AHCI specification, Device Sleep is an optional feature and as such no errors should be printed if it's missing. Keep informing users, but use dev_info() instead of dev_err(). Signed-off-by: Gabriele Mazzotta Signed-off-by: Tejun Heo diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 97683e4..61a9c07 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -2003,7 +2003,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) devslp = readl(port_mmio + PORT_DEVSLP); if (!(devslp & PORT_DEVSLP_DSP)) { - dev_err(ap->host->dev, "port does not support device sleep\n"); + dev_info(ap->host->dev, "port does not support device sleep\n"); return; } -- cgit v0.10.2 From b13a65ef190e488e2761d65bdd2e1fe8a3a125f5 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 25 Dec 2014 00:37:46 +0200 Subject: mei: clean reset bit before reset H_RST bit in H_CSR register may be found lit before reset is started, for example if preceding reset flow hasn't completed. In that case asserting H_RST will be ignored, therefore we need to clean H_RST bit to start a successful reset sequence. Cc: #3.10+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index ff27550..06ff0a2 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -234,6 +234,18 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable) struct mei_me_hw *hw = to_me_hw(dev); u32 hcsr = mei_hcsr_read(hw); + /* H_RST may be found lit before reset is started, + * for example if preceding reset flow hasn't completed. + * In that case asserting H_RST will be ignored, therefore + * we need to clean H_RST bit to start a successful reset sequence. + */ + if ((hcsr & H_RST) == H_RST) { + dev_warn(dev->dev, "H_RST is set = 0x%08X", hcsr); + hcsr &= ~H_RST; + mei_me_reg_write(hw, H_CSR, hcsr); + hcsr = mei_hcsr_read(hw); + } + hcsr |= H_RST | H_IG | H_IS; if (intr_enable) -- cgit v0.10.2 From 7e4a90cb2efecb3799bde9280efbf7f4af8f891b Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Fri, 19 Dec 2014 00:44:59 +0200 Subject: mei: add ABI documentation for fw_status exported through sysfs Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/ABI/testing/sysfs-class-mei b/Documentation/ABI/testing/sysfs-class-mei index 0ec8b81..80d9888 100644 --- a/Documentation/ABI/testing/sysfs-class-mei +++ b/Documentation/ABI/testing/sysfs-class-mei @@ -14,3 +14,18 @@ Description: The /sys/class/mei/meiN directory is created for each probed mei device +What: /sys/class/mei/meiN/fw_status +Date: Nov 2014 +KernelVersion: 3.19 +Contact: Tomas Winkler +Description: Display fw status registers content + + The ME FW writes its status information into fw status + registers for BIOS and OS to monitor fw health. + + The register contains running state, power management + state, error codes, and others. The way the registers + are decoded depends on PCH or SoC generation. + Also number of registers varies between 1 and 6 + depending on generation. + -- cgit v0.10.2 From 7b7c54914f73966976893747ee8e2ca58166a627 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Tue, 16 Dec 2014 10:09:20 +0100 Subject: mcb: mcb-pci: Only remap the 1st 0x200 bytes of BAR 0 Currently it is not possible to have a kernel with built-in MCB attached devices. This results out of the fact that mcb-pci requests PCI BAR 0, then parses the chameleon table and calls the driver's probe function before releasing BAR 0 again. When building the kernel with modules this is not a problem (and therefore it wasn't detected by my tests yet). A solution is to only remap the 1st 0x200 bytes of a Chameleon PCI device. 0x200 bytes is the maximum size of a Chameleon v2 Table. Also this patch stops disabling the PCI device on successful registration of MCB devices. Signed-off-by: Johannes Thumshirn Suggested-by: Bjorn Helgaas Reviewed-by: Bjorn Helgaas Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/mcb/mcb-internal.h b/drivers/mcb/mcb-internal.h index f956ef2..fb7493d 100644 --- a/drivers/mcb/mcb-internal.h +++ b/drivers/mcb/mcb-internal.h @@ -7,6 +7,7 @@ #define PCI_DEVICE_ID_MEN_CHAMELEON 0x4d45 #define CHAMELEON_FILENAME_LEN 12 #define CHAMELEONV2_MAGIC 0xabce +#define CHAM_HEADER_SIZE 0x200 enum chameleon_descriptor_type { CHAMELEON_DTYPE_GENERAL = 0x0, diff --git a/drivers/mcb/mcb-pci.c b/drivers/mcb/mcb-pci.c index b591819..5e1bd5d 100644 --- a/drivers/mcb/mcb-pci.c +++ b/drivers/mcb/mcb-pci.c @@ -17,6 +17,7 @@ struct priv { struct mcb_bus *bus; + phys_addr_t mapbase; void __iomem *base; }; @@ -31,8 +32,8 @@ static int mcb_pci_get_irq(struct mcb_device *mdev) static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct resource *res; struct priv *priv; - phys_addr_t mapbase; int ret; int num_cells; unsigned long flags; @@ -47,19 +48,21 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENODEV; } - mapbase = pci_resource_start(pdev, 0); - if (!mapbase) { + priv->mapbase = pci_resource_start(pdev, 0); + if (!priv->mapbase) { dev_err(&pdev->dev, "No PCI resource\n"); goto err_start; } - ret = pci_request_region(pdev, 0, KBUILD_MODNAME); - if (ret) { - dev_err(&pdev->dev, "Failed to request PCI BARs\n"); + res = request_mem_region(priv->mapbase, CHAM_HEADER_SIZE, + KBUILD_MODNAME); + if (IS_ERR(res)) { + dev_err(&pdev->dev, "Failed to request PCI memory\n"); + ret = PTR_ERR(res); goto err_start; } - priv->base = pci_iomap(pdev, 0, 0); + priv->base = ioremap(priv->mapbase, CHAM_HEADER_SIZE); if (!priv->base) { dev_err(&pdev->dev, "Cannot ioremap\n"); ret = -ENOMEM; @@ -84,7 +87,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) priv->bus->get_irq = mcb_pci_get_irq; - ret = chameleon_parse_cells(priv->bus, mapbase, priv->base); + ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base); if (ret < 0) goto err_drvdata; num_cells = ret; @@ -93,8 +96,10 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) mcb_bus_add_devices(priv->bus); + return 0; + err_drvdata: - pci_iounmap(pdev, priv->base); + iounmap(priv->base); err_ioremap: pci_release_region(pdev, 0); err_start: @@ -107,6 +112,10 @@ static void mcb_pci_remove(struct pci_dev *pdev) struct priv *priv = pci_get_drvdata(pdev); mcb_release_bus(priv->bus); + + iounmap(priv->base); + release_region(priv->mapbase, CHAM_HEADER_SIZE); + pci_disable_device(pdev); } static const struct pci_device_id mcb_pci_tbl[] = { -- cgit v0.10.2 From 72392ed0eb6fde96826cb9d66bd4f50a7ba61450 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 5 Dec 2014 23:41:33 +0100 Subject: kernfs: Fix kernfs_name_compare Returning a difference from a comparison functions is usually wrong (see acbbe6fbb240 "kcmp: fix standard comparison bug" for the long story). Here there is the additional twist that if the void pointers ns and kn->ns happen to differ by a multiple of 2^32, kernfs_name_compare returns 0, falsely reporting a match to the caller. Technically 'hash - kn->hash' is ok since the hashes are restricted to 31 bits, but it's better to avoid that subtlety. Signed-off-by: Rasmus Villemoes Acked-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 37989f0..2d881b3 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -201,10 +201,14 @@ static unsigned int kernfs_name_hash(const char *name, const void *ns) static int kernfs_name_compare(unsigned int hash, const char *name, const void *ns, const struct kernfs_node *kn) { - if (hash != kn->hash) - return hash - kn->hash; - if (ns != kn->ns) - return ns - kn->ns; + if (hash < kn->hash) + return -1; + if (hash > kn->hash) + return 1; + if (ns < kn->ns) + return -1; + if (ns > kn->ns) + return 1; return strcmp(name, kn->name); } -- cgit v0.10.2 From 42d6cfa0caec4b68a7f17147fbf13a36e94a8bf2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 6 Jan 2015 13:19:21 +0300 Subject: usb: gadget: gadgetfs: fix an oops in ep_write() We try to free an ERR_PTR on this error path. Fixes: b44be2462dbe ('usb: gadget: gadgetfs: Free memory allocated by memdup_user()') Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 0804861..db49ec4 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -441,6 +441,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) kbuf = memdup_user(buf, len); if (IS_ERR(kbuf)) { value = PTR_ERR(kbuf); + kbuf = NULL; goto free1; } -- cgit v0.10.2 From 5fb694f96e7c19e66b1c55124b98812e32e3efa5 Mon Sep 17 00:00:00 2001 From: Songjun Wu Date: Fri, 9 Jan 2015 17:11:24 +0100 Subject: usb: gadget: udc: atmel: fix possible oops when unloading module When unloading the module 'g_hid.ko', the urb request will be dequeued and the completion routine will be excuted. If there is no urb packet, the urb request will not be added to the endpoint queue and the completion routine pointer in urb request is NULL. Accessing to this NULL function pointer will cause the Oops issue reported below. Add the code to check if the urb request is in the endpoint queue or not. If the urb request is not in the endpoint queue, a negative error code will be returned. Here is the Oops log: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = dedf0000 [00000000] *pgd=3ede5831, *pte=00000000, *ppte=00000000 Internal error: Oops: 80000007 [#1] ARM Modules linked in: g_hid(-) usb_f_hid libcomposite CPU: 0 PID: 923 Comm: rmmod Not tainted 3.18.0+ #2 Hardware name: Atmel SAMA5 (Device Tree) task: df6b1100 ti: dedf6000 task.ti: dedf6000 PC is at 0x0 LR is at usb_gadget_giveback_request+0xc/0x10 pc : [<00000000>] lr : [] psr: 60000093 sp : dedf7eb0 ip : df572634 fp : 00000000 r10: 00000000 r9 : df52e210 r8 : 60000013 r7 : df6a9858 r6 : df52e210 r5 : df6a9858 r4 : df572600 r3 : 00000000 r2 : ffffff98 r1 : df572600 r0 : df6a9868 Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user Control: 10c53c7d Table: 3edf0059 DAC: 00000015 Process rmmod (pid: 923, stack limit = 0xdedf6230) Stack: (0xdedf7eb0 to 0xdedf8000) 7ea0: 00000000 c02adbbc df572580 deced608 7ec0: df572600 df6a9868 df572634 c02aed3c df577c00 c01b8608 00000000 df6be27c 7ee0: 00200200 00100100 bf0162f4 c000e544 dedf6000 00000000 00000000 bf010c00 7f00: bf0162cc bf00159c 00000000 df572980 df52e218 00000001 df5729b8 bf0031d0 [..] [] (usb_gadget_giveback_request) from [] (request_complete+0x64/0x88) [] (request_complete) from [] (usba_ep_dequeue+0x70/0x128) [] (usba_ep_dequeue) from [] (hidg_unbind+0x50/0x7c [usb_f_hid]) [] (hidg_unbind [usb_f_hid]) from [] (remove_config.isra.6+0x98/0x9c [libcomposite]) [] (remove_config.isra.6 [libcomposite]) from [] (__composite_unbind+0x34/0x98 [libcomposite]) [] (__composite_unbind [libcomposite]) from [] (usb_gadget_remove_driver+0x50/0x78) [] (usb_gadget_remove_driver) from [] (usb_gadget_unregister_driver+0x64/0x94) [] (usb_gadget_unregister_driver) from [] (hidg_cleanup+0x10/0x34 [g_hid]) [] (hidg_cleanup [g_hid]) from [] (SyS_delete_module+0x118/0x19c) [] (SyS_delete_module) from [] (ret_fast_syscall+0x0/0x30) Code: bad PC value Signed-off-by: Songjun Wu [nicolas.ferre@atmel.com: reworked the commit message] Signed-off-by: Nicolas Ferre Fixes: 914a3f3b3754 ("USB: add atmel_usba_udc driver") Cc: # 2.6.x-ish Signed-off-by: Felipe Balbi diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 93328ea..9f93bed 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -828,7 +828,7 @@ static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) { struct usba_ep *ep = to_usba_ep(_ep); struct usba_udc *udc = ep->udc; - struct usba_request *req = to_usba_req(_req); + struct usba_request *req; unsigned long flags; u32 status; @@ -837,6 +837,16 @@ static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) spin_lock_irqsave(&udc->lock, flags); + list_for_each_entry(req, &ep->queue, queue) { + if (&req->req == _req) + break; + } + + if (&req->req != _req) { + spin_unlock_irqrestore(&udc->lock, flags); + return -EINVAL; + } + if (req->using_dma) { /* * If this request is currently being transferred, -- cgit v0.10.2 From d269d4434c72ed0da3a9b1230c30da82c4918c63 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 5 Jan 2015 16:04:12 +0100 Subject: USB: console: fix uninitialised ldisc semaphore The USB console currently allocates a temporary fake tty which is used to pass terminal settings to the underlying serial driver. The tty struct is not fully initialised, something which can lead to a lockdep warning (or worse) if a serial driver tries to acquire a line-discipline reference: usbserial: USB Serial support registered for pl2303 pl2303 1-2.1:1.0: pl2303 converter detected usb 1-2.1: pl2303 converter now attached to ttyUSB0 INFO: trying to register non-static key. the code is fine but needs lockdep annotation. turning off the locking correctness validator. CPU: 0 PID: 68 Comm: udevd Tainted: G W 3.18.0-rc5 #10 [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [] (show_stack) from [] (dump_stack+0x24/0x28) [] (dump_stack) from [] (__lock_acquire+0x1e50/0x2004) [] (__lock_acquire) from [] (lock_acquire+0xe4/0x18c) [] (lock_acquire) from [] (ldsem_down_read_trylock+0x78/0x90) [] (ldsem_down_read_trylock) from [] (tty_ldisc_ref+0x24/0x58) [] (tty_ldisc_ref) from [] (usb_serial_handle_dcd_change+0x48/0xe8) [] (usb_serial_handle_dcd_change) from [] (pl2303_read_int_callback+0x210/0x220 [pl2303]) [] (pl2303_read_int_callback [pl2303]) from [] (__usb_hcd_giveback_urb+0x80/0x140) [] (__usb_hcd_giveback_urb) from [] (usb_giveback_urb_bh+0x98/0xd4) [] (usb_giveback_urb_bh) from [] (tasklet_hi_action+0x9c/0x108) [] (tasklet_hi_action) from [] (__do_softirq+0x148/0x42c) [] (__do_softirq) from [] (irq_exit+0xd8/0x114) [] (irq_exit) from [] (__handle_domain_irq+0x84/0xdc) [] (__handle_domain_irq) from [] (omap_intc_handle_irq+0xd8/0xe0) [] (omap_intc_handle_irq) from [] (__irq_svc+0x44/0x7c) Exception stack(0xdf4e7f08 to 0xdf4e7f50) 7f00: debc0b80 df4e7f5c 00000000 00000000 debc0b80 be8da96c 7f20: 00000000 00000128 c000fc84 df4e6000 00000000 df4e7f94 00000004 df4e7f50 7f40: c038ebc0 c038d74c 600f0013 ffffffff [] (__irq_svc) from [] (___sys_sendmsg.part.29+0x0/0x2e0) [] (___sys_sendmsg.part.29) from [] (SyS_sendmsg+0x18/0x1c) [] (SyS_sendmsg) from [] (ret_fast_syscall+0x0/0x48) console [ttyUSB0] enabled Fixes: 36697529b5bb ("tty: Replace ldisc locking with ldisc_sem") Cc: stable Signed-off-by: Johan Hovold diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 8d7fc48..e56f394 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -140,6 +140,7 @@ static int usb_console_setup(struct console *co, char *options) tty_port_tty_set(&port->port, tty); tty->driver = usb_serial_tty_driver; tty->index = co->index; + init_ldsem(&tty->ldisc_sem); if (tty_init_termios(tty)) { retval = -ENOMEM; goto free_tty; -- cgit v0.10.2 From 32a4bf2e81ec378e5925d4e069e0677a6c86a6ad Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 5 Jan 2015 16:04:13 +0100 Subject: USB: console: fix potential use after free Use tty kref to release the fake tty in usb_console_setup to avoid use after free if the underlying serial driver has acquired a reference. Note that using the tty destructor release_one_tty requires some more state to be initialised. Fixes: 4a90f09b20f4 ("tty: usb-serial krefs") Cc: stable Signed-off-by: Johan Hovold diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index e56f394..29fa1c3 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -46,6 +46,8 @@ static struct console usbcons; * ------------------------------------------------------------ */ +static const struct tty_operations usb_console_fake_tty_ops = { +}; /* * The parsing of the command line works exactly like the @@ -137,14 +139,17 @@ static int usb_console_setup(struct console *co, char *options) goto reset_open_count; } kref_init(&tty->kref); - tty_port_tty_set(&port->port, tty); tty->driver = usb_serial_tty_driver; tty->index = co->index; init_ldsem(&tty->ldisc_sem); + INIT_LIST_HEAD(&tty->tty_files); + kref_get(&tty->driver->kref); + tty->ops = &usb_console_fake_tty_ops; if (tty_init_termios(tty)) { retval = -ENOMEM; - goto free_tty; + goto put_tty; } + tty_port_tty_set(&port->port, tty); } /* only call the device specific open if this @@ -162,7 +167,7 @@ static int usb_console_setup(struct console *co, char *options) serial->type->set_termios(tty, port, &dummy); tty_port_tty_set(&port->port, NULL); - kfree(tty); + tty_kref_put(tty); } set_bit(ASYNCB_INITIALIZED, &port->port.flags); } @@ -178,8 +183,8 @@ static int usb_console_setup(struct console *co, char *options) fail: tty_port_tty_set(&port->port, NULL); - free_tty: - kfree(tty); + put_tty: + tty_kref_put(tty); reset_open_count: port->port.count = 0; usb_autopm_put_interface(serial->interface); -- cgit v0.10.2 From f27bd5bfeda5881ce283aa06408c8fa99fb950fa Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 21 Dec 2014 11:51:22 +0100 Subject: m68k: Wire up execveat Check success of execveat(3, '../execveat', 0)... [OK] Check success of execveat(5, 'execveat', 0)... [OK] Check success of execveat(6, 'execveat', 0)... [OK] Check success of execveat(-100, '/root/selftest-exec/exec/execveat', 0)... [OK] Check success of execveat(99, '/root/selftest-exec/exec/execveat', 0)... [OK] Check success of execveat(8, '', 4096)... [OK] Check success of execveat(17, '', 4096)... [OK] Check success of execveat(9, '', 4096)... [OK] Check success of execveat(14, '', 4096)... [OK] Check success of execveat(14, '', 4096)... [OK] Check success of execveat(15, '', 4096)... [OK] Check failure of execveat(8, '', 0) with ENOENT... [OK] Check failure of execveat(8, '(null)', 4096) with EFAULT... [OK] Check success of execveat(5, 'execveat.symlink', 0)... [OK] Check success of execveat(6, 'execveat.symlink', 0)... [OK] Check success of execveat(-100, '/root/selftest-exec/...xec/execveat.symlink', 0)... [OK] Check success of execveat(10, '', 4096)... [OK] Check success of execveat(10, '', 4352)... [OK] Check failure of execveat(5, 'execveat.symlink', 256) with ELOOP... [OK] Check failure of execveat(6, 'execveat.symlink', 256) with ELOOP... [OK] Check failure of execveat(-100, '/root/selftest-exec/exec/execveat.symlink', 256) with ELOOP... [OK] Check success of execveat(3, '../script', 0)... [OK] Check success of execveat(5, 'script', 0)... [OK] Check success of execveat(6, 'script', 0)... [OK] Check success of execveat(-100, '/root/selftest-exec/exec/script', 0)... [OK] Check success of execveat(13, '', 4096)... [OK] Check success of execveat(13, '', 4352)... [OK] Check failure of execveat(18, '', 4096) with ENOENT... [OK] Check failure of execveat(7, 'script', 0) with ENOENT... [OK] Check success of execveat(16, '', 4096)... [OK] Check success of execveat(16, '', 4096)... [OK] Check success of execveat(4, '../script', 0)... [OK] Check success of execveat(4, 'script', 0)... [OK] Check success of execveat(4, '../script', 0)... [OK] Check failure of execveat(4, 'script', 0) with ENOENT... [OK] Check failure of execveat(5, 'execveat', 65535) with EINVAL... [OK] Check failure of execveat(5, 'no-such-file', 0) with ENOENT... [OK] Check failure of execveat(6, 'no-such-file', 0) with ENOENT... [OK] Check failure of execveat(-100, 'no-such-file', 0) with ENOENT... [OK] Check failure of execveat(5, '', 4096) with EACCES... [OK] Check failure of execveat(5, 'Makefile', 0) with EACCES... [OK] Check failure of execveat(11, '', 4096) with EACCES... [OK] Check failure of execveat(12, '', 4096) with EACCES... [OK] Check failure of execveat(99, '', 4096) with EBADF... [OK] Check failure of execveat(99, 'execveat', 0) with EBADF... [OK] Check failure of execveat(8, 'execveat', 0) with ENOTDIR... [OK] Invoke copy of 'execveat' via filename of length 4093: Check success of execveat(19, '', 4096)... [OK] Check success of execveat(5, 'xxxxxxxxxxxxxxxxxxxx...yyyyyyyyyyyyyyyyyyyy', 0)... [OK] Invoke copy of 'script' via filename of length 4093: Check success of execveat(20, '', 4096)... [OK] Check success of execveat(5, 'xxxxxxxxxxxxxxxxxxxx...yyyyyyyyyyyyyyyyyyyy', 0)... [OK] Signed-off-by: Geert Uytterhoeven diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index 75e75d7..244e0db 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -4,7 +4,7 @@ #include -#define NR_syscalls 355 +#define NR_syscalls 356 #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 2c1bec9..61fb6cb 100644 --- a/arch/m68k/include/uapi/asm/unistd.h +++ b/arch/m68k/include/uapi/asm/unistd.h @@ -360,5 +360,6 @@ #define __NR_getrandom 352 #define __NR_memfd_create 353 #define __NR_bpf 354 +#define __NR_execveat 355 #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 2ca219e..a0ec430 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S @@ -375,4 +375,5 @@ ENTRY(sys_call_table) .long sys_getrandom .long sys_memfd_create .long sys_bpf + .long sys_execveat /* 355 */ -- cgit v0.10.2 From d40f74f7273b484ca4382e5ae08b59dee85e01e4 Mon Sep 17 00:00:00 2001 From: Hyungwon Hwang Date: Fri, 9 Jan 2015 10:24:41 +0900 Subject: drm/exynos: remove the redundant machine checking code This code is unnecessary, because same logic is already included. Refer this mail thread[1] for detail. [1] http://lists.freedesktop.org/archives/dri-devel/2015-January/075132.html Signed-off-by: Hyungwon Hwang Signed-off-by: Inki Dae diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 121470a..1bcbe07 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -645,18 +645,6 @@ static int exynos_drm_init(void) if (!is_exynos) return -ENODEV; - /* - * Register device object only in case of Exynos SoC. - * - * Below codes resolves temporarily infinite loop issue incurred - * by Exynos drm driver when using multi-platform kernel. - * So these codes will be replaced with more generic way later. - */ - if (!of_machine_is_compatible("samsung,exynos3") && - !of_machine_is_compatible("samsung,exynos4") && - !of_machine_is_compatible("samsung,exynos5")) - return -ENODEV; - exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, NULL, 0); if (IS_ERR(exynos_drm_pdev)) -- cgit v0.10.2 From 029b18361921a0a07b17bd89a2cf20df3d115de8 Mon Sep 17 00:00:00 2001 From: Gabriel Laskar Date: Sun, 11 Jan 2015 16:18:06 -0800 Subject: Input: uinput - fix ioctl nr overflow for UI_GET_SYSNAME/VERSION Request number for ioctls are encoded as 8bit numbers, but unfortunately UI_GET_SYSNAME and UI_GET_VERSION specifu values larger than that, so they get truncated to 44 (0x2c) and 45 (0x2d). This change makes requested values match their effective values (the ABI stays intact). Signed-off-by: Gabriel Laskar Signed-off-by: Dmitry Torokhov diff --git a/include/uapi/linux/uinput.h b/include/uapi/linux/uinput.h index baeab83..013c9d8 100644 --- a/include/uapi/linux/uinput.h +++ b/include/uapi/linux/uinput.h @@ -82,7 +82,7 @@ struct uinput_ff_erase { * The complete sysfs path is then /sys/devices/virtual/input/--NAME-- * Usually, it is in the form "inputN" */ -#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 300, len) +#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 44, len) /** * UI_GET_VERSION - Return version of uinput protocol @@ -91,7 +91,7 @@ struct uinput_ff_erase { * the integer pointed to by the ioctl argument. The protocol version * is hard-coded in the kernel and is independent of the uinput device. */ -#define UI_GET_VERSION _IOR(UINPUT_IOCTL_BASE, 301, unsigned int) +#define UI_GET_VERSION _IOR(UINPUT_IOCTL_BASE, 45, unsigned int) /* * To write a force-feedback-capable driver, the upload_effect -- cgit v0.10.2 From bfe5fda8e7ced129716f5741cf7ed2592a338824 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 6 Jan 2015 21:12:08 +1100 Subject: powernv: Fix OPAL tracepoint code Patch c49f63530bb6 ("powernv: Add OPAL tracepoints") has a spurious store to the stack: ld r12,opal_tracepoint_refcount@toc(r2); \ std r12,32(r1); \ The store was originally used to save the current tracepoint status so the entry and the exit tracepoints were always balanced. In the end I just created a separate path when tracepoints are enabled. The offset on the stack used for this store is not valid for ABIv2 and it causes strange issues. I noticed it because OPAL console input was broken. Fixes: c49f63530bb6 ("powernv: Add OPAL tracepoints") Cc: # v3.17+ Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 54eca8b..0509bca 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -40,7 +40,6 @@ BEGIN_FTR_SECTION; \ b 1f; \ END_FTR_SECTION(0, 1); \ ld r12,opal_tracepoint_refcount@toc(r2); \ - std r12,32(r1); \ cmpdi r12,0; \ bne- LABEL; \ 1: -- cgit v0.10.2 From 0712dc7e73e59d79bcead5d5520acf4e9e917e87 Mon Sep 17 00:00:00 2001 From: Ian Munsie Date: Wed, 7 Jan 2015 16:33:04 +1100 Subject: cxl: Fix issues when unmapping contexts An issue was introduced with "cxl: Unmap MMIO regions when detaching a context" (b123429e6a9e8d03aacf888d23262835f0081448) where closing a context normally could also unmap the problem state area of other contexts currently using the AFU. It was also discovered that after a context's MMIO space had been unmapped it would read 0s when accessing it, whereas the expected behaviour was for the access to fail altogether. In order to address these issues, this patch does two things: - Forced mmap unmapping is only done when we are forcefully detaching all contexts, and not in the normal detach path. Since the normal context close path is tied to the file release any mmaps must have already been released so we don't need to worry in that case. - The mmap path now uses a vm_operations_struct with a fault handler. The fault handler ensures that the context is in started state, otherwise it fails the access attempt with a SIGBUS. Fixes: b123429e6a9e ("cxl: Unmap MMIO regions when detaching a context") Signed-off-by: Ian Munsie Signed-off-by: Michael Ellerman diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 51fd6b5..d1b55fe 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c @@ -100,6 +100,46 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master, return 0; } +static int cxl_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct cxl_context *ctx = vma->vm_file->private_data; + unsigned long address = (unsigned long)vmf->virtual_address; + u64 area, offset; + + offset = vmf->pgoff << PAGE_SHIFT; + + pr_devel("%s: pe: %i address: 0x%lx offset: 0x%llx\n", + __func__, ctx->pe, address, offset); + + if (ctx->afu->current_mode == CXL_MODE_DEDICATED) { + area = ctx->afu->psn_phys; + if (offset > ctx->afu->adapter->ps_size) + return VM_FAULT_SIGBUS; + } else { + area = ctx->psn_phys; + if (offset > ctx->psn_size) + return VM_FAULT_SIGBUS; + } + + mutex_lock(&ctx->status_mutex); + + if (ctx->status != STARTED) { + mutex_unlock(&ctx->status_mutex); + pr_devel("%s: Context not started, failing problem state access\n", __func__); + return VM_FAULT_SIGBUS; + } + + vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); + + mutex_unlock(&ctx->status_mutex); + + return VM_FAULT_NOPAGE; +} + +static const struct vm_operations_struct cxl_mmap_vmops = { + .fault = cxl_mmap_fault, +}; + /* * Map a per-context mmio space into the given vma. */ @@ -108,26 +148,25 @@ int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma) u64 len = vma->vm_end - vma->vm_start; len = min(len, ctx->psn_size); - if (ctx->afu->current_mode == CXL_MODE_DEDICATED) { - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - return vm_iomap_memory(vma, ctx->afu->psn_phys, ctx->afu->adapter->ps_size); - } + if (ctx->afu->current_mode != CXL_MODE_DEDICATED) { + /* make sure there is a valid per process space for this AFU */ + if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) { + pr_devel("AFU doesn't support mmio space\n"); + return -EINVAL; + } - /* make sure there is a valid per process space for this AFU */ - if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) { - pr_devel("AFU doesn't support mmio space\n"); - return -EINVAL; + /* Can't mmap until the AFU is enabled */ + if (!ctx->afu->enabled) + return -EBUSY; } - /* Can't mmap until the AFU is enabled */ - if (!ctx->afu->enabled) - return -EBUSY; - pr_devel("%s: mmio physical: %llx pe: %i master:%i\n", __func__, ctx->psn_phys, ctx->pe , ctx->master); + vma->vm_flags |= VM_IO | VM_PFNMAP; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - return vm_iomap_memory(vma, ctx->psn_phys, len); + vma->vm_ops = &cxl_mmap_vmops; + return 0; } /* @@ -150,12 +189,6 @@ static void __detach_context(struct cxl_context *ctx) afu_release_irqs(ctx); flush_work(&ctx->fault_work); /* Only needed for dedicated process */ wake_up_all(&ctx->wq); - - /* Release Problem State Area mapping */ - mutex_lock(&ctx->mapping_lock); - if (ctx->mapping) - unmap_mapping_range(ctx->mapping, 0, 0, 1); - mutex_unlock(&ctx->mapping_lock); } /* @@ -184,6 +217,17 @@ void cxl_context_detach_all(struct cxl_afu *afu) * created and torn down after the IDR removed */ __detach_context(ctx); + + /* + * We are force detaching - remove any active PSA mappings so + * userspace cannot interfere with the card if it comes back. + * Easiest way to exercise this is to unbind and rebind the + * driver via sysfs while it is in use. + */ + mutex_lock(&ctx->mapping_lock); + if (ctx->mapping) + unmap_mapping_range(ctx->mapping, 0, 0, 1); + mutex_unlock(&ctx->mapping_lock); } mutex_unlock(&afu->contexts_lock); } diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index e9f2f10..b15d811 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c @@ -140,18 +140,20 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, pr_devel("%s: pe: %i\n", __func__, ctx->pe); - mutex_lock(&ctx->status_mutex); - if (ctx->status != OPENED) { - rc = -EIO; - goto out; - } - + /* Do this outside the status_mutex to avoid a circular dependency with + * the locking in cxl_mmap_fault() */ if (copy_from_user(&work, uwork, sizeof(struct cxl_ioctl_start_work))) { rc = -EFAULT; goto out; } + mutex_lock(&ctx->status_mutex); + if (ctx->status != OPENED) { + rc = -EIO; + goto out; + } + /* * if any of the reserved fields are set or any of the unused * flags are set it's invalid -- cgit v0.10.2 From a87e810f61b49f19bd29ea564b7cd1e92e43d989 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 Jan 2015 15:30:08 +1100 Subject: powerpc: Work around gcc bug in current_thread_info() In commit a3e5b356b3ab "powerpc: Don't use local named register variable in current_thread_info" Anton changed the way we did current_thread_info() to accommodate LLVM, and it was not meant to have any effect elsewhere. Unfortunately it has exposed a gcc bug, where r1 gets copied into another register and then gcc uses that register to restore the toc after a function call, even when that register is volatile and has been clobbered by the function call. We could revert Anton's patch, but it's not clear the original code is safe either, we may just have been lucky. The cleanest solution is to just use the existing CURRENT_THREAD_INFO() asm macro, and call it using inline asm. Segher points out we don't need volatile on the asm, if the result of the shift is unused it's fine for the compiler to elide it. Fixes: a3e5b356b3ab ("powerpc: Don't use local named register variable in current_thread_info") Reported-by: Alexander Graf Signed-off-by: Michael Ellerman diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index ebc4f16..0be6c68 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -23,9 +23,9 @@ #define THREAD_SIZE (1 << THREAD_SHIFT) #ifdef CONFIG_PPC64 -#define CURRENT_THREAD_INFO(dest, sp) clrrdi dest, sp, THREAD_SHIFT +#define CURRENT_THREAD_INFO(dest, sp) stringify_in_c(clrrdi dest, sp, THREAD_SHIFT) #else -#define CURRENT_THREAD_INFO(dest, sp) rlwinm dest, sp, 0, 0, 31-THREAD_SHIFT +#define CURRENT_THREAD_INFO(dest, sp) stringify_in_c(rlwinm dest, sp, 0, 0, 31-THREAD_SHIFT) #endif #ifndef __ASSEMBLY__ @@ -71,12 +71,13 @@ struct thread_info { #define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) /* how to get the thread information struct from C */ -register unsigned long __current_r1 asm("r1"); static inline struct thread_info *current_thread_info(void) { - /* gcc4, at least, is smart enough to turn this into a single - * rlwinm for ppc32 and clrrdi for ppc64 */ - return (struct thread_info *)(__current_r1 & ~(THREAD_SIZE-1)); + unsigned long val; + + asm (CURRENT_THREAD_INFO(%0,1) : "=r" (val)); + + return (struct thread_info *)val; } #endif /* __ASSEMBLY__ */ -- cgit v0.10.2 From 2809d90f4e697da0674e1eafa40da322d6f967b5 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 9 Jan 2015 01:11:10 +0900 Subject: ARM: exynos_defconfig: Enable options for display panel support Many Exynos devices have a display panel. Most of them just have a simple panel while others have more complex configurations that requires an embedded DisplayPort (eDP) to LVDS bridges. This patch enables the following features to be built in the kernel image to support both setups: - Direct Rendering Manager (DRM) - DRM bridge registration and lookup framework - Parade ps8622/ps8625 eDP/LVDS bridge - NXP ptn3460 eDP/LVDS bridge - Exynos Fully Interactive Mobile Display controller (FIMD) - Panel registration and lookup framework - Simple panels - Backlight & LCD device support Signed-off-by: Javier Martinez Canillas Tested-by: Kevin Hilman Signed-off-by: Kukjin Kim diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 5ef14de..2c6fe86 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -109,11 +109,26 @@ CONFIG_REGULATOR_S2MPA01=y CONFIG_REGULATOR_S2MPS11=y CONFIG_REGULATOR_S5M8767=y CONFIG_REGULATOR_TPS65090=y +CONFIG_DRM=y +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_PTN3460=y +CONFIG_DRM_PS8622=y +CONFIG_DRM_EXYNOS=y +CONFIG_DRM_EXYNOS_FIMD=y +CONFIG_DRM_EXYNOS_DP=y +CONFIG_DRM_PANEL=y +CONFIG_DRM_PANEL_SIMPLE=y CONFIG_FB=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_SIMPLE=y CONFIG_EXYNOS_VIDEO=y CONFIG_EXYNOS_MIPI_DSI=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_PLATFORM=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y +CONFIG_BACKLIGHT_PWM=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FONTS=y CONFIG_FONT_7x14=y -- cgit v0.10.2 From 26d13bf77b8e59adf4953577ba48e1903545bf7f Mon Sep 17 00:00:00 2001 From: Andreas Faerber Date: Sat, 22 Nov 2014 23:31:30 +0900 Subject: ARM: exynos_defconfig: Enable LM90 driver multi_v7_defconfig has it as Y already, so build it in here, too, for consistency, and therefore build in HWMON as well. Signed-off-by: Andreas Faerber Reviewed-by: Javier Martinez Canillas Signed-off-by: Kukjin Kim diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 2c6fe86..3d0c5d6 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -84,7 +84,8 @@ CONFIG_DEBUG_GPIO=y CONFIG_POWER_SUPPLY=y CONFIG_BATTERY_SBS=y CONFIG_CHARGER_TPS65090=y -# CONFIG_HWMON is not set +CONFIG_HWMON=y +CONFIG_SENSORS_LM90=y CONFIG_THERMAL=y CONFIG_EXYNOS_THERMAL=y CONFIG_EXYNOS_THERMAL_CORE=y -- cgit v0.10.2 From 63a3451641ec2e129dfe80044e3c96bc9f0bb690 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 19 Dec 2014 19:33:25 +0200 Subject: drm/i915: gen9: fix RPS interrupt routing to CPU vs. GT GEN8+ HW has the option to route PM interrupts to either the CPU or to GT. For GEN8 this was already set correctly to routing to CPU, but not for GEN9, so fix this. Note that when disabling RPS interrupts this was set already correctly, though in that case it didn't matter much except for the possibility of spurious interrupts. Signed-off-by: Imre Deak Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 964b28e..78e308b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4369,7 +4369,7 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) if (INTEL_INFO(dev_priv->dev)->gen <= 7 && !IS_HASWELL(dev_priv->dev)) mask |= GEN6_PM_RP_UP_EI_EXPIRED; - if (IS_GEN8(dev_priv->dev)) + if (INTEL_INFO(dev_priv)->gen >= 8) mask |= GEN8_PMINTR_REDIRECT_TO_NON_DISP; return ~mask; -- cgit v0.10.2 From 59d02a1f45beb1b6f4ef83a47feb264cb3577725 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 19 Dec 2014 19:33:26 +0200 Subject: drm/i915: fix HW lockup due to missing RPS IRQ workaround on GEN6 In commit dbea3cea69508e9d548ed4a6be13de35492e5d15 Author: Imre Deak Date: Mon Dec 15 18:59:28 2014 +0200 drm/i915: sanitize RPS resetting during GPU reset we disable RPS interrupts during GPU resetting, but don't apply the necessary GEN6 HW workaround. This leads to a HW lockup during a subsequent "looping batchbuffer" workload. This is triggered by the testcase that submits exactly this kind of workload after a simulated GPU reset. I'm not sure how likely the bug would have triggered otherwise, since we would have applied the workaround anyway shortly after the GPU reset, when enabling GT powersaving from the deferred work. This may also fix unrelated issues, since during driver loading / suspending we also disable RPS interrupts and so we also had a short window during the rest of the loading / resuming where a similar workload could run without the workaround applied. v2: - separate the fix to route RPS interrupts to the CPU on GEN9 too to a separate patch (Daniel) Bisected-by: Ander Conselvan de Oliveira Testcase: igt/gem_reset_stats/ban-ctx-render Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87429 Signed-off-by: Imre Deak Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d0d3dfb..ba86dc3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -292,6 +292,21 @@ void gen6_enable_rps_interrupts(struct drm_device *dev) spin_unlock_irq(&dev_priv->irq_lock); } +u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask) +{ + /* + * IVB and SNB hard hangs on looping batchbuffer + * if GEN6_PM_UP_EI_EXPIRED is masked. + */ + if (INTEL_INFO(dev_priv)->gen <= 7 && !IS_HASWELL(dev_priv)) + mask &= ~GEN6_PM_RP_UP_EI_EXPIRED; + + if (INTEL_INFO(dev_priv)->gen >= 8) + mask &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP; + + return mask; +} + void gen6_disable_rps_interrupts(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -304,8 +319,7 @@ void gen6_disable_rps_interrupts(struct drm_device *dev) spin_lock_irq(&dev_priv->irq_lock); - I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? - ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); + I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0)); __gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 25fdbb1..3b40a17 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -794,6 +794,7 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void gen6_reset_rps_interrupts(struct drm_device *dev); void gen6_enable_rps_interrupts(struct drm_device *dev); void gen6_disable_rps_interrupts(struct drm_device *dev); +u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask); void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv); static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 78e308b..3801ff5 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4363,16 +4363,7 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) mask |= dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED); mask &= dev_priv->pm_rps_events; - /* IVB and SNB hard hangs on looping batchbuffer - * if GEN6_PM_UP_EI_EXPIRED is masked. - */ - if (INTEL_INFO(dev_priv->dev)->gen <= 7 && !IS_HASWELL(dev_priv->dev)) - mask |= GEN6_PM_RP_UP_EI_EXPIRED; - - if (INTEL_INFO(dev_priv)->gen >= 8) - mask |= GEN8_PMINTR_REDIRECT_TO_NON_DISP; - - return ~mask; + return gen6_sanitize_rps_pm_mask(dev_priv, ~mask); } /* gen6_set_rps is called to update the frequency request, but should also be -- cgit v0.10.2 From f24eeb191229b040deb3e813913e06a4316c6d3f Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 19 Dec 2014 19:33:27 +0200 Subject: drm/i915: vlv: sanitize RPS interrupt mask during GPU idling We apply the RPS interrupt workaround on VLV everywhere except when writing the mask directly during idling the GPU. For consistency do this also there. While at it also extend the code comment about affected platforms. I couldn't reproduce the issue on VLV fixed by this workaround, by removing the workaround from everywhere, while it's 100% reproducible on SNB using igt/gem_reset_stats/ban-ctx-render. So also add a note that it hasn't been verified if the workaround really applies to VLV/CHV. Suggested-by: Daniel Vetter Signed-off-by: Imre Deak Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ba86dc3..b051a23 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -295,8 +295,10 @@ void gen6_enable_rps_interrupts(struct drm_device *dev) u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask) { /* - * IVB and SNB hard hangs on looping batchbuffer + * SNB,IVB can while VLV,CHV may hard hang on looping batchbuffer * if GEN6_PM_UP_EI_EXPIRED is masked. + * + * TODO: verify if this can be reproduced on VLV,CHV. */ if (INTEL_INFO(dev_priv)->gen <= 7 && !IS_HASWELL(dev_priv)) mask &= ~GEN6_PM_RP_UP_EI_EXPIRED; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3801ff5..bf814a6 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4432,7 +4432,8 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) return; /* Mask turbo interrupt so that they will not come in between */ - I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); + I915_WRITE(GEN6_PMINTRMSK, + gen6_sanitize_rps_pm_mask(dev_priv, ~0)); vlv_force_gfx_clock(dev_priv, true); -- cgit v0.10.2 From 48bf5b2d00bfeb681f6500c626189c7cd2c964d2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 27 Dec 2014 09:48:28 +0000 Subject: drm/i915: Ban Haswell from using RCS flips Like Ivybridge, we have reports that we get random hangs when flipping with multiple pipes. Extend commit 2a92d5bca1999b69c78f3c3e97b5484985b094b9 Author: Chris Wilson Date: Tue Jul 8 10:40:29 2014 +0100 drm/i915: Disable RCS flips on Ivybridge to also apply to Haswell. Reported-and-tested-by: Scott Tsai Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87759 Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org # 2a92d5bca199 drm/i915: Disable RCS flips on Ivybridge Cc: stable@vger.kernel.org Signed-off-by: Jani Nikula diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e2af138..e7a16f1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9815,7 +9815,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (obj->tiling_mode != work->old_fb_obj->tiling_mode) /* vlv: DISPLAY_FLIP fails to change tiling */ ring = NULL; - } else if (IS_IVYBRIDGE(dev)) { + } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { ring = &dev_priv->ring[BCS]; } else if (INTEL_INFO(dev)->gen >= 7) { ring = obj->ring; -- cgit v0.10.2 From 226e5ae9e5f9108beb0bde4ac69f68fe6210fed9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 2 Jan 2015 09:47:10 +0000 Subject: drm/i915: Fix mutex->owner inspection race under DEBUG_MUTEXES If CONFIG_DEBUG_MUTEXES is set, the mutex->owner field is only cleared if the mutex debugging is enabled which introduces a race in our mutex_is_locked_by() - i.e. we may inspect the old owner value before it is acquired by the new task. This is the root cause of this error: diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c index 5cf6731..3ef3736 100644 --- a/kernel/locking/mutex-debug.c +++ b/kernel/locking/mutex-debug.c @@ -80,13 +80,13 @@ void debug_mutex_unlock(struct mutex *lock) DEBUG_LOCKS_WARN_ON(lock->owner != current); DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); - mutex_clear_owner(lock); } /* * __mutex_slowpath_needs_to_unlock() is explicitly 0 for debug * mutexes so that we can do it here after we've verified state. */ + mutex_clear_owner(lock); atomic_set(&lock->count, 1); } Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87955 Signed-off-by: Chris Wilson Cc: stable@vger.kernel.org Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c11603b..76354d3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5155,7 +5155,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) if (!mutex_is_locked(mutex)) return false; -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES) +#if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES) return mutex->owner == task; #else /* Since UP may be pre-empted, we cannot assume that we own the lock */ -- cgit v0.10.2 From aa8e22128b40590b291cd13512098bf258a7e6c5 Mon Sep 17 00:00:00 2001 From: Jeremiah Mahler Date: Sun, 11 Jan 2015 05:42:06 -0800 Subject: usb: serial: silence all non-critical read errors If a USB serial device is unplugged while there is an active program using the device it may spam the logs with -EPROTO (71) messages as it attempts to retry. Most serial usb drivers (metro-usb, pl2303, mos7840, ...) only output these messages for debugging. The generic driver treats these as errors. Change the default output for the generic serial driver from error to debug to silence these non-critical errors. Signed-off-by: Jeremiah Mahler Signed-off-by: Johan Hovold diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 1bd1922..2d7207b 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -373,7 +373,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb) __func__, urb->status); return; default: - dev_err(&port->dev, "%s - nonzero urb status: %d\n", + dev_dbg(&port->dev, "%s - nonzero urb status: %d\n", __func__, urb->status); goto resubmit; } -- cgit v0.10.2 From 04f9c6e6d17584340fb6c8a9469a0e6df28876d2 Mon Sep 17 00:00:00 2001 From: Jeremiah Mahler Date: Sun, 11 Jan 2015 05:42:07 -0800 Subject: usb: serial: handle -ENODEV quietly in generic_submit_read_urb If a USB serial device (e.g. /dev/ttyUSB0) with an active program is unplugged, an -ENODEV (19) error will be produced after it gives up trying to resubmit a read. usb_serial_generic_submit_read_urb - usb_submit_urb failed: -19 Add -ENODEV as one of the permanent errors along with -EPERM that usb_serial_generic_submit_read_urb() handles quietly without an error. Signed-off-by: Jeremiah Mahler Signed-off-by: Johan Hovold diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 2d7207b..ccf1df7 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -286,7 +286,7 @@ static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, res = usb_submit_urb(port->read_urbs[index], mem_flags); if (res) { - if (res != -EPERM) { + if (res != -EPERM && res != -ENODEV) { dev_err(&port->dev, "%s - usb_submit_urb failed: %d\n", __func__, res); -- cgit v0.10.2 From 0068b2e1b7f925a818fdc0a5d10ef0ad40f746e7 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Thu, 11 Dec 2014 10:54:33 +0800 Subject: ARM: at91/dt: sama5d4: fix the timer reg length The second property of reg is the length, so correct it for timer. Signed-off-by: Bo Shen Signed-off-by: Nicolas Ferre diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 1b0f30c..b94995d 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -1008,7 +1008,7 @@ pit: timer@fc068630 { compatible = "atmel,at91sam9260-pit"; - reg = <0xfc068630 0xf>; + reg = <0xfc068630 0x10>; interrupts = <3 IRQ_TYPE_LEVEL_HIGH 5>; clocks = <&h32ck>; }; -- cgit v0.10.2 From 04582fd03fb263598e3b126c76cc42195aa0fd05 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Fri, 9 Jan 2015 17:18:16 +0800 Subject: ARM: at91: sama5d3: dt: correct the sound route The MICBIAS is a supply, should route to MIC while not IN1L. Signed-off-by: Bo Shen Signed-off-by: Nicolas Ferre diff --git a/arch/arm/boot/dts/sama5d3xmb.dtsi b/arch/arm/boot/dts/sama5d3xmb.dtsi index 49c10d3..77e0365 100644 --- a/arch/arm/boot/dts/sama5d3xmb.dtsi +++ b/arch/arm/boot/dts/sama5d3xmb.dtsi @@ -176,7 +176,7 @@ "Headphone Jack", "HPOUTR", "IN2L", "Line In Jack", "IN2R", "Line In Jack", - "MICBIAS", "IN1L", + "Mic", "MICBIAS", "IN1L", "Mic"; atmel,ssc-controller = <&ssc0>; -- cgit v0.10.2 From 55eb9c343fdd3611ae3de6ab8a8512f303d3f581 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 5 Dec 2014 14:31:39 +0100 Subject: ARM: at91/dt: sam9263: Add missing clocks to lcdc node atmel_lcdfb needs also uses hclk clock, but AT91SAM9263 doesn't have that specific clock, so use lcd_clk twice. The same was done in arch/arm/mach-at91/at91sam9263.c Signed-off-by: Alexander Stein Acked-by: Alexandre Belloni Signed-off-by: Nicolas Ferre diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 1467750..e8c6c60 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -953,6 +953,8 @@ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fb>; + clocks = <&lcd_clk>, <&lcd_clk>; + clock-names = "lcdc_clk", "hclk"; status = "disabled"; }; -- cgit v0.10.2 From b8659752c37ec157ee254cff443b1c9d523aea22 Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Thu, 11 Dec 2014 15:31:09 +0800 Subject: ARM: at91: board-dt-sama5: add phy_fixup to override NAND_Tree Appearance: On some SAMA5D4EK boards, after power up, the Eth1 doesn't work. Reason: The PIOE2 pin is connected to the NAND_Tree# of KSZ8081, But it outputs LOW during the reset period, which cause the NAND_Tree# enabled. Add phy_fixup() to disable NAND_Tree by overriding the Operation Mode Strap Override register(i.e. Register 16h) to clear the NAND_Tree bit. Signed-off-by: Wenyou Yang Signed-off-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c index 8fb9ef5..97f7367 100644 --- a/arch/arm/mach-at91/board-dt-sama5.c +++ b/arch/arm/mach-at91/board-dt-sama5.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -26,8 +27,25 @@ #include "generic.h" +static int ksz8081_phy_fixup(struct phy_device *phy) +{ + int value; + + value = phy_read(phy, 0x16); + value &= ~0x20; + phy_write(phy, 0x16, value); + + return 0; +} + static void __init sama5_dt_device_init(void) { + if (of_machine_is_compatible("atmel,sama5d4ek") && + IS_ENABLED(CONFIG_PHYLIB)) { + phy_register_fixup_for_id("fc028000.etherne:00", + ksz8081_phy_fixup); + } + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -- cgit v0.10.2 From cd25b85ba6ee1f67c6458ba9d990170728d60828 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 12 Jan 2015 16:46:21 +0000 Subject: arm64: compat: wire up compat_sys_execveat With 841ee230253f ("ARM: wire up execveat syscall"), arch/arm/ has grown support for the execveat system call. This patch wires up the compat variant for arm64. Signed-off-by: Will Deacon diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index b780c6c..23e9432 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h @@ -44,7 +44,7 @@ #define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2) #define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5) -#define __NR_compat_syscalls 387 +#define __NR_compat_syscalls 388 #endif #define __ARCH_WANT_SYS_CLONE diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index 8893ceb..2722442 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h @@ -795,3 +795,5 @@ __SYSCALL(__NR_getrandom, sys_getrandom) __SYSCALL(__NR_memfd_create, sys_memfd_create) #define __NR_bpf 386 __SYSCALL(__NR_bpf, sys_bpf) +#define __NR_execveat 387 +__SYSCALL(__NR_execveat, compat_sys_execveat) -- cgit v0.10.2 From a18f36453e0788d2d285a62b85c7c668ec119a64 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Fri, 9 Jan 2015 18:30:13 +0100 Subject: ARM: 8266/1: Remove early stack deallocation from restore_user_regs Currently restore_user_regs deallocates the SVC stack early in its execution and relies on no exception being taken between the deallocation and the registers being restored. The introduction of a default FIQ handler that also uses the SVC stack breaks this assumption and can result in corrupted register state. This patch works around the problem by removing the early stack deallocation and using r2 as a temporary instead. I have not found a way to do this without introducing an extra mov instruction to the macro. Signed-off-by: Daniel Thompson Signed-off-by: Russell King diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 4176df7..1a0045a 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -253,21 +253,22 @@ .endm .macro restore_user_regs, fast = 0, offset = 0 - ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr - ldr lr, [sp, #\offset + S_PC]! @ get pc + mov r2, sp + ldr r1, [r2, #\offset + S_PSR] @ get calling cpsr + ldr lr, [r2, #\offset + S_PC]! @ get pc msr spsr_cxsf, r1 @ save in spsr_svc #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K) @ We must avoid clrex due to Cortex-A15 erratum #830321 - strex r1, r2, [sp] @ clear the exclusive monitor + strex r1, r2, [r2] @ clear the exclusive monitor #endif .if \fast - ldmdb sp, {r1 - lr}^ @ get calling r1 - lr + ldmdb r2, {r1 - lr}^ @ get calling r1 - lr .else - ldmdb sp, {r0 - lr}^ @ get calling r0 - lr + ldmdb r2, {r0 - lr}^ @ get calling r0 - lr .endif mov r0, r0 @ ARMv5T and earlier require a nop @ after ldm {}^ - add sp, sp, #S_FRAME_SIZE - S_PC + add sp, sp, #\offset + S_FRAME_SIZE movs pc, lr @ return & move spsr_svc into cpsr .endm -- cgit v0.10.2 From 2d9ed7406fd24987b75f78fea8290202d8108f34 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Mon, 5 Jan 2015 15:58:54 +0100 Subject: ARM: 8255/1: perf: Prevent wraparound during overflow If the overflow threshold for a counter is set above or near the 0xffffffff boundary then the kernel may lose track of the overflow causing only events that occur *after* the overflow to be recorded. Specifically the problem occurs when the value of the performance counter overtakes its original programmed value due to wrap around. Typical solutions to this problem are either to avoid programming in values likely to be overtaken or to treat the overflow bit as the 33rd bit of the counter. Its somewhat fiddly to refactor the code to correctly handle the 33rd bit during irqsave sections (context switches for example) so instead we take the simpler approach of avoiding values likely to be overtaken. We set the limit to half of max_period because this matches the limit imposed in __hw_perf_event_init(). This causes a doubling of the interrupt rate for large threshold values, however even with a very fast counter ticking at 4GHz the interrupt rate would only be ~1Hz. Signed-off-by: Daniel Thompson Acked-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index f7c65ad..557e128 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -116,8 +116,14 @@ int armpmu_event_set_period(struct perf_event *event) ret = 1; } - if (left > (s64)armpmu->max_period) - left = armpmu->max_period; + /* + * Limit the maximum period to prevent the counter value + * from overtaking the one we are about to program. In + * effect we are reducing max_period to account for + * interrupt latency (and we are being very conservative). + */ + if (left > (armpmu->max_period >> 1)) + left = armpmu->max_period >> 1; local64_set(&hwc->prev_count, (u64)-left); -- cgit v0.10.2 From ee853addd9fedb116bd34a18f11dd5959fcf0428 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 12 Jan 2015 17:33:59 +0100 Subject: thermal: rcar: Spelling/grammar: s/drier use .../driver uses ...s/ Signed-off-by: Geert Uytterhoeven Signed-off-by: Eduardo Valentin diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 70bb02c..2580a48 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -391,7 +391,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) /* * platform has IRQ support. - * Then, drier use common register + * Then, driver uses common registers */ ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0, -- cgit v0.10.2 From ad1a62227f2e3d5eb4eb0b61a2d9005369bbef45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 9 Jan 2015 11:07:49 +0100 Subject: drm/radeon: don't print error on -ERESTARTSYS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Signed-off-by: Alex Deucher diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index a46f737..d0b4f7d 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -576,7 +576,7 @@ error_unreserve: error_free: drm_free_large(vm_bos); - if (r) + if (r && r != -ERESTARTSYS) DRM_ERROR("Couldn't update BO_VA (%d)\n", r); } -- cgit v0.10.2 From 5615f890bc6babdc2998dec62f3552326d06eb7b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 12 Jan 2015 17:15:12 -0500 Subject: drm/radeon: add si dpm quirk list This adds a quirks list to fix stability problems with certain SI boards. bug: https://bugs.freedesktop.org/show_bug.cgi?id=76490 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 32e354b..eff8a64 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -2908,6 +2908,22 @@ static int si_init_smc_spll_table(struct radeon_device *rdev) return ret; } +struct si_dpm_quirk { + u32 chip_vendor; + u32 chip_device; + u32 subsys_vendor; + u32 subsys_device; + u32 max_sclk; + u32 max_mclk; +}; + +/* cards with dpm stability problems */ +static struct si_dpm_quirk si_dpm_quirk_list[] = { + /* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */ + { PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 }, + { 0, 0, 0, 0 }, +}; + static void si_apply_state_adjust_rules(struct radeon_device *rdev, struct radeon_ps *rps) { @@ -2918,7 +2934,22 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, u32 mclk, sclk; u16 vddc, vddci; u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; + u32 max_sclk = 0, max_mclk = 0; int i; + struct si_dpm_quirk *p = si_dpm_quirk_list; + + /* Apply dpm quirks */ + while (p && p->chip_device != 0) { + if (rdev->pdev->vendor == p->chip_vendor && + rdev->pdev->device == p->chip_device && + rdev->pdev->subsystem_vendor == p->subsys_vendor && + rdev->pdev->subsystem_device == p->subsys_device) { + max_sclk = p->max_sclk; + max_mclk = p->max_mclk; + break; + } + ++p; + } if ((rdev->pm.dpm.new_active_crtc_count > 1) || ni_dpm_vblank_too_short(rdev)) @@ -2972,6 +3003,14 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, if (ps->performance_levels[i].mclk > max_mclk_vddc) ps->performance_levels[i].mclk = max_mclk_vddc; } + if (max_mclk) { + if (ps->performance_levels[i].mclk > max_mclk) + ps->performance_levels[i].mclk = max_mclk; + } + if (max_sclk) { + if (ps->performance_levels[i].sclk > max_sclk) + ps->performance_levels[i].sclk = max_sclk; + } } /* XXX validate the min clocks required for display */ -- cgit v0.10.2 From 84c00afef41a2172b7290f3d75e082e6dd609a58 Mon Sep 17 00:00:00 2001 From: Mike Krinkin Date: Sun, 21 Dec 2014 16:56:47 +0300 Subject: staging: vt6655: fix sparse warnings: incorrect argument type this patch fixes following sparse warnings: drivers/staging/vt6655/device_main.c:1503:25: warning: incorrect type in argument 1 (different address spaces) drivers/staging/vt6655/device_main.c:1503:25: expected void [noderef] * drivers/staging/vt6655/device_main.c:1503:25: got struct vnt_private * drivers/staging/vt6655/device_main.c:1503:25: warning: incorrect type in argument 2 (different address spaces) drivers/staging/vt6655/device_main.c:1503:25: expected void [noderef] * drivers/staging/vt6655/device_main.c:1503:25: got struct vnt_private * drivers/staging/vt6655/device_main.c:1505:25: warning: incorrect type in argument 1 (different address spaces) drivers/staging/vt6655/device_main.c:1505:25: expected void [noderef] * drivers/staging/vt6655/device_main.c:1505:25: got struct vnt_private * drivers/staging/vt6655/device_main.c:1505:25: warning: incorrect type in argument 2 (different address spaces) drivers/staging/vt6655/device_main.c:1505:25: expected void [noderef] * drivers/staging/vt6655/device_main.c:1505:25: got struct vnt_private * Signed-off-by: Mike Krinkin Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 83e4162..ce616f9 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1500,9 +1500,11 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, if (conf->enable_beacon) { vnt_beacon_enable(priv, vif, conf); - MACvRegBitsOn(priv, MAC_REG_TCR, TCR_AUTOBCNTX); + MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, + TCR_AUTOBCNTX); } else { - MACvRegBitsOff(priv, MAC_REG_TCR, TCR_AUTOBCNTX); + MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, + TCR_AUTOBCNTX); } } -- cgit v0.10.2 From b5745290af06a621aaddfd636bab4f08432d0492 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 21 Dec 2014 12:56:34 +0000 Subject: staging: vt6655: vnt_tx_packet Fix corrupted tx packets. Move PSTxDesc->m_td1TD1 to inside spin locks. if m_td1TD1.byTCR has TCR_EDP and TCR_STP are set, the interrupt handler will try and complete the buffer before it is completed. Usually on the tail of a burst of tx packets. This results in a partially completed packet being transmitted or worse sitll dead lock when skb is freed by the interrupt handler. Set head_td->m_td1TD1.byTCR to 0 in first lock of vnt_tx_packet to stop interrupt handler completing the buffer. Move Set TSR1 & ReqCount in s_cbFillTxBufHead to the second lock. cbReqCount is carried to the second lock in pTDInfo->dwReqCount without the padding removed. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index ce616f9..cd1a277 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1232,7 +1232,7 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) head_td = priv->apCurrTD[dma_idx]; - head_td->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); + head_td->m_td1TD1.byTCR = 0; head_td->pTDInfo->skb = skb; @@ -1257,6 +1257,11 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) priv->bPWBitOn = false; + /* Set TSR1 & ReqCount in TxDescHead */ + head_td->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); + head_td->m_td1TD1.wReqCount = + cpu_to_le16((u16)head_td->pTDInfo->dwReqCount); + head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; if (dma_idx == TYPE_AC0DMA) diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 61c39dd..b5b0155 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -1204,13 +1204,10 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, ptdCurr = (PSTxDesc)pHeadTD; - ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; + ptdCurr->pTDInfo->dwReqCount = cbReqCount; ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); - /* Set TSR1 & ReqCount in TxDescHead */ - ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); - ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); return cbHeaderLength; } -- cgit v0.10.2 From 3a9dda79257589fe1ab10d0ce96b22e252354c6b Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 21 Dec 2014 12:56:35 +0000 Subject: staging: vt6655: Fix loss of distant/weak access points on channel change. If the asssocated access point is strong byBBVGACurrent will be adjusted accordingly. Users will nolonger see distant access points without taking down interface. When changing channel reset byBBVGACurrent back to pDevice->abyBBVGA[0] for max sensitivity. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index c8f739d..70f8705 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -182,6 +182,14 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) if (pDevice->byCurrentCh == uConnectionChannel) return bResult; + /* Set VGA to max sensitivity */ + if (pDevice->bUpdateBBVGA && + pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) { + pDevice->byBBVGACurrent = pDevice->abyBBVGA[0]; + + BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); + } + /* clear NAV */ MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV); -- cgit v0.10.2 From a307d1d6d4cf66723a395785fd4c5998fe922b61 Mon Sep 17 00:00:00 2001 From: Eddie Kovsky Date: Sat, 20 Dec 2014 22:27:55 -0700 Subject: staging: vt6655: fix sparse warning: argument type Fixes following warning generated by sparse: drivers/staging/vt6655/baseband.c:2180:45: warning: incorrect type in argument 1 (different address spaces) drivers/staging/vt6655/baseband.c:2180:45: expected struct vnt_private *priv drivers/staging/vt6655/baseband.c:2180:45: got void [noderef] *dwIoBase Compile tested on next-20141219. Signed-off-by: Eddie Kovsky Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 86c72ba..f8c5fc3 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -2177,7 +2177,7 @@ bool BBbVT3253Init(struct vnt_private *priv) /* Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) */ /*bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);*/ /* Select VC1/VC2, CR215 = 0x02->0x06 */ - bResult &= BBbWriteEmbedded(dwIoBase, 0xd7, 0x06); + bResult &= BBbWriteEmbedded(priv, 0xd7, 0x06); /* }} */ for (ii = 0; ii < CB_VT3253B0_AGC; ii++) -- cgit v0.10.2 From d9e020197d371c90ad56cc4be388fc95e0c08e6f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 5 Jan 2015 09:15:16 +0100 Subject: simplefb: Fix build failure on Sparc of_platform_device_create is only defined when CONFIG_OF_ADDRESS is set, which is normally always the case when CONFIG_OF is defined, except on Sparc, so explicitly check for CONFIG_OF_ADDRESS rather then for CONFIG_OF. Reported-by: kbuild test robot Signed-off-by: Hans de Goede Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 92cac80..1085c04 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -402,7 +402,7 @@ static int __init simplefb_init(void) if (ret) return ret; - if (IS_ENABLED(CONFIG_OF) && of_chosen) { + if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) { for_each_child_of_node(of_chosen, np) { if (of_device_is_compatible(np, "simple-framebuffer")) of_platform_device_create(np, NULL, NULL); -- cgit v0.10.2 From 3e14dcf7cb80b34a1f38b55bc96f02d23fdaaaaf Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Sun, 11 Jan 2015 18:17:42 +0100 Subject: crypto: add missing crypto module aliases Commit 5d26a105b5a7 ("crypto: prefix module autoloading with "crypto-"") changed the automatic module loading when requesting crypto algorithms to prefix all module requests with "crypto-". This requires all crypto modules to have a crypto specific module alias even if their file name would otherwise match the requested crypto algorithm. Even though commit 5d26a105b5a7 added those aliases for a vast amount of modules, it was missing a few. Add the required MODULE_ALIAS_CRYPTO annotations to those files to make them get loaded automatically, again. This fixes, e.g., requesting 'ecb(blowfish-generic)', which used to work with kernels v3.18 and below. Also change MODULE_ALIAS() lines to MODULE_ALIAS_CRYPTO(). The former won't work for crypto modules any more. Fixes: 5d26a105b5a7 ("crypto: prefix module autoloading with "crypto-"") Cc: Kees Cook Signed-off-by: Mathias Krause Signed-off-by: Herbert Xu diff --git a/arch/powerpc/crypto/sha1.c b/arch/powerpc/crypto/sha1.c index d3feba5a2..c154ceb 100644 --- a/arch/powerpc/crypto/sha1.c +++ b/arch/powerpc/crypto/sha1.c @@ -154,4 +154,5 @@ module_exit(sha1_powerpc_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm"); +MODULE_ALIAS_CRYPTO("sha1"); MODULE_ALIAS_CRYPTO("sha1-powerpc"); diff --git a/arch/x86/crypto/sha-mb/sha1_mb.c b/arch/x86/crypto/sha-mb/sha1_mb.c index a225a5ca..fd9f6b0 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb.c +++ b/arch/x86/crypto/sha-mb/sha1_mb.c @@ -931,4 +931,4 @@ module_exit(sha1_mb_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, multi buffer accelerated"); -MODULE_ALIAS("sha1"); +MODULE_ALIAS_CRYPTO("sha1"); diff --git a/crypto/aes_generic.c b/crypto/aes_generic.c index 9b3c54c..3dd1011 100644 --- a/crypto/aes_generic.c +++ b/crypto/aes_generic.c @@ -1475,3 +1475,4 @@ module_exit(aes_fini); MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_ALIAS_CRYPTO("aes"); +MODULE_ALIAS_CRYPTO("aes-generic"); diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c index b4485a1..6f5bebc 100644 --- a/crypto/ansi_cprng.c +++ b/crypto/ansi_cprng.c @@ -477,3 +477,4 @@ MODULE_PARM_DESC(dbg, "Boolean to enable debugging (0/1 == off/on)"); module_init(prng_mod_init); module_exit(prng_mod_fini); MODULE_ALIAS_CRYPTO("stdrng"); +MODULE_ALIAS_CRYPTO("ansi_cprng"); diff --git a/crypto/blowfish_generic.c b/crypto/blowfish_generic.c index 7bd71f0..87b392a 100644 --- a/crypto/blowfish_generic.c +++ b/crypto/blowfish_generic.c @@ -139,3 +139,4 @@ module_exit(blowfish_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Blowfish Cipher Algorithm"); MODULE_ALIAS_CRYPTO("blowfish"); +MODULE_ALIAS_CRYPTO("blowfish-generic"); diff --git a/crypto/camellia_generic.c b/crypto/camellia_generic.c index 1b74c5a..a02286b 100644 --- a/crypto/camellia_generic.c +++ b/crypto/camellia_generic.c @@ -1099,3 +1099,4 @@ module_exit(camellia_fini); MODULE_DESCRIPTION("Camellia Cipher Algorithm"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CRYPTO("camellia"); +MODULE_ALIAS_CRYPTO("camellia-generic"); diff --git a/crypto/cast5_generic.c b/crypto/cast5_generic.c index 84c86db..df5c726 100644 --- a/crypto/cast5_generic.c +++ b/crypto/cast5_generic.c @@ -550,3 +550,4 @@ module_exit(cast5_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Cast5 Cipher Algorithm"); MODULE_ALIAS_CRYPTO("cast5"); +MODULE_ALIAS_CRYPTO("cast5-generic"); diff --git a/crypto/cast6_generic.c b/crypto/cast6_generic.c index f408f0b..058c8d7 100644 --- a/crypto/cast6_generic.c +++ b/crypto/cast6_generic.c @@ -292,3 +292,4 @@ module_exit(cast6_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Cast6 Cipher Algorithm"); MODULE_ALIAS_CRYPTO("cast6"); +MODULE_ALIAS_CRYPTO("cast6-generic"); diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c index 2a06202..06f1b60 100644 --- a/crypto/crc32c_generic.c +++ b/crypto/crc32c_generic.c @@ -171,4 +171,5 @@ MODULE_AUTHOR("Clay Haapala "); MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CRYPTO("crc32c"); +MODULE_ALIAS_CRYPTO("crc32c-generic"); MODULE_SOFTDEP("pre: crc32c"); diff --git a/crypto/crct10dif_generic.c b/crypto/crct10dif_generic.c index 08bb4f5..c1229614 100644 --- a/crypto/crct10dif_generic.c +++ b/crypto/crct10dif_generic.c @@ -125,3 +125,4 @@ MODULE_AUTHOR("Tim Chen "); MODULE_DESCRIPTION("T10 DIF CRC calculation."); MODULE_LICENSE("GPL"); MODULE_ALIAS_CRYPTO("crct10dif"); +MODULE_ALIAS_CRYPTO("crct10dif-generic"); diff --git a/crypto/des_generic.c b/crypto/des_generic.c index 4291294..a717205 100644 --- a/crypto/des_generic.c +++ b/crypto/des_generic.c @@ -983,8 +983,6 @@ static struct crypto_alg des_algs[2] = { { .cia_decrypt = des3_ede_decrypt } } } }; -MODULE_ALIAS_CRYPTO("des3_ede"); - static int __init des_generic_mod_init(void) { return crypto_register_algs(des_algs, ARRAY_SIZE(des_algs)); @@ -1001,4 +999,7 @@ module_exit(des_generic_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); MODULE_AUTHOR("Dag Arne Osvik "); -MODULE_ALIAS("des"); +MODULE_ALIAS_CRYPTO("des"); +MODULE_ALIAS_CRYPTO("des-generic"); +MODULE_ALIAS_CRYPTO("des3_ede"); +MODULE_ALIAS_CRYPTO("des3_ede-generic"); diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c index 4e97fae..bac7099 100644 --- a/crypto/ghash-generic.c +++ b/crypto/ghash-generic.c @@ -173,3 +173,4 @@ module_exit(ghash_mod_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("GHASH Message Digest Algorithm"); MODULE_ALIAS_CRYPTO("ghash"); +MODULE_ALIAS_CRYPTO("ghash-generic"); diff --git a/crypto/krng.c b/crypto/krng.c index 67c88b3..0224841 100644 --- a/crypto/krng.c +++ b/crypto/krng.c @@ -63,3 +63,4 @@ module_exit(krng_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Kernel Random Number Generator"); MODULE_ALIAS_CRYPTO("stdrng"); +MODULE_ALIAS_CRYPTO("krng"); diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c index 3d0f9df..f550b5d 100644 --- a/crypto/salsa20_generic.c +++ b/crypto/salsa20_generic.c @@ -249,3 +249,4 @@ module_exit(salsa20_generic_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION ("Salsa20 stream cipher algorithm"); MODULE_ALIAS_CRYPTO("salsa20"); +MODULE_ALIAS_CRYPTO("salsa20-generic"); diff --git a/crypto/serpent_generic.c b/crypto/serpent_generic.c index a53b5e2..94970a7 100644 --- a/crypto/serpent_generic.c +++ b/crypto/serpent_generic.c @@ -667,3 +667,4 @@ MODULE_DESCRIPTION("Serpent and tnepres (kerneli compatible serpent reversed) Ci MODULE_AUTHOR("Dag Arne Osvik "); MODULE_ALIAS_CRYPTO("tnepres"); MODULE_ALIAS_CRYPTO("serpent"); +MODULE_ALIAS_CRYPTO("serpent-generic"); diff --git a/crypto/sha1_generic.c b/crypto/sha1_generic.c index 039e58c..a3e50c3 100644 --- a/crypto/sha1_generic.c +++ b/crypto/sha1_generic.c @@ -154,3 +154,4 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm"); MODULE_ALIAS_CRYPTO("sha1"); +MODULE_ALIAS_CRYPTO("sha1-generic"); diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c index 5eb21b1..b001ff5 100644 --- a/crypto/sha256_generic.c +++ b/crypto/sha256_generic.c @@ -385,4 +385,6 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm"); MODULE_ALIAS_CRYPTO("sha224"); +MODULE_ALIAS_CRYPTO("sha224-generic"); MODULE_ALIAS_CRYPTO("sha256"); +MODULE_ALIAS_CRYPTO("sha256-generic"); diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c index 8d0b19e..1c3c376 100644 --- a/crypto/sha512_generic.c +++ b/crypto/sha512_generic.c @@ -289,4 +289,6 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms"); MODULE_ALIAS_CRYPTO("sha384"); +MODULE_ALIAS_CRYPTO("sha384-generic"); MODULE_ALIAS_CRYPTO("sha512"); +MODULE_ALIAS_CRYPTO("sha512-generic"); diff --git a/crypto/tea.c b/crypto/tea.c index 495be2d..b70b441 100644 --- a/crypto/tea.c +++ b/crypto/tea.c @@ -270,6 +270,7 @@ static void __exit tea_mod_fini(void) crypto_unregister_algs(tea_algs, ARRAY_SIZE(tea_algs)); } +MODULE_ALIAS_CRYPTO("tea"); MODULE_ALIAS_CRYPTO("xtea"); MODULE_ALIAS_CRYPTO("xeta"); diff --git a/crypto/tgr192.c b/crypto/tgr192.c index 6e5651c..321bc6f 100644 --- a/crypto/tgr192.c +++ b/crypto/tgr192.c @@ -676,6 +676,7 @@ static void __exit tgr192_mod_fini(void) crypto_unregister_shashes(tgr_algs, ARRAY_SIZE(tgr_algs)); } +MODULE_ALIAS_CRYPTO("tgr192"); MODULE_ALIAS_CRYPTO("tgr160"); MODULE_ALIAS_CRYPTO("tgr128"); diff --git a/crypto/twofish_generic.c b/crypto/twofish_generic.c index 523ad8c..ebf7a3e 100644 --- a/crypto/twofish_generic.c +++ b/crypto/twofish_generic.c @@ -212,3 +212,4 @@ module_exit(twofish_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION ("Twofish Cipher Algorithm"); MODULE_ALIAS_CRYPTO("twofish"); +MODULE_ALIAS_CRYPTO("twofish-generic"); diff --git a/crypto/wp512.c b/crypto/wp512.c index 0de42eb..7ee5a04 100644 --- a/crypto/wp512.c +++ b/crypto/wp512.c @@ -1167,6 +1167,7 @@ static void __exit wp512_mod_fini(void) crypto_unregister_shashes(wp_algs, ARRAY_SIZE(wp_algs)); } +MODULE_ALIAS_CRYPTO("wp512"); MODULE_ALIAS_CRYPTO("wp384"); MODULE_ALIAS_CRYPTO("wp256"); -- cgit v0.10.2 From ef6899cdc8608e2f018e590683f04bb04a069704 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 12 Jan 2015 15:27:52 +0000 Subject: fbdev/broadsheetfb: fix memory leak static code analysis from cppcheck reports: [drivers/video/fbdev/broadsheetfb.c:673]: (error) Memory leak: sector_buffer sector_buffer is not being kfree'd on each call to broadsheet_spiflash_rewrite_sector(), so free it. Signed-off-by: Colin Ian King Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/fbdev/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c index 1c29bd1..0e5fde1 100644 --- a/drivers/video/fbdev/broadsheetfb.c +++ b/drivers/video/fbdev/broadsheetfb.c @@ -636,7 +636,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, err = broadsheet_spiflash_read_range(par, start_sector_addr, data_start_addr, sector_buffer); if (err) - return err; + goto out; } /* now we copy our data into the right place in the sector buffer */ @@ -657,7 +657,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, err = broadsheet_spiflash_read_range(par, tail_start_addr, tail_len, sector_buffer + tail_start_addr); if (err) - return err; + goto out; } /* if we got here we have the full sector that we want to rewrite. */ @@ -665,11 +665,13 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, /* first erase the sector */ err = broadsheet_spiflash_erase_sector(par, start_sector_addr); if (err) - return err; + goto out; /* now write it */ err = broadsheet_spiflash_write_sector(par, start_sector_addr, sector_buffer, sector_size); +out: + kfree(sector_buffer); return err; } -- cgit v0.10.2 From 90bdf403db4ca75ee60ca5a760dc342cef96b5e1 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 13 Jan 2015 15:25:11 +0100 Subject: usb: phy: mv-usb: fix usb_phy build errors The driver was recently adapted to a core API change, but the change was incomplete, missing out the suspend helper and leaving an extraneous local variable around: usb/phy/phy-mv-usb.c: In function 'mv_otg_update_state': usb/phy/phy-mv-usb.c:341:18: warning: unused variable 'phy' [-Wunused-variable] usb/phy/phy-mv-usb.c: In function 'mv_otg_suspend': usb/phy/phy-mv-usb.c:861:16: error: 'struct usb_phy' has no member named 'state' Signed-off-by: Arnd Bergmann Fixes: e47d92545c297 ("usb: move the OTG state from the USB PHY to the OTG structure") Signed-off-by: Felipe Balbi diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index 699e38c..697a741 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -338,7 +338,6 @@ static void mv_otg_update_inputs(struct mv_otg *mvotg) static void mv_otg_update_state(struct mv_otg *mvotg) { struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; - struct usb_phy *phy = &mvotg->phy; int old_state = mvotg->phy.otg->state; switch (old_state) { @@ -858,10 +857,10 @@ static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state) { struct mv_otg *mvotg = platform_get_drvdata(pdev); - if (mvotg->phy.state != OTG_STATE_B_IDLE) { + if (mvotg->phy.otg->state != OTG_STATE_B_IDLE) { dev_info(&pdev->dev, "OTG state is not B_IDLE, it is %d!\n", - mvotg->phy.state); + mvotg->phy.otg->state); return -EAGAIN; } -- cgit v0.10.2 From 46319e13581a6c442b0a0e5a3bd5d9af4496f252 Mon Sep 17 00:00:00 2001 From: James Ralston Date: Mon, 12 Jan 2015 16:13:52 -0800 Subject: ahci: Remove Device ID for Intel Sunrise Point PCH This patch removes a duplicate AHCI-mode SATA Device ID for the Intel Sunrise Point PCH. Signed-off-by: James Ralston Signed-off-by: Tejun Heo diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 49f1e68..33bb06e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -325,7 +325,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */ { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */ { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ - { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ -- cgit v0.10.2 From 6acf3998d2c7420b2deb2b475fa78ba7573c6162 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 13 Jan 2015 18:57:15 +0200 Subject: dmaengine: dw: balance PM runtime calls In case of PCI driver we will get a warning: dw_dmac_pci 0000:00:18.0: Unbalanced pm_runtime_enable! dw_dmac_pci 0000:00:18.0: DesignWare DMA Controller, 8 channels This happens due to pm_runtime_enable() call from the driver when PM runtime is enabled by core. This patch moves that call to the platform driver where it might make sense. Fixes: bb32baf76e56 (dmaengine: dw: enable runtime PM) Signed-off-by: Andy Shevchenko Signed-off-by: Vinod Koul diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 3804785..5c06254 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -1505,7 +1505,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) dw->regs = chip->regs; chip->dw = dw; - pm_runtime_enable(chip->dev); pm_runtime_get_sync(chip->dev); dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); @@ -1703,7 +1702,6 @@ int dw_dma_remove(struct dw_dma_chip *chip) } pm_runtime_put_sync_suspend(chip->dev); - pm_runtime_disable(chip->dev); return 0; } EXPORT_SYMBOL_GPL(dw_dma_remove); diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c index a630161..32ea1ac 100644 --- a/drivers/dma/dw/platform.c +++ b/drivers/dma/dw/platform.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -185,6 +186,8 @@ static int dw_probe(struct platform_device *pdev) if (err) return err; + pm_runtime_enable(&pdev->dev); + err = dw_dma_probe(chip, pdata); if (err) goto err_dw_dma_probe; @@ -205,6 +208,7 @@ static int dw_probe(struct platform_device *pdev) return 0; err_dw_dma_probe: + pm_runtime_disable(&pdev->dev); clk_disable_unprepare(chip->clk); return err; } @@ -217,6 +221,7 @@ static int dw_remove(struct platform_device *pdev) of_dma_controller_free(pdev->dev.of_node); dw_dma_remove(chip); + pm_runtime_disable(&pdev->dev); clk_disable_unprepare(chip->clk); return 0; -- cgit v0.10.2 From dca1a4b5ff6e2c25adeff366eb06270dadeab3db Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 13 Jan 2015 15:44:06 +0100 Subject: clk: at91: keep slow clk enabled to prevent system hang All slow clk users are not properly claiming it (get + prepare + enable) before using it. If all users properly claiming this clock release it, the clock is disabled, but faulty users still depends on it, and the system hangs. This fix prevents the slow clock from being disabled, and should solve the hanging issue, but offending drivers should be patched to properly claim this clock. Signed-off-by: Boris Brezillon Reported-by: Bo Shen Cc: stable@vger.kernel.org Signed-off-by: Michael Turquette diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index 32f7c1b..2f13bd5 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c @@ -70,6 +70,7 @@ struct clk_sam9x5_slow { #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) +static struct clk *slow_clk; static int clk_slow_osc_prepare(struct clk_hw *hw) { @@ -357,6 +358,8 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr, clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) kfree(slowck); + else + slow_clk = clk; return clk; } @@ -433,6 +436,8 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) kfree(slowck); + else + slow_clk = clk; return clk; } @@ -465,3 +470,25 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np, of_clk_add_provider(np, of_clk_src_simple_get, clk); } + +/* + * FIXME: All slow clk users are not properly claiming it (get + prepare + + * enable) before using it. + * If all users properly claiming this clock decide that they don't need it + * anymore (or are removed), it is disabled while faulty users are still + * requiring it, and the system hangs. + * Prevent this clock from being disabled until all users are properly + * requesting it. + * Once this is done we should remove this function and the slow_clk variable. + */ +static int __init of_at91_clk_slow_retain(void) +{ + if (!slow_clk) + return 0; + + __clk_get(slow_clk); + clk_prepare_enable(slow_clk); + + return 0; +} +arch_initcall(of_at91_clk_slow_retain); -- cgit v0.10.2 From b71e8ecd57c8aae5b1815782c47b74ffe3efc09a Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Wed, 31 Dec 2014 16:57:52 +0800 Subject: clk: berlin: bg2q: remove non-exist "smemc" gate clock The "smemc" clock is removed on BG2Q SoCs. In fact, bit19 of clkenable register is for nfc. Current code use bit19 for non-exist "smemc" incorrectly, this prevents eMMC from working due to the sdhci's "core" clk is still gated. Signed-off-by: Jisheng Zhang Cc: stable@vger.kernel.org # 3.16+ Signed-off-by: Michael Turquette diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c index 21784e4..440ef81 100644 --- a/drivers/clk/berlin/bg2q.c +++ b/drivers/clk/berlin/bg2q.c @@ -285,7 +285,6 @@ static const struct berlin2_gate_data bg2q_gates[] __initconst = { { "pbridge", "perif", 15, CLK_IGNORE_UNUSED }, { "sdio", "perif", 16, CLK_IGNORE_UNUSED }, { "nfc", "perif", 18 }, - { "smemc", "perif", 19 }, { "pcie", "perif", 22 }, }; -- cgit v0.10.2 From 7d1f90188a64ba14c7b465547dba0b91a97075cf Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 26 Dec 2014 13:47:30 -0600 Subject: MAINTAINERS: drop DT regex matching on of_get_property and of_match_table The regex matching on of_get_property and of_match_table cause Grant and me to be copied on loads of drivers as well as be listed as maintainers of those drivers. I believe the intent here was to check for documenting of properties, but that has proven horribly ineffective. checkpatch now at least partially covers this checking compatible strings. So remove these regex's to reduce the firehose somewhat. Cc: Grant Likely Signed-off-by: Rob Herring diff --git a/MAINTAINERS b/MAINTAINERS index 3589d67..94cc4b9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -696,7 +696,7 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers) W: http://blackfin.uclinux.org/ S: Supported F: sound/soc/blackfin/* - + ANALOG DEVICES INC IIO DRIVERS M: Lars-Peter Clausen M: Michael Hennerich @@ -6984,8 +6984,6 @@ S: Maintained F: drivers/of/ F: include/linux/of*.h F: scripts/dtc/ -K: of_get_property -K: of_match_table OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS M: Rob Herring -- cgit v0.10.2 From a7fefe9fb81f68b0784c84290939c295bcf61a74 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 26 Dec 2014 14:05:54 -0600 Subject: MAINTAINERS: Update DT website and git repository Per Grant, secretlab.ca is defunct and he has moved his tree to kernel.org so update the DT website and git tree. devicetree.org needs work, but is better than "Internal Server Error" that secretlab.ca returns. Cc: Grant Likely Signed-off-by: Rob Herring diff --git a/MAINTAINERS b/MAINTAINERS index 94cc4b9..6440d08 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6978,8 +6978,8 @@ OPEN FIRMWARE AND FLATTENED DEVICE TREE M: Grant Likely M: Rob Herring L: devicetree@vger.kernel.org -W: http://fdt.secretlab.ca -T: git git://git.secretlab.ca/git/linux-2.6.git +W: http://www.devicetree.org/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/glikely/linux.git S: Maintained F: drivers/of/ F: include/linux/of*.h -- cgit v0.10.2 From 7c2461b766d5c7627e85e05d8f411781dbc3b37b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 10 Dec 2014 14:54:29 +0100 Subject: dt/bindings: arm-boards: Spelling s/pointong/pointing/ Signed-off-by: Geert Uytterhoeven Cc: Russell King Cc: Rob Herring Signed-off-by: Rob Herring diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index 556c866..b78564b2 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards @@ -23,7 +23,7 @@ Required nodes: range of 0x200 bytes. - syscon: the root node of the Integrator platforms must have a - system controller node pointong to the control registers, + system controller node pointing to the control registers, with the compatible string "arm,integrator-ap-syscon" "arm,integrator-cp-syscon" -- cgit v0.10.2 From d6613aa750ad66b25737231415050f1dca924eb7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 10 Dec 2014 14:54:28 +0100 Subject: ARM: dt: GIC: Spelling s/specific/specifier/, s/flaggs/flags/ Signed-off-by: Geert Uytterhoeven Cc: Stephen Warren Cc: Rob Herring Signed-off-by: Rob Herring diff --git a/include/dt-bindings/interrupt-controller/arm-gic.h b/include/dt-bindings/interrupt-controller/arm-gic.h index 1ea1b70..d4110d5 100644 --- a/include/dt-bindings/interrupt-controller/arm-gic.h +++ b/include/dt-bindings/interrupt-controller/arm-gic.h @@ -7,14 +7,14 @@ #include -/* interrupt specific cell 0 */ +/* interrupt specifier cell 0 */ #define GIC_SPI 0 #define GIC_PPI 1 /* * Interrupt specifier cell 2. - * The flaggs in irq.h are valid, plus those below. + * The flags in irq.h are valid, plus those below. */ #define GIC_CPU_MASK_RAW(x) ((x) << 8) #define GIC_CPU_MASK_SIMPLE(num) GIC_CPU_MASK_RAW((1 << (num)) - 1) -- cgit v0.10.2 From 7c7a9b3de5282b5b83b7a5cf388fb8b5bd30d66e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 25 Dec 2014 03:55:52 +0000 Subject: of: replace Asahi Kasei Corp vendor prefix Current vendor-prefixes.txt already has "ak" prefix for Asahi Kasei Corp by ae8c4209af2c(of: Add vendor prefix for Asahi Kasei Corp.) It went through the appropriate review process. But, almost all Asahi Kasei chip drivers are using "asahi-kasei" prefix today. (arch/arm/boot/dts/tegra20-seaboard.dts only is using "ak,ak8975", but there are instances of "asahi-kasei,ak8975" in other dts files. And drivers/iio/magnetometer/ak8975.c doesn't support "ak,ak8975" prefix) So, we made a mistake there. In addition, checkpatch.pl reports WARNING if it is using "asahi-kasei" prerfix in DT file. (DT compatible string vendor "asahi-kasei" appears un-documented) Marking it deprecated and warning with checkpatch is certainly preferable. So, this patch replace "ak" to "asahi-kasei" in vendor-prefixes.txt. (and fixup tegra20-seaboard) OTOH, Asahi Kasei is usually referred to as "AKM", but this patch doesn't care about it. Because no DT is using that today. Signed-off-by: Kuninori Morimoto Acked-by: Thierry Reding Acked-by: Alexandre Courbot Signed-off-by: Rob Herring diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index b1df0ad..769b9de 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -9,7 +9,6 @@ ad Avionic Design GmbH adapteva Adapteva, Inc. adi Analog Devices, Inc. aeroflexgaisler Aeroflex Gaisler AB -ak Asahi Kasei Corp. allwinner Allwinner Technology Co., Ltd. altr Altera Corp. amcc Applied Micro Circuits Corporation (APM, formally AMCC) @@ -20,6 +19,7 @@ amstaos AMS-Taos Inc. apm Applied Micro Circuits Corporation (APM) arm ARM Ltd. armadeus ARMadeus Systems SARL +asahi-kasei Asahi Kasei Corp. atmel Atmel Corporation auo AU Optronics Corporation avago Avago Technologies diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts index ea282c7..e2fed27 100644 --- a/arch/arm/boot/dts/tegra20-seaboard.dts +++ b/arch/arm/boot/dts/tegra20-seaboard.dts @@ -406,7 +406,7 @@ clock-frequency = <400000>; magnetometer@c { - compatible = "ak,ak8975"; + compatible = "asahi-kasei,ak8975"; reg = <0xc>; interrupt-parent = <&gpio>; interrupts = ; -- cgit v0.10.2 From 3772160d7b5f40f28ed703ada9b7deef5edc0483 Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Mon, 22 Dec 2014 10:35:09 -0500 Subject: dma-mapping: fix debug print to display correct dma_pfn_offset fix the dev_dbg to display the offset which is the calculated dma_pfn_offset value and set later in the code. Signed-off-by: Murali Karicheri Signed-off-by: Rob Herring diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 5b33c6a..a54ec10 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -188,7 +188,7 @@ static void of_dma_configure(struct device *dev) size = dev->coherent_dma_mask; } else { offset = PFN_DOWN(paddr - dma_addr); - dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", dev->dma_pfn_offset); + dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset); } dev->dma_pfn_offset = offset; -- cgit v0.10.2 From 9d45e8818099ae02ee617550423ce7c29e32d1d8 Mon Sep 17 00:00:00 2001 From: Kaixu Xia Date: Mon, 5 Jan 2015 18:02:16 +0800 Subject: Documentation: of: fix typo in graph bindings Just fix a minor typo about the example path. Signed-off-by: Kaixu Xia Acked-by: Philipp Zabel Signed-off-by: Rob Herring diff --git a/Documentation/devicetree/bindings/graph.txt b/Documentation/devicetree/bindings/graph.txt index 1a69c07..fcb1c6a 100644 --- a/Documentation/devicetree/bindings/graph.txt +++ b/Documentation/devicetree/bindings/graph.txt @@ -19,7 +19,7 @@ type of the connections, they just map their existence. Specific properties may be described by specialized bindings depending on the type of connection. To see how this binding applies to video pipelines, for example, see -Documentation/device-tree/bindings/media/video-interfaces.txt. +Documentation/devicetree/bindings/media/video-interfaces.txt. Here the ports describe data interfaces, and the links between them are the connecting data buses. A single port with multiple connections can correspond to multiple devices being connected to the same physical bus. -- cgit v0.10.2 From 53275a61bc7a107dd75406931f8078c7d2c8b9db Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Wed, 7 Jan 2015 18:42:54 +0100 Subject: devicetree: document ARM bindings for QEMU's Firmware Config interface Peter Maydell suggested that we describe new devices / DTB nodes in the kernel Documentation tree that we expose to arm "virt" guests in QEMU. Although the kernel is not required to access the fw_cfg interface, "Documentation/devicetree/bindings/arm" is probably the best central spot to keep the fw_cfg description in. Suggested-by: Peter Maydell Signed-off-by: Laszlo Ersek Acked-by: Arnd Bergmann Acked-by: Mark Rutland Signed-off-by: Rob Herring diff --git a/Documentation/devicetree/bindings/arm/fw-cfg.txt b/Documentation/devicetree/bindings/arm/fw-cfg.txt new file mode 100644 index 0000000..953fb64 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/fw-cfg.txt @@ -0,0 +1,72 @@ +* QEMU Firmware Configuration bindings for ARM + +QEMU's arm-softmmu and aarch64-softmmu emulation / virtualization targets +provide the following Firmware Configuration interface on the "virt" machine +type: + +- A write-only, 16-bit wide selector (or control) register, +- a read-write, 64-bit wide data register. + +QEMU exposes the control and data register to ARM guests as memory mapped +registers; their location is communicated to the guest's UEFI firmware in the +DTB that QEMU places at the bottom of the guest's DRAM. + +The guest writes a selector value (a key) to the selector register, and then +can read the corresponding data (produced by QEMU) via the data register. If +the selected entry is writable, the guest can rewrite it through the data +register. + +The selector register takes keys in big endian byte order. + +The data register allows accesses with 8, 16, 32 and 64-bit width (only at +offset 0 of the register). Accesses larger than a byte are interpreted as +arrays, bundled together only for better performance. The bytes constituting +such a word, in increasing address order, correspond to the bytes that would +have been transferred by byte-wide accesses in chronological order. + +The interface allows guest firmware to download various parameters and blobs +that affect how the firmware works and what tables it installs for the guest +OS. For example, boot order of devices, ACPI tables, SMBIOS tables, kernel and +initrd images for direct kernel booting, virtual machine UUID, SMP information, +virtual NUMA topology, and so on. + +The authoritative registry of the valid selector values and their meanings is +the QEMU source code; the structure of the data blobs corresponding to the +individual key values is also defined in the QEMU source code. + +The presence of the registers can be verified by selecting the "signature" blob +with key 0x0000, and reading four bytes from the data register. The returned +signature is "QEMU". + +The outermost protocol (involving the write / read sequences of the control and +data registers) is expected to be versioned, and/or described by feature bits. +The interface revision / feature bitmap can be retrieved with key 0x0001. The +blob to be read from the data register has size 4, and it is to be interpreted +as a uint32_t value in little endian byte order. The current value +(corresponding to the above outer protocol) is zero. + +The guest kernel is not expected to use these registers (although it is +certainly allowed to); the device tree bindings are documented here because +this is where device tree bindings reside in general. + +Required properties: + +- compatible: "qemu,fw-cfg-mmio". + +- reg: the MMIO region used by the device. + * Bytes 0x0 to 0x7 cover the data register. + * Bytes 0x8 to 0x9 cover the selector register. + * Further registers may be appended to the region in case of future interface + revisions / feature bits. + +Example: + +/ { + #size-cells = <0x2>; + #address-cells = <0x2>; + + fw-cfg@9020000 { + compatible = "qemu,fw-cfg-mmio"; + reg = <0x0 0x9020000 0x0 0xa>; + }; +}; -- cgit v0.10.2 From 957c8111478369780b241b19947ed52ba89acf80 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Wed, 7 Jan 2015 18:42:53 +0100 Subject: devicetree: document the "qemu" and "virtio" vendor prefixes The QEMU open source machine emulator and virtualizer presents firmware and operating systems running in virtual machines ("guests") with purely virtual hardware (ie. hardware that has never existed in physical form). Since QEMU exposes some of these devices in a DTB, it makes sense to define "qemu" and "virtio" as vendor prefixes. The qemu definition is from [1], revision 4451 (22:24, 25 November 2014). The virtio definition is composed from [2] and [3]. [1] http://wiki.qemu.org/Main_Page [2] http://docs.oasis-open.org/virtio/virtio/v1.0/csprd01/virtio-v1.0-csprd01.html [3] http://en.wikipedia.org/wiki/OASIS_%28organization%29 Suggested-by: Mark Rutland Suggested-by: Arnd Bergmann Signed-off-by: Laszlo Ersek Acked-by: Arnd Bergmann Acked-by: Mark Rutland Signed-off-by: Rob Herring diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 769b9de..d443279 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -127,6 +127,7 @@ pixcir PIXCIR MICROELECTRONICS Co., Ltd powervr PowerVR (deprecated, use img) qca Qualcomm Atheros, Inc. qcom Qualcomm Technologies, Inc +qemu QEMU, a generic and open source machine emulator and virtualizer qnap QNAP Systems, Inc. radxa Radxa raidsonic RaidSonic Technology GmbH @@ -168,6 +169,7 @@ usi Universal Scientific Industrial Co., Ltd. v3 V3 Semiconductor variscite Variscite Ltd. via VIA Technologies, Inc. +virtio Virtual I/O Device Specification, developed by the OASIS consortium voipac Voipac Technologies s.r.o. winbond Winbond Electronics corp. wlf Wolfson Microelectronics -- cgit v0.10.2 From 19406d7d9512254d1a467997101bb77b090a44be Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 13 Jan 2015 19:25:17 +0100 Subject: ata: pata_at91: depend on !ARCH_MULTIPLATFORM Until the driver is corrected to stop using mach/at91isam9_smc.h, it won't compile in a ARCH_MULTIPLATFORM configuration. Suggested-by: Arnd Bergmann Signed-off-by: Alexandre Belloni Signed-off-by: Tejun Heo diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index a3a1360..5f60155 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -835,6 +835,7 @@ config PATA_AT32 config PATA_AT91 tristate "PATA support for AT91SAM9260" depends on ARM && SOC_AT91SAM9 + depends on !ARCH_MULTIPLATFORM help This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. -- cgit v0.10.2 From 3cbc6123a93dc91b99b58f7ea37d267fe93e1cad Mon Sep 17 00:00:00 2001 From: Tim Kryger Date: Wed, 14 Jan 2015 07:24:12 +0100 Subject: mmc: sdhci: Set SDHCI_POWER_ON with external vmmc Host controllers lacking the required internal vmmc regulator may still follow the spec with regard to the LSB of SDHCI_POWER_CONTROL. Set the SDHCI_POWER_ON bit when vmmc is enabled to encourage the controller to to drive CMD, DAT, SDCLK. This fixes a regression observed on some Qualcomm and Nvidia boards caused by 5222161 mmc: sdhci: Improve external VDD regulator support. Fixes: 52221610dd84 (mmc: sdhci: Improve external VDD regulator support) Signed-off-by: Tim Kryger Tested-by: Bjorn Andersson Signed-off-by: Ulf Hansson diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 1453cd1..f1a488e 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1271,6 +1271,12 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode, spin_unlock_irq(&host->lock); mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); spin_lock_irq(&host->lock); + + if (mode != MMC_POWER_OFF) + sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL); + else + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); + return; } -- cgit v0.10.2 From e733a2fb8cbcff0747108cb529ffb4e4a00465ac Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Mon, 12 Jan 2015 10:09:32 +0800 Subject: gpio: crystalcove: use handle_nested_irq The CrystalCove GPIO chip has can_sleep set so its demultiplexed irqs will have IRQ_NESTED_THREAD flag set, thus we should use the nested version handle_nested_irq in CrystalCove's irq handler instead of handle_generic_irq, or the following warning will be hit and the functionality is lost: [ 4089.639554] Hardware name: ASUSTeK COMPUTER INC. T100TA/T100TA, BIOS T100TA.313 08/13/2014 [ 4089.639564] 00000002 00000000 c24fbdf4 c16e0257 c24fbe38 c24fbe28 c105390c c18ec480 [ 4089.639596] c24fbe54 00000048 c18f8e3b 00000295 c10a60fc 00000295 c10a60fc f4464540 [ 4089.639626] f446459c c278ad40 c24fbe40 c1053974 00000009 c24fbe38 c18ec480 c24fbe54 [ 4089.639656] Call Trace: [ 4089.639685] [] dump_stack+0x41/0x52 [ 4089.639707] [] warn_slowpath_common+0x8c/0xc0 [ 4089.639727] [] ? irq_nested_primary_handler+0x2c/0x30 [ 4089.639744] [] ? irq_nested_primary_handler+0x2c/0x30 [ 4089.639763] [] warn_slowpath_fmt+0x34/0x40 [ 4089.639781] [] irq_nested_primary_handler+0x2c/0x30 [ 4089.639800] [] handle_irq_event_percpu+0x76/0x190 [ 4089.639818] [] ? regmap_format_10_14_write+0x30/0x30 [ 4089.639836] [] ? _regmap_bus_raw_write+0x4c/0x70 [ 4089.639854] [] handle_irq_event+0x31/0x50 [ 4089.639872] [] handle_simple_irq+0x4b/0x70 [ 4089.639889] [] generic_handle_irq+0x24/0x40 [ 4089.639908] [] crystalcove_gpio_irq_handler+0xa7/0xc0 [ 4089.639927] [] handle_nested_irq+0x77/0x190 [ 4089.639947] [] regmap_irq_thread+0x1b1/0x360 [ 4089.639966] [] irq_thread_fn+0x18/0x30 [ 4089.639983] [] irq_thread+0xf6/0x110 [ 4089.640001] [] ? irq_finalize_oneshot.part.30+0x1b0/0x1b0 [ 4089.640019] [] ? irq_forced_thread_fn+0x50/0x50 [ 4089.640037] [] ? irq_thread_check_affinity+0xc0/0xc0 [ 4089.640054] [] kthread+0xa9/0xc0 [ 4089.640074] [] ret_from_kernel_thread+0x21/0x30 [ 4089.640091] [] ? kthread_create_on_node+0x110/0x110 [ 4089.640105] ---[ end trace dca7946ad31eba7d ]--- Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=90521 Reported-and-tested-by: Brian Loften Cc: Stable Signed-off-by: Aaron Lu Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 55d4803..3d9e08f 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -272,7 +272,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data) for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) { if (pending & BIT(gpio)) { virq = irq_find_mapping(cg->chip.irqdomain, gpio); - generic_handle_irq(virq); + handle_nested_irq(virq); } } -- cgit v0.10.2 From 53b1bfc76df23230bbe32fd5879ff4927f04c53a Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Mon, 22 Dec 2014 10:47:29 -0800 Subject: pinctrl: rockchip: Avoid losing interrupts when supporting both edges I was seeing cases where I was losing interrupts when inserting and removing SD cards. Sometimes the card would get "stuck" in the inserted state. I believe that the problem was related to the code to handle the case where we needed both rising and falling edges. This code would disable the interrupt as the polarity was switched. If an interrupt came at the wrong time it could be lost. We'll match what the gpio-dwapb.c driver does upstream and change the interrupt polarity without disabling things. Signed-off-by: Doug Anderson Reviewed-by: Heiko Stuebner Tested-by: Heiko Stuebner Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 3c22dbe..43eacc9 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1398,10 +1398,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) { struct irq_chip *chip = irq_get_chip(irq); struct rockchip_pin_bank *bank = irq_get_handler_data(irq); - u32 polarity = 0, data = 0; u32 pend; - bool edge_changed = false; - unsigned long flags; dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); @@ -1409,12 +1406,6 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); - if (bank->toggle_edge_mode) { - polarity = readl_relaxed(bank->reg_base + - GPIO_INT_POLARITY); - data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); - } - while (pend) { unsigned int virq; @@ -1434,27 +1425,31 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) * needs manual intervention. */ if (bank->toggle_edge_mode & BIT(irq)) { - if (data & BIT(irq)) - polarity &= ~BIT(irq); - else - polarity |= BIT(irq); + u32 data, data_old, polarity; + unsigned long flags; - edge_changed = true; - } + data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); + do { + spin_lock_irqsave(&bank->slock, flags); - generic_handle_irq(virq); - } + polarity = readl_relaxed(bank->reg_base + + GPIO_INT_POLARITY); + if (data & BIT(irq)) + polarity &= ~BIT(irq); + else + polarity |= BIT(irq); + writel(polarity, + bank->reg_base + GPIO_INT_POLARITY); - if (bank->toggle_edge_mode && edge_changed) { - /* Interrupt params should only be set with ints disabled */ - spin_lock_irqsave(&bank->slock, flags); + spin_unlock_irqrestore(&bank->slock, flags); - data = readl_relaxed(bank->reg_base + GPIO_INTEN); - writel_relaxed(0, bank->reg_base + GPIO_INTEN); - writel(polarity, bank->reg_base + GPIO_INT_POLARITY); - writel(data, bank->reg_base + GPIO_INTEN); + data_old = data; + data = readl_relaxed(bank->reg_base + + GPIO_EXT_PORT); + } while ((data & BIT(irq)) != (data_old & BIT(irq))); + } - spin_unlock_irqrestore(&bank->slock, flags); + generic_handle_irq(virq); } chained_irq_exit(chip, desc); -- cgit v0.10.2 From db93facfb0ef542aa5d8079e47580b3e669a4d82 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Thu, 8 Jan 2015 20:25:05 +0800 Subject: pinctrl: Fix two deadlocks This patch is to fix two deadlock cases. Deadlock 1: CPU #1 pinctrl_register-> pinctrl_get -> create_pinctrl (Holding lock pinctrl_maps_mutex) -> get_pinctrl_dev_from_devname (Trying to acquire lock pinctrldev_list_mutex) CPU #0 pinctrl_unregister (Holding lock pinctrldev_list_mutex) -> pinctrl_put ->> pinctrl_free -> pinctrl_dt_free_maps -> pinctrl_unregister_map (Trying to acquire lock pinctrl_maps_mutex) Simply to say CPU#1 is holding lock A and trying to acquire lock B, CPU#0 is holding lock B and trying to acquire lock A. Deadlock 2: CPU #3 pinctrl_register-> pinctrl_get -> create_pinctrl (Holding lock pinctrl_maps_mutex) -> get_pinctrl_dev_from_devname (Trying to acquire lock pinctrldev_list_mutex) CPU #2 pinctrl_unregister (Holding lock pctldev->mutex) -> pinctrl_put ->> pinctrl_free -> pinctrl_dt_free_maps -> pinctrl_unregister_map (Trying to acquire lock pinctrl_maps_mutex) CPU #0 tegra_gpio_request (Holding lock pinctrldev_list_mutex) -> pinctrl_get_device_gpio_range (Trying to acquire lock pctldev->mutex) Simply to say CPU#3 is holding lock A and trying to acquire lock D, CPU#2 is holding lock B and trying to acquire lock A, CPU#0 is holding lock D and trying to acquire lock B. Cc: Stable Signed-off-by: Jim Lin Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index e4f6551..89dca77 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1801,14 +1801,15 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) if (pctldev == NULL) return; - mutex_lock(&pinctrldev_list_mutex); mutex_lock(&pctldev->mutex); - pinctrl_remove_device_debugfs(pctldev); + mutex_unlock(&pctldev->mutex); if (!IS_ERR(pctldev->p)) pinctrl_put(pctldev->p); + mutex_lock(&pinctrldev_list_mutex); + mutex_lock(&pctldev->mutex); /* TODO: check that no pinmuxes are still active? */ list_del(&pctldev->node); /* Destroy descriptor tree */ -- cgit v0.10.2 From 41f632fe177bc4822c2e8236fe7c291e6e9eb6f8 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 12 Jan 2015 17:20:51 +0100 Subject: pinctrl: lantiq: remove bogus of_gpio_chip_add Remove bogus call to of_gpiochip_add (and of_gpio_chip remove in error path) which is also called when adding the gpio chip. This prevents adding the same pinctrl range twice. Fixes: 3f8c50c9b110 ("OF: pinctrl: MIPS: lantiq: implement lantiq/xway pinctrl support") Signed-off-by: Johan Hovold Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index c5cef59..779950c 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c @@ -798,10 +798,8 @@ static int pinmux_xway_probe(struct platform_device *pdev) /* load the gpio chip */ xway_chip.dev = &pdev->dev; - of_gpiochip_add(&xway_chip); ret = gpiochip_add(&xway_chip); if (ret) { - of_gpiochip_remove(&xway_chip); dev_err(&pdev->dev, "Failed to register gpio chip\n"); return ret; } -- cgit v0.10.2 From 5539b3c938d64a60cb1fc442ac3ce9263d52de0c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 12 Jan 2015 17:12:24 +0100 Subject: gpio: fix memory and reference leaks in gpiochip_add error path Memory allocated and references taken by of_gpiochip_add and acpi_gpiochip_add were never released on errors in gpiochip_add (e.g. failure to find free gpio range). Fixes: 391c970c0dd1 ("of/gpio: add default of_xlate function if device has a node pointer") Fixes: 664e3e5ac64c ("gpio / ACPI: register to ACPI events automatically") Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 487afe6..89c59f5 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -277,6 +277,9 @@ int gpiochip_add(struct gpio_chip *chip) spin_unlock_irqrestore(&gpio_lock, flags); + if (status) + goto fail; + #ifdef CONFIG_PINCTRL INIT_LIST_HEAD(&chip->pin_ranges); #endif @@ -284,12 +287,12 @@ int gpiochip_add(struct gpio_chip *chip) of_gpiochip_add(chip); acpi_gpiochip_add(chip); - if (status) - goto fail; - status = gpiochip_export(chip); - if (status) + if (status) { + acpi_gpiochip_remove(chip); + of_gpiochip_remove(chip); goto fail; + } pr_debug("%s: registered GPIOs %d to %d on device: %s\n", __func__, chip->base, chip->base + chip->ngpio - 1, -- cgit v0.10.2 From 225fce83cb72e1bffb712a33ce47c210c770f8ab Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 12 Jan 2015 17:12:25 +0100 Subject: gpio: fix gpio-chip list corruption Fix potential corruption of gpio-chip list due to failure to remove the chip from the list before returning in gpiochip_add error path. The chip could be long gone when the global list is next traversed, something which could lead to a null-pointer dereference. In the best case (chip not deallocated) we are just leaking the gpio range. Fixes: 14e85c0e69d5 ("gpio: remove gpio_descs global array") Signed-off-by: Johan Hovold Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 89c59f5..ac5944b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -248,7 +248,8 @@ int gpiochip_add(struct gpio_chip *chip) base = gpiochip_find_base(chip->ngpio); if (base < 0) { status = base; - goto unlock; + spin_unlock_irqrestore(&gpio_lock, flags); + goto err_free_descs; } chip->base = base; } @@ -288,11 +289,8 @@ int gpiochip_add(struct gpio_chip *chip) acpi_gpiochip_add(chip); status = gpiochip_export(chip); - if (status) { - acpi_gpiochip_remove(chip); - of_gpiochip_remove(chip); - goto fail; - } + if (status) + goto err_remove_chip; pr_debug("%s: registered GPIOs %d to %d on device: %s\n", __func__, chip->base, chip->base + chip->ngpio - 1, @@ -300,9 +298,14 @@ int gpiochip_add(struct gpio_chip *chip) return 0; -unlock: +err_remove_chip: + acpi_gpiochip_remove(chip); + of_gpiochip_remove(chip); + spin_lock_irqsave(&gpio_lock, flags); + list_del(&chip->list); spin_unlock_irqrestore(&gpio_lock, flags); fail: +err_free_descs: kfree(descs); chip->desc = NULL; -- cgit v0.10.2 From 05aa52033494a13178fb550660aea87cd8a99cfd Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 12 Jan 2015 17:12:26 +0100 Subject: gpio: clean up gpiochip_add error handling Clean up gpiochip_add error handling. Signed-off-by: Johan Hovold Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index ac5944b..4efb92c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -255,32 +255,29 @@ int gpiochip_add(struct gpio_chip *chip) } status = gpiochip_add_to_list(chip); + if (status) { + spin_unlock_irqrestore(&gpio_lock, flags); + goto err_free_descs; + } - if (status == 0) { - for (id = 0; id < chip->ngpio; id++) { - struct gpio_desc *desc = &descs[id]; - desc->chip = chip; - - /* REVISIT: most hardware initializes GPIOs as - * inputs (often with pullups enabled) so power - * usage is minimized. Linux code should set the - * gpio direction first thing; but until it does, - * and in case chip->get_direction is not set, - * we may expose the wrong direction in sysfs. - */ - desc->flags = !chip->direction_input - ? (1 << FLAG_IS_OUT) - : 0; - } + for (id = 0; id < chip->ngpio; id++) { + struct gpio_desc *desc = &descs[id]; + + desc->chip = chip; + + /* REVISIT: most hardware initializes GPIOs as inputs (often + * with pullups enabled) so power usage is minimized. Linux + * code should set the gpio direction first thing; but until + * it does, and in case chip->get_direction is not set, we may + * expose the wrong direction in sysfs. + */ + desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0; } chip->desc = descs; spin_unlock_irqrestore(&gpio_lock, flags); - if (status) - goto fail; - #ifdef CONFIG_PINCTRL INIT_LIST_HEAD(&chip->pin_ranges); #endif @@ -304,10 +301,9 @@ err_remove_chip: spin_lock_irqsave(&gpio_lock, flags); list_del(&chip->list); spin_unlock_irqrestore(&gpio_lock, flags); -fail: + chip->desc = NULL; err_free_descs: kfree(descs); - chip->desc = NULL; /* failures here can mean systems won't boot... */ pr_err("%s: GPIOs %d..%d (%s) failed to register\n", __func__, -- cgit v0.10.2 From 00acc3dc248063f982cfacfbe5e78c0d6797ffef Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 12 Jan 2015 17:12:27 +0100 Subject: gpio: fix memory leak and sleep-while-atomic Fix memory leak and sleep-while-atomic in gpiochip_remove. The memory leak was introduced by afa82fab5e13 ("gpio / ACPI: Move event handling registration to gpiolib irqchip helpers") that moved the release of acpi interrupt resources to gpiochip_irqchip_remove, but by then the resources are no longer accessible as the acpi_gpio_chip has already been freed by acpi_gpiochip_remove. Note that this also fixes a few potential sleep-while-atomics, which has been around since 1425052097b5 ("gpio: add IRQ chip helpers in gpiolib") when the call to gpiochip_irqchip_remove while holding a spinlock was added (a couple of irq-domain paths can end up grabbing mutexes). Fixes: afa82fab5e13 ("gpio / ACPI: Move event handling registration to gpiolib irqchip helpers") Fixes: 1425052097b5 ("gpio: add IRQ chip helpers in gpiolib") Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 4efb92c..0f81730 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -327,11 +327,12 @@ void gpiochip_remove(struct gpio_chip *chip) unsigned long flags; unsigned id; + gpiochip_irqchip_remove(chip); + acpi_gpiochip_remove(chip); spin_lock_irqsave(&gpio_lock, flags); - gpiochip_irqchip_remove(chip); gpiochip_remove_pin_ranges(chip); of_gpiochip_remove(chip); -- cgit v0.10.2 From 6798acaa0138d8b12f1c54402ebcb66fea3deb03 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 12 Jan 2015 17:12:28 +0100 Subject: gpio: fix sleep-while-atomic in gpiochip_remove Move direct and indirect calls to gpiochip_remove_pin_ranges outside of spin lock as they can end up taking a mutex in pinctrl_remove_gpio_range. Note that the pin ranges are already added outside of the lock. Fixes: 9ef0d6f7628b ("gpiolib: call pin removal in chip removal function") Fixes: f23f1516b675 ("gpiolib: provide provision to register pin ranges") Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 0f81730..37f919d 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -330,12 +330,10 @@ void gpiochip_remove(struct gpio_chip *chip) gpiochip_irqchip_remove(chip); acpi_gpiochip_remove(chip); - - spin_lock_irqsave(&gpio_lock, flags); - gpiochip_remove_pin_ranges(chip); of_gpiochip_remove(chip); + spin_lock_irqsave(&gpio_lock, flags); for (id = 0; id < chip->ngpio; id++) { if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) dev_crit(chip->dev, "REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n"); -- cgit v0.10.2 From 01cca93a9491ed95992523ff7e79dd9bfcdea8e0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 12 Jan 2015 17:12:29 +0100 Subject: gpio: unregister gpiochip device before removing it Unregister gpiochip device (used to export information through sysfs) before removing it internally. This way removal will reverse addition. Signed-off-by: Johan Hovold Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 37f919d..568aa2b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -327,6 +327,8 @@ void gpiochip_remove(struct gpio_chip *chip) unsigned long flags; unsigned id; + gpiochip_unexport(chip); + gpiochip_irqchip_remove(chip); acpi_gpiochip_remove(chip); @@ -343,7 +345,6 @@ void gpiochip_remove(struct gpio_chip *chip) list_del(&chip->list); spin_unlock_irqrestore(&gpio_lock, flags); - gpiochip_unexport(chip); kfree(chip->desc); chip->desc = NULL; -- cgit v0.10.2 From ec512fb8e5611fed1df2895f90317ce6797d6b32 Mon Sep 17 00:00:00 2001 From: Amit Virdi Date: Tue, 13 Jan 2015 14:27:20 +0530 Subject: usb: dwc3: gadget: Fix TRB preparation during SG When scatter gather (SG) is used, multiple TRBs are prepared from one DWC3 request (dwc3_request). So while preparing TRBs, the 'last' flag should be set only when it is the last TRB being prepared from the last dwc3_request entry. The current implementation uses list_is_last to check if the dwc3_request is the last entry from the request_list. However, list_is_last returns false for the last entry too. This is because, while preparing the first TRB from a request, the function dwc3_prepare_one_trb modifies the request's next and prev pointers while moving the URB to req_queued. Hence, list_is_last always returns false no matter what. The correct way is not to access the modified pointers of dwc3_request but to use list_empty macro instead. Fixes: e5ba5ec833aa (usb: dwc3: gadget: fix scatter gather implementation) Signed-off-by: Amit Virdi Cc: # v3.9+ Signed-off-by: Felipe Balbi diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f03b136..0eec2e9 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -882,8 +882,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) if (i == (request->num_mapped_sgs - 1) || sg_is_last(s)) { - if (list_is_last(&req->list, - &dep->request_list)) + if (list_empty(&dep->request_list)) last_one = true; chain = false; } -- cgit v0.10.2 From 39e60635a01520e8c8ed3946a28c2b98e6a46f79 Mon Sep 17 00:00:00 2001 From: Amit Virdi Date: Tue, 13 Jan 2015 14:27:21 +0530 Subject: usb: dwc3: gadget: Stop TRB preparation after limit is reached DWC3 gadget sets up a pool of 32 TRBs for each EP during initialization. This means, the max TRBs that can be submitted for an EP is fixed to 32. Since the request queue for an EP is a linked list, any number of requests can be queued to it by the gadget layer. However, the dwc3 driver must not submit TRBs more than the pool it has created for. This limit wasn't respected when SG was used resulting in submitting more than the max TRBs, eventually leading to non-transfer of the TRBs submitted over the max limit. Root cause: When SG is used, there are two loops iterating to prepare TRBs: - Outer loop over the request_list - Inner loop over the SG list The code was missing break to get out of the outer loop. Fixes: eeb720fb21d6 (usb: dwc3: gadget: add support for SG lists) Cc: # v3.9+ Signed-off-by: Amit Virdi Signed-off-by: Felipe Balbi diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 0eec2e9..8f65ab3 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -900,6 +900,9 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) if (last_one) break; } + + if (last_one) + break; } else { dma = req->request.dma; length = req->request.length; -- cgit v0.10.2 From 16dde0d6ac159531a5e03cd3f8bc8a401d9f3fb6 Mon Sep 17 00:00:00 2001 From: Sriharsha Basavapatna Date: Thu, 15 Jan 2015 16:08:43 +0530 Subject: be2net: Allow GRE to work concurrently while a VxLAN tunnel is configured Other tunnels like GRE break while VxLAN offloads are enabled in Skyhawk-R. To avoid this, we should restrict offload features on a per-packet basis in such conditions. Signed-off-by: Sriharsha Basavapatna Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 41a0a54..d48806b 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -4383,8 +4383,9 @@ static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, * distinguish various types of transports (VxLAN, GRE, NVGRE ..). So, offload * is expected to work across all types of IP tunnels once exported. Skyhawk * supports offloads for either VxLAN or NVGRE, exclusively. So we export VxLAN - * offloads in hw_enc_features only when a VxLAN port is added. Note this only - * ensures that other tunnels work fine while VxLAN offloads are not enabled. + * offloads in hw_enc_features only when a VxLAN port is added. If other (non + * VxLAN) tunnels are configured while VxLAN offloads are enabled, offloads for + * those other tunnels are unexported on the fly through ndo_features_check(). * * Skyhawk supports VxLAN offloads only for one UDP dport. So, if the stack * adds more than one port, disable offloads and don't re-enable them again @@ -4463,7 +4464,41 @@ static netdev_features_t be_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) { - return vxlan_features_check(skb, features); + struct be_adapter *adapter = netdev_priv(dev); + u8 l4_hdr = 0; + + /* The code below restricts offload features for some tunneled packets. + * Offload features for normal (non tunnel) packets are unchanged. + */ + if (!skb->encapsulation || + !(adapter->flags & BE_FLAGS_VXLAN_OFFLOADS)) + return features; + + /* It's an encapsulated packet and VxLAN offloads are enabled. We + * should disable tunnel offload features if it's not a VxLAN packet, + * as tunnel offloads have been enabled only for VxLAN. This is done to + * allow other tunneled traffic like GRE work fine while VxLAN + * offloads are configured in Skyhawk-R. + */ + switch (vlan_get_protocol(skb)) { + case htons(ETH_P_IP): + l4_hdr = ip_hdr(skb)->protocol; + break; + case htons(ETH_P_IPV6): + l4_hdr = ipv6_hdr(skb)->nexthdr; + break; + default: + return features; + } + + if (l4_hdr != IPPROTO_UDP || + 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)) + return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); + + return features; } #endif -- cgit v0.10.2 From 5a80244246d503df688341a10e1d244d15bb8ce5 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 14 Jan 2015 11:25:07 +0100 Subject: s390/bpf: Fix JMP_JGE_K (A >= K) and JMP_JGT_K (A > K) Currently the signed COMPARE HALFWORD IMMEDIATE (chi) and COMPARE (c) instructions are used to compare "A" with "K". This is not correct because "A" and "K" are both unsigned. To fix this remove the chi instruction (no unsigned analogon available) and use the unsigned COMPARE LOGICAL (cl) instruction instead of COMPARE (c). Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 524496d..bbd1981 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -448,15 +448,12 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter, mask = 0x800000; /* je */ kbranch: /* Emit compare if the branch targets are different */ if (filter->jt != filter->jf) { - if (K <= 16383) - /* chi %r5, */ - EMIT4_IMM(0xa75e0000, K); - else if (test_facility(21)) + if (test_facility(21)) /* clfi %r5, */ EMIT6_IMM(0xc25f0000, K); else - /* c %r5,(%r13) */ - EMIT4_DISP(0x5950d000, EMIT_CONST(K)); + /* cl %r5,(%r13) */ + EMIT4_DISP(0x5550d000, EMIT_CONST(K)); } branch: if (filter->jt == filter->jf) { if (filter->jt == 0) -- cgit v0.10.2 From db9aa8f432b83b270686e68172c6d2895babdc26 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Thu, 15 Jan 2015 10:20:28 +0100 Subject: s390/bpf: Fix skb_copy_bits() parameter passing The skb_copy_bits() function has the following signature: int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) Currently in bpf_jit.S the "to" and "len" parameters have been exchanged. So fix this and call the function with the correct parameters. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/net/bpf_jit.S b/arch/s390/net/bpf_jit.S index 7e45d13..d34b707 100644 --- a/arch/s390/net/bpf_jit.S +++ b/arch/s390/net/bpf_jit.S @@ -22,8 +22,8 @@ * skb_copy_bits takes 4 parameters: * %r2 = skb pointer * %r3 = offset into skb data - * %r4 = length to copy - * %r5 = pointer to temp buffer + * %r4 = pointer to temp buffer + * %r5 = length to copy */ #define SKBDATA %r8 @@ -44,8 +44,8 @@ ENTRY(sk_load_word) sk_load_word_slow: lgr %r9,%r2 # save %r2 - lhi %r4,4 # 4 bytes - la %r5,160(%r15) # pointer to temp buffer + la %r4,160(%r15) # pointer to temp buffer + lhi %r5,4 # 4 bytes brasl %r14,skb_copy_bits # get data from skb l %r5,160(%r15) # load result from temp buffer ltgr %r2,%r2 # set cc to (%r2 != 0) @@ -69,8 +69,8 @@ ENTRY(sk_load_half) sk_load_half_slow: lgr %r9,%r2 # save %r2 - lhi %r4,2 # 2 bytes - la %r5,162(%r15) # pointer to temp buffer + la %r4,162(%r15) # pointer to temp buffer + lhi %r5,2 # 2 bytes brasl %r14,skb_copy_bits # get data from skb xc 160(2,%r15),160(%r15) l %r5,160(%r15) # load result from temp buffer @@ -95,8 +95,8 @@ ENTRY(sk_load_byte) sk_load_byte_slow: lgr %r9,%r2 # save %r2 - lhi %r4,1 # 1 bytes - la %r5,163(%r15) # pointer to temp buffer + la %r4,163(%r15) # pointer to temp buffer + lhi %r5,1 # 1 bytes brasl %r14,skb_copy_bits # get data from skb xc 160(3,%r15),160(%r15) l %r5,160(%r15) # load result from temp buffer @@ -118,8 +118,8 @@ ENTRY(sk_load_byte_msh) sk_load_byte_msh_slow: lgr %r9,%r2 # save %r2 - lhi %r4,2 # 2 bytes - la %r5,162(%r15) # pointer to temp buffer + la %r4,162(%r15) # pointer to temp buffer + lhi %r5,2 # 2 bytes brasl %r14,skb_copy_bits # get data from skb xc 160(3,%r15),160(%r15) l %r12,160(%r15) # load result from temp buffer -- cgit v0.10.2 From d86eb7448e6de97b1319ea935f77b65590dbc049 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Thu, 15 Jan 2015 10:21:20 +0100 Subject: s390/bpf: Fix offset parameter for skb_copy_bits() Currently the offset parameter for skb_copy_bits is changed in sk_load_word() and sk_load_half(). Therefore it is not correct when calling skb_copy_bits(). Fix this and use the original offset for the function call. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/net/bpf_jit.S b/arch/s390/net/bpf_jit.S index d34b707..ede6108 100644 --- a/arch/s390/net/bpf_jit.S +++ b/arch/s390/net/bpf_jit.S @@ -44,6 +44,7 @@ ENTRY(sk_load_word) sk_load_word_slow: lgr %r9,%r2 # save %r2 + lgr %r3,%r1 # offset la %r4,160(%r15) # pointer to temp buffer lhi %r5,4 # 4 bytes brasl %r14,skb_copy_bits # get data from skb @@ -69,6 +70,7 @@ ENTRY(sk_load_half) sk_load_half_slow: lgr %r9,%r2 # save %r2 + lgr %r3,%r1 # offset la %r4,162(%r15) # pointer to temp buffer lhi %r5,2 # 2 bytes brasl %r14,skb_copy_bits # get data from skb -- cgit v0.10.2 From 1a92b2deaf5c1b71f995ef571076200a391aac66 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Thu, 15 Jan 2015 10:21:58 +0100 Subject: s390/bpf: Fix sk_load_byte_msh() In sk_load_byte_msh() sk_load_byte_slow() is called instead of sk_load_byte_msh_slow(). Fix this and call the correct function. Besides of this load only one byte instead of two and fix the comment. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/net/bpf_jit.S b/arch/s390/net/bpf_jit.S index ede6108..e2f2111 100644 --- a/arch/s390/net/bpf_jit.S +++ b/arch/s390/net/bpf_jit.S @@ -106,11 +106,11 @@ sk_load_byte_slow: lgr %r2,%r9 # restore %r2 br %r8 - /* A = (*(u8 *)(skb->data+K) & 0xf) << 2 */ + /* X = (*(u8 *)(skb->data+K) & 0xf) << 2 */ ENTRY(sk_load_byte_msh) llgfr %r1,%r3 # extend offset clr %r11,%r3 # hlen < offset ? - jle sk_load_byte_slow + jle sk_load_byte_msh_slow lhi %r12,0 ic %r12,0(%r1,%r10) # get byte from skb nill %r12,0x0f @@ -120,8 +120,8 @@ ENTRY(sk_load_byte_msh) sk_load_byte_msh_slow: lgr %r9,%r2 # save %r2 - la %r4,162(%r15) # pointer to temp buffer - lhi %r5,2 # 2 bytes + la %r4,163(%r15) # pointer to temp buffer + lhi %r5,1 # 1 bytes brasl %r14,skb_copy_bits # get data from skb xc 160(3,%r15),160(%r15) l %r12,160(%r15) # load result from temp buffer -- cgit v0.10.2 From fe82bbae36943fbead5e326aab1665d001a87dd7 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Thu, 15 Jan 2015 10:23:46 +0100 Subject: s390/bpf: Zero extend parameters before calling C function The s390x ABI requires to zero extend parameters before functions are called. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/net/bpf_jit.S b/arch/s390/net/bpf_jit.S index e2f2111..ba44c9f 100644 --- a/arch/s390/net/bpf_jit.S +++ b/arch/s390/net/bpf_jit.S @@ -46,7 +46,7 @@ sk_load_word_slow: lgr %r9,%r2 # save %r2 lgr %r3,%r1 # offset la %r4,160(%r15) # pointer to temp buffer - lhi %r5,4 # 4 bytes + lghi %r5,4 # 4 bytes brasl %r14,skb_copy_bits # get data from skb l %r5,160(%r15) # load result from temp buffer ltgr %r2,%r2 # set cc to (%r2 != 0) @@ -72,7 +72,7 @@ sk_load_half_slow: lgr %r9,%r2 # save %r2 lgr %r3,%r1 # offset la %r4,162(%r15) # pointer to temp buffer - lhi %r5,2 # 2 bytes + lghi %r5,2 # 2 bytes brasl %r14,skb_copy_bits # get data from skb xc 160(2,%r15),160(%r15) l %r5,160(%r15) # load result from temp buffer @@ -97,8 +97,9 @@ ENTRY(sk_load_byte) sk_load_byte_slow: lgr %r9,%r2 # save %r2 + lgr %r3,%r1 # offset la %r4,163(%r15) # pointer to temp buffer - lhi %r5,1 # 1 bytes + lghi %r5,1 # 1 byte brasl %r14,skb_copy_bits # get data from skb xc 160(3,%r15),160(%r15) l %r5,160(%r15) # load result from temp buffer @@ -120,8 +121,9 @@ ENTRY(sk_load_byte_msh) sk_load_byte_msh_slow: lgr %r9,%r2 # save %r2 + lgr %r3,%r1 # offset la %r4,163(%r15) # pointer to temp buffer - lhi %r5,1 # 1 bytes + lghi %r5,1 # 1 byte brasl %r14,skb_copy_bits # get data from skb xc 160(3,%r15),160(%r15) l %r12,160(%r15) # load result from temp buffer -- cgit v0.10.2 From 8f86f83709c585742dea5dd7f0d2b79c43f992ec Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Tue, 13 Jan 2015 11:20:43 -0500 Subject: ftrace: Fix updating of filters for shared global_ops filters As the set_ftrace_filter affects both the function tracer as well as the function graph tracer, the ops that represent each have a shared ftrace_ops_hash structure. This allows both to be updated when the filter files are updated. But if function graph is enabled and the global_ops (function tracing) ops is not, then it is possible that the filter could be changed without the update happening for the function graph ops. This will cause the changes to not take place and may even cause a ftrace_bug to occur as it could mess with the trampoline accounting. The solution is to check if the ops uses the shared global_ops filter and if the ops itself is not enabled, to check if there's another ops that is enabled and also shares the global_ops filter. In that case, the modification still needs to be executed. Link: http://lkml.kernel.org/r/20150114154329.055980438@goodmis.org Cc: stable@vger.kernel.org # 3.17+ Reviewed-by: Masami Hiramatsu Signed-off-by: Steven Rostedt diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 929a733d..2b35d0b 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -4008,8 +4008,32 @@ ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove) static void ftrace_ops_update_code(struct ftrace_ops *ops, struct ftrace_hash *old_hash) { - if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled) + struct ftrace_ops *op; + + if (!ftrace_enabled) + return; + + if (ops->flags & FTRACE_OPS_FL_ENABLED) { ftrace_run_modify_code(ops, FTRACE_UPDATE_CALLS, old_hash); + return; + } + + /* + * If this is the shared global_ops filter, then we need to + * check if there is another ops that shares it, is enabled. + * If so, we still need to run the modify code. + */ + if (ops->func_hash != &global_ops.local_hash) + return; + + do_for_each_ftrace_op(op, ftrace_ops_list) { + if (op->func_hash == &global_ops.local_hash && + op->flags & FTRACE_OPS_FL_ENABLED) { + ftrace_run_modify_code(op, FTRACE_UPDATE_CALLS, old_hash); + /* Only need to do this once */ + return; + } + } while_for_each_ftrace_op(op); } static int -- cgit v0.10.2 From 7485058eea40783ac142a60c3e799fc66ce72583 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Tue, 13 Jan 2015 14:03:38 -0500 Subject: ftrace: Check both notrace and filter for old hash Using just the filter for checking for trampolines or regs is not enough when updating the code against the records that represent all functions. Both the filter hash and the notrace hash need to be checked. To trigger this bug (using trace-cmd and perf): # perf probe -a do_fork # trace-cmd start -B foo -e probe # trace-cmd record -p function_graph -n do_fork sleep 1 The trace-cmd record at the end clears the filter before it disables function_graph tracing and then that causes the accounting of the ftrace function records to become incorrect and causes ftrace to bug. Link: http://lkml.kernel.org/r/20150114154329.358378039@goodmis.org Cc: stable@vger.kernel.org [ still need to switch old_hash_ops to old_ops_hash ] Reviewed-by: Masami Hiramatsu Signed-off-by: Steven Rostedt diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 2b35d0b..224e768 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2497,12 +2497,14 @@ static void ftrace_run_update_code(int command) } static void ftrace_run_modify_code(struct ftrace_ops *ops, int command, - struct ftrace_hash *old_hash) + struct ftrace_ops_hash *old_hash) { ops->flags |= FTRACE_OPS_FL_MODIFYING; - ops->old_hash.filter_hash = old_hash; + ops->old_hash.filter_hash = old_hash->filter_hash; + ops->old_hash.notrace_hash = old_hash->notrace_hash; ftrace_run_update_code(command); ops->old_hash.filter_hash = NULL; + ops->old_hash.notrace_hash = NULL; ops->flags &= ~FTRACE_OPS_FL_MODIFYING; } @@ -3579,7 +3581,7 @@ static struct ftrace_ops trace_probe_ops __read_mostly = static int ftrace_probe_registered; -static void __enable_ftrace_function_probe(struct ftrace_hash *old_hash) +static void __enable_ftrace_function_probe(struct ftrace_ops_hash *old_hash) { int ret; int i; @@ -3637,6 +3639,7 @@ int register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, void *data) { + struct ftrace_ops_hash old_hash_ops; struct ftrace_func_probe *entry; struct ftrace_hash **orig_hash = &trace_probe_ops.func_hash->filter_hash; struct ftrace_hash *old_hash = *orig_hash; @@ -3658,6 +3661,10 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, mutex_lock(&trace_probe_ops.func_hash->regex_lock); + old_hash_ops.filter_hash = old_hash; + /* Probes only have filters */ + old_hash_ops.notrace_hash = NULL; + hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, old_hash); if (!hash) { count = -ENOMEM; @@ -3718,7 +3725,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); - __enable_ftrace_function_probe(old_hash); + __enable_ftrace_function_probe(&old_hash_ops); if (!ret) free_ftrace_hash_rcu(old_hash); @@ -4006,7 +4013,7 @@ ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove) } static void ftrace_ops_update_code(struct ftrace_ops *ops, - struct ftrace_hash *old_hash) + struct ftrace_ops_hash *old_hash) { struct ftrace_ops *op; @@ -4041,6 +4048,7 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len, unsigned long ip, int remove, int reset, int enable) { struct ftrace_hash **orig_hash; + struct ftrace_ops_hash old_hash_ops; struct ftrace_hash *old_hash; struct ftrace_hash *hash; int ret; @@ -4077,9 +4085,11 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len, mutex_lock(&ftrace_lock); old_hash = *orig_hash; + old_hash_ops.filter_hash = ops->func_hash->filter_hash; + old_hash_ops.notrace_hash = ops->func_hash->notrace_hash; ret = ftrace_hash_move(ops, enable, orig_hash, hash); if (!ret) { - ftrace_ops_update_code(ops, old_hash); + ftrace_ops_update_code(ops, &old_hash_ops); free_ftrace_hash_rcu(old_hash); } mutex_unlock(&ftrace_lock); @@ -4291,6 +4301,7 @@ static void __init set_ftrace_early_filters(void) int ftrace_regex_release(struct inode *inode, struct file *file) { struct seq_file *m = (struct seq_file *)file->private_data; + struct ftrace_ops_hash old_hash_ops; struct ftrace_iterator *iter; struct ftrace_hash **orig_hash; struct ftrace_hash *old_hash; @@ -4324,10 +4335,12 @@ int ftrace_regex_release(struct inode *inode, struct file *file) mutex_lock(&ftrace_lock); old_hash = *orig_hash; + old_hash_ops.filter_hash = iter->ops->func_hash->filter_hash; + old_hash_ops.notrace_hash = iter->ops->func_hash->notrace_hash; ret = ftrace_hash_move(iter->ops, filter_hash, orig_hash, iter->hash); if (!ret) { - ftrace_ops_update_code(iter->ops, old_hash); + ftrace_ops_update_code(iter->ops, &old_hash_ops); free_ftrace_hash_rcu(old_hash); } mutex_unlock(&ftrace_lock); -- cgit v0.10.2 From 237d28db036e411f22c03cfd5b0f6dc2aa9bf3bc Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Mon, 12 Jan 2015 12:12:03 -0500 Subject: ftrace/jprobes/x86: Fix conflict between jprobes and function graph tracing If the function graph tracer traces a jprobe callback, the system will crash. This can easily be demonstrated by compiling the jprobe sample module that is in the kernel tree, loading it and running the function graph tracer. # modprobe jprobe_example.ko # echo function_graph > /sys/kernel/debug/tracing/current_tracer # ls The first two commands end up in a nice crash after the first fork. (do_fork has a jprobe attached to it, so "ls" just triggers that fork) The problem is caused by the jprobe_return() that all jprobe callbacks must end with. The way jprobes works is that the function a jprobe is attached to has a breakpoint placed at the start of it (or it uses ftrace if fentry is supported). The breakpoint handler (or ftrace callback) will copy the stack frame and change the ip address to return to the jprobe handler instead of the function. The jprobe handler must end with jprobe_return() which swaps the stack and does an int3 (breakpoint). This breakpoint handler will then put back the saved stack frame, simulate the instruction at the beginning of the function it added a breakpoint to, and then continue on. For function tracing to work, it hijakes the return address from the stack frame, and replaces it with a hook function that will trace the end of the call. This hook function will restore the return address of the function call. If the function tracer traces the jprobe handler, the hook function for that handler will not be called, and its saved return address will be used for the next function. This will result in a kernel crash. To solve this, pause function tracing before the jprobe handler is called and unpause it before it returns back to the function it probed. Some other updates: Used a variable "saved_sp" to hold kcb->jprobe_saved_sp. This makes the code look a bit cleaner and easier to understand (various tries to fix this bug required this change). Note, if fentry is being used, jprobes will change the ip address before the function graph tracer runs and it will not be able to trace the function that the jprobe is probing. Link: http://lkml.kernel.org/r/20150114154329.552437962@goodmis.org Cc: stable@vger.kernel.org # 2.6.30+ Acked-by: Masami Hiramatsu Signed-off-by: Steven Rostedt diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index f7e3cd5..98f654d 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -1020,6 +1020,15 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) regs->flags &= ~X86_EFLAGS_IF; trace_hardirqs_off(); regs->ip = (unsigned long)(jp->entry); + + /* + * jprobes use jprobe_return() which skips the normal return + * path of the function, and this messes up the accounting of the + * function graph tracer to get messed up. + * + * Pause function graph tracing while performing the jprobe function. + */ + pause_graph_tracing(); return 1; } NOKPROBE_SYMBOL(setjmp_pre_handler); @@ -1048,24 +1057,25 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); u8 *addr = (u8 *) (regs->ip - 1); struct jprobe *jp = container_of(p, struct jprobe, kp); + void *saved_sp = kcb->jprobe_saved_sp; if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { - if (stack_addr(regs) != kcb->jprobe_saved_sp) { + if (stack_addr(regs) != saved_sp) { struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; printk(KERN_ERR "current sp %p does not match saved sp %p\n", - stack_addr(regs), kcb->jprobe_saved_sp); + stack_addr(regs), saved_sp); printk(KERN_ERR "Saved registers for jprobe %p\n", jp); show_regs(saved_regs); printk(KERN_ERR "Current registers\n"); show_regs(regs); BUG(); } + /* It's OK to start function graph tracing again */ + unpause_graph_tracing(); *regs = kcb->jprobe_saved_regs; - memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp), - kcb->jprobes_stack, - MIN_STACK_SIZE(kcb->jprobe_saved_sp)); + memcpy(saved_sp, kcb->jprobes_stack, MIN_STACK_SIZE(saved_sp)); preempt_enable_no_resched(); return 1; } -- cgit v0.10.2 From 83829b74f54186a154ae6b586c05cdb838c2ebc6 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 14 Jan 2015 12:24:37 -0500 Subject: tracing: Remove extra call to init_ftrace_syscalls() trace_init() calls init_ftrace_syscalls() and then calls trace_event_init() which also calls init_ftrace_syscalls(). It makes more sense to only call it from trace_event_init(). Calling it twice wastes memory, as it allocates the syscall events twice, and loses the first copy of it. Link: http://lkml.kernel.org/r/54AF53BD.5070303@huawei.com Link: http://lkml.kernel.org/r/20150115040505.930398632@goodmis.org Reported-by: Wang Nan Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2e76797..4a9079b 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6918,7 +6918,6 @@ void __init trace_init(void) tracepoint_printk = 0; } tracer_alloc_buffers(); - init_ftrace_syscalls(); trace_event_init(); } -- cgit v0.10.2 From ce1039bd3a89e99e4f624e75fb1777fc92d76eb3 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 14 Jan 2015 12:53:45 -0500 Subject: tracing: Fix enabling of syscall events on the command line Commit 5f893b2639b2 "tracing: Move enabling tracepoints to just after rcu_init()" broke the enabling of system call events from the command line. The reason was that the enabling of command line trace events was moved before PID 1 started, and the syscall tracepoints require that all tasks have the TIF_SYSCALL_TRACEPOINT flag set. But the swapper task (pid 0) is not part of that. Since the swapper task is the only task that is running at this early in boot, no task gets the flag set, and the tracepoint never gets reached. Instead of setting the swapper task flag (there should be no reason to do that), re-enabled trace events again after the init thread (PID 1) has been started. It requires disabling all command line events and re-enabling them, as just enabling them again will not reset the logic to set the TIF_SYSCALL_TRACEPOINT flag, as the syscall tracepoint will be fooled into thinking that it was already set, and wont try setting it again. For this reason, we must first disable it and re-enable it. Link: http://lkml.kernel.org/r/1421188517-18312-1-git-send-email-mpe@ellerman.id.au Link: http://lkml.kernel.org/r/20150115040506.216066449@goodmis.org Reported-by: Michael Ellerman Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 366a78a..b03a0ea 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2429,12 +2429,39 @@ static __init int event_trace_memsetup(void) return 0; } +static __init void +early_enable_events(struct trace_array *tr, bool disable_first) +{ + char *buf = bootup_event_buf; + char *token; + int ret; + + while (true) { + token = strsep(&buf, ","); + + if (!token) + break; + if (!*token) + continue; + + /* Restarting syscalls requires that we stop them first */ + if (disable_first) + ftrace_set_clr_event(tr, token, 0); + + ret = ftrace_set_clr_event(tr, token, 1); + if (ret) + pr_warn("Failed to enable trace event: %s\n", token); + + /* Put back the comma to allow this to be called again */ + if (buf) + *(buf - 1) = ','; + } +} + static __init int event_trace_enable(void) { struct trace_array *tr = top_trace_array(); struct ftrace_event_call **iter, *call; - char *buf = bootup_event_buf; - char *token; int ret; if (!tr) @@ -2456,18 +2483,7 @@ static __init int event_trace_enable(void) */ __trace_early_add_events(tr); - while (true) { - token = strsep(&buf, ","); - - if (!token) - break; - if (!*token) - continue; - - ret = ftrace_set_clr_event(tr, token, 1); - if (ret) - pr_warn("Failed to enable trace event: %s\n", token); - } + early_enable_events(tr, false); trace_printk_start_comm(); @@ -2478,6 +2494,31 @@ static __init int event_trace_enable(void) return 0; } +/* + * event_trace_enable() is called from trace_event_init() first to + * initialize events and perhaps start any events that are on the + * command line. Unfortunately, there are some events that will not + * start this early, like the system call tracepoints that need + * to set the TIF_SYSCALL_TRACEPOINT flag of pid 1. But event_trace_enable() + * is called before pid 1 starts, and this flag is never set, making + * the syscall tracepoint never get reached, but the event is enabled + * regardless (and not doing anything). + */ +static __init int event_trace_enable_again(void) +{ + struct trace_array *tr; + + tr = top_trace_array(); + if (!tr) + return -ENODEV; + + early_enable_events(tr, true); + + return 0; +} + +early_initcall(event_trace_enable_again); + static __init int event_trace_init(void) { struct trace_array *tr; -- cgit v0.10.2 From 870482a4190007bb8aed45c6ebcbfc03369241d2 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 15 Jan 2015 16:56:26 +0100 Subject: MAINTAINERS: update linux-can git repositories The linux-can upstream git repositories are now hosted on kernel.org, update MAINTAINERS accordingly. Signed-off-by: Marc Kleine-Budde diff --git a/MAINTAINERS b/MAINTAINERS index 600d2aa..efa5f8d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2346,7 +2346,8 @@ CAN NETWORK LAYER M: Oliver Hartkopp L: linux-can@vger.kernel.org W: http://gitorious.org/linux-can -T: git git://gitorious.org/linux-can/linux-can-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git S: Maintained F: Documentation/networking/can.txt F: net/can/ @@ -2361,7 +2362,8 @@ M: Wolfgang Grandegger M: Marc Kleine-Budde L: linux-can@vger.kernel.org W: http://gitorious.org/linux-can -T: git git://gitorious.org/linux-can/linux-can-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git S: Maintained F: drivers/net/can/ F: include/linux/can/dev.h -- cgit v0.10.2 From 9b1087aa5e86448fe6ad40a58964e35f3ba423d5 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Mon, 5 Jan 2015 18:40:15 +0100 Subject: can: dev: fix crtlmode_supported check When changing flags in the CAN drivers ctrlmode the provided new content has to be checked whether the bits are allowed to be changed. The bits that are to be changed are given as a bitfield in cm->mask. Therefore checking against cm->flags is wrong as the content can hold any kind of values. The iproute2 tool sets the bits in cm->mask and cm->flags depending on the detected command line options. To be robust against bogus user space applications additionally sanitize the provided flags with the provided mask. Cc: Wolfgang Grandegger Signed-off-by: Oliver Hartkopp Cc: linux-stable Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 3ec8f6f..847c1f8 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -807,10 +807,14 @@ static int can_changelink(struct net_device *dev, if (dev->flags & IFF_UP) return -EBUSY; cm = nla_data(data[IFLA_CAN_CTRLMODE]); - if (cm->flags & ~priv->ctrlmode_supported) + + /* check whether changed bits are allowed to be modified */ + if (cm->mask & ~priv->ctrlmode_supported) return -EOPNOTSUPP; + + /* clear bits to be modified and copy the flag values */ priv->ctrlmode &= ~cm->mask; - priv->ctrlmode |= cm->flags; + priv->ctrlmode |= (cm->flags & cm->mask); /* CAN_CTRLMODE_FD can only be set when driver supports FD */ if (priv->ctrlmode & CAN_CTRLMODE_FD) -- cgit v0.10.2 From 6cfda7fbebe8a4fd33ea5722fa0212f98f643c35 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Mon, 5 Jan 2015 19:47:43 +0100 Subject: can: m_can: tag current CAN FD controllers as non-ISO During the CAN FD standardization process within the ISO it turned out that the failure detection capability has to be improved. The CAN in Automation organization (CiA) defined the already implemented CAN FD controllers as 'non-ISO' and the upcoming improved CAN FD controllers as 'ISO' compliant. See at http://www.can-cia.com/index.php?id=1937 Finally there will be three types of CAN FD controllers in the future: 1. ISO compliant (fixed) 2. non-ISO compliant (fixed, like the M_CAN IP v3.0.1 in m_can.c) 3. ISO/non-ISO CAN FD controllers (switchable, like the PEAK USB FD) So the current M_CAN driver for the M_CAN IP v3.0.1 has to expose its non-ISO implementation by setting the CAN_CTRLMODE_FD_NON_ISO ctrlmode at startup. As this bit cannot be switched at configuration time CAN_CTRLMODE_FD_NON_ISO must not be set in ctrlmode_supported of the current M_CAN driver. Signed-off-by: Oliver Hartkopp Cc: linux-stable Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index d7bc462..2445298 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -955,6 +955,11 @@ static struct net_device *alloc_m_can_dev(void) priv->can.data_bittiming_const = &m_can_data_bittiming_const; priv->can.do_set_mode = m_can_set_mode; priv->can.do_get_berr_counter = m_can_get_berr_counter; + + /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.1 */ + priv->can.ctrlmode = CAN_CTRLMODE_FD_NON_ISO; + + /* CAN_CTRLMODE_FD_NON_ISO can not be changed with M_CAN IP v3.0.1 */ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING | diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h index 3e4323a..94ffe0c 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -98,6 +98,7 @@ struct can_ctrlmode { #define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */ #define CAN_CTRLMODE_FD 0x20 /* CAN FD mode */ #define CAN_CTRLMODE_PRESUME_ACK 0x40 /* Ignore missing CAN ACKs */ +#define CAN_CTRLMODE_FD_NON_ISO 0x80 /* CAN FD in non-ISO mode */ /* * CAN device statistics -- cgit v0.10.2 From 47e3485af0a7a65547a3267021851d4ea6474d09 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 13 Jan 2015 16:23:11 +0200 Subject: can: c_can: use regmap_update_bits() to modify RAMINIT register use of regmap_read() and regmap_write() in c_can_hw_raminit_syscon() is not safe as the RAMINIT register can be shared between different drivers at least for TI SoCs. To make the modification atomic we switch to using regmap_update_bits(). regmap_update_bits() skips writing to the register if it's read content is the same as what is going to be written. This causes an issue for us when we need to clear the DONE bit with the initial condition START:0, DONE:1 as DONE bit must be written with 1 to clear it. So we defer the clearing of DONE bit to later when we set the START bit. There we are sure that START bit is changed from 0 to 1 so the write of 1 to already set DONE bit will happen. Signed-off-by: Roger Quadros Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index f363972..e36d105 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -103,27 +103,34 @@ static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable) mask = 1 << raminit->bits.start | 1 << raminit->bits.done; regmap_read(raminit->syscon, raminit->reg, &ctrl); - /* We clear the done and start bit first. The start bit is + /* We clear the start bit first. The start bit is * looking at the 0 -> transition, but is not self clearing; - * And we clear the init done bit as well. * NOTE: DONE must be written with 1 to clear it. + * We can't clear the DONE bit here using regmap_update_bits() + * as it will bypass the write if initial condition is START:0 DONE:1 + * e.g. on DRA7 which needs START pulse. */ - ctrl &= ~(1 << raminit->bits.start); - ctrl |= 1 << raminit->bits.done; - regmap_write(raminit->syscon, raminit->reg, ctrl); + ctrl &= ~mask; /* START = 0, DONE = 0 */ + regmap_update_bits(raminit->syscon, raminit->reg, mask, ctrl); - ctrl &= ~(1 << raminit->bits.done); - c_can_hw_raminit_wait_syscon(priv, mask, ctrl); + /* check if START bit is 0. Ignore DONE bit for now + * as it can be either 0 or 1. + */ + c_can_hw_raminit_wait_syscon(priv, 1 << raminit->bits.start, ctrl); if (enable) { - /* Set start bit and wait for the done bit. */ + /* Clear DONE bit & set START bit. */ ctrl |= 1 << raminit->bits.start; - regmap_write(raminit->syscon, raminit->reg, ctrl); - + /* DONE must be written with 1 to clear it */ + ctrl |= 1 << raminit->bits.done; + regmap_update_bits(raminit->syscon, raminit->reg, mask, ctrl); + /* prevent further clearing of DONE bit */ + ctrl &= ~(1 << raminit->bits.done); /* clear START bit if start pulse is needed */ if (raminit->needs_pulse) { ctrl &= ~(1 << raminit->bits.start); - regmap_write(raminit->syscon, raminit->reg, ctrl); + regmap_update_bits(raminit->syscon, raminit->reg, + mask, ctrl); } ctrl |= 1 << raminit->bits.done; -- cgit v0.10.2 From b442723fcec445fb0ae1104888dd22cd285e0a91 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 5 Jan 2015 12:49:10 -0500 Subject: can: kvaser_usb: Don't free packets when tight on URBs Flooding the Kvaser CAN to USB dongle with multiple reads and writes in high frequency caused seemingly-random panics in the kernel. On further inspection, it seems the driver erroneously freed the to-be-transmitted packet upon getting tight on URBs and returning NETDEV_TX_BUSY, leading to invalid memory writes and double frees at a later point in time. Note: Finding no more URBs/transmit-contexts and returning NETDEV_TX_BUSY is a driver bug in and out of itself: it means that our start/stop queue flow control is broken. This patch only fixes the (buggy) error handling code; the root cause shall be fixed in a later commit. Acked-by: Olivier Sobrie Signed-off-by: Ahmed S. Darwish Cc: linux-stable Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 541fb7a..2e7d513 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -1294,12 +1294,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, if (!urb) { netdev_err(netdev, "No memory left for URBs\n"); stats->tx_dropped++; - goto nourbmem; + dev_kfree_skb(skb); + return NETDEV_TX_OK; } buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC); if (!buf) { stats->tx_dropped++; + dev_kfree_skb(skb); goto nobufmem; } @@ -1334,6 +1336,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, } } + /* This should never happen; it implies a flow control bug */ if (!context) { netdev_warn(netdev, "cannot find free context\n"); ret = NETDEV_TX_BUSY; @@ -1364,9 +1367,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, if (unlikely(err)) { can_free_echo_skb(netdev, context->echo_index); - skb = NULL; /* set to NULL to avoid double free in - * dev_kfree_skb(skb) */ - atomic_dec(&priv->active_tx_urbs); usb_unanchor_urb(urb); @@ -1388,8 +1388,6 @@ releasebuf: kfree(buf); nobufmem: usb_free_urb(urb); -nourbmem: - dev_kfree_skb(skb); return ret; } -- cgit v0.10.2 From 889b77f7fd2bcc922493d73a4c51d8a851505815 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 5 Jan 2015 12:52:06 -0500 Subject: can: kvaser_usb: Reset all URB tx contexts upon channel close Flooding the Kvaser CAN to USB dongle with multiple reads and writes in very high frequency (*), closing the CAN channel while all the transmissions are on (#), opening the device again (@), then sending a small number of packets would make the driver enter an almost infinite loop of: [....] [15959.853988] kvaser_usb 4-3:1.0 can0: cannot find free context [15959.853990] kvaser_usb 4-3:1.0 can0: cannot find free context [15959.853991] kvaser_usb 4-3:1.0 can0: cannot find free context [15959.853993] kvaser_usb 4-3:1.0 can0: cannot find free context [15959.853994] kvaser_usb 4-3:1.0 can0: cannot find free context [15959.853995] kvaser_usb 4-3:1.0 can0: cannot find free context [....] _dragging the whole system down_ in the process due to the excessive logging output. Initially, this has caused random panics in the kernel due to a buggy error recovery path. That got fixed in an earlier commit.(%) This patch aims at solving the root cause. --> 16 tx URBs and contexts are allocated per CAN channel per USB device. Such URBs are protected by: a) A simple atomic counter, up to a value of MAX_TX_URBS (16) b) A flag in each URB context, stating if it's free c) The fact that ndo_start_xmit calls are themselves protected by the networking layers higher above After grabbing one of the tx URBs, if the driver noticed that all of them are now taken, it stops the netif transmission queue. Such queue is worken up again only if an acknowedgment was received from the firmware on one of our earlier-sent frames. Meanwhile, upon channel close (#), the driver sends a CMD_STOP_CHIP to the firmware, effectively closing all further communication. In the high traffic case, the atomic counter remains at MAX_TX_URBS, and all the URB contexts remain marked as active. While opening the channel again (@), it cannot send any further frames since no more free tx URB contexts are available. Reset all tx URB contexts upon CAN channel close. (*) 50 parallel instances of `cangen0 -g 0 -ix` (#) `ifconfig can0 down` (@) `ifconfig can0 up` (%) "can: kvaser_usb: Don't free packets when tight on URBs" Signed-off-by: Ahmed S. Darwish Cc: linux-stable Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 2e7d513..9accc82 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -1246,6 +1246,9 @@ static int kvaser_usb_close(struct net_device *netdev) if (err) netdev_warn(netdev, "Cannot stop device, error %d\n", err); + /* reset tx contexts */ + kvaser_usb_unlink_tx_urbs(priv); + priv->can.state = CAN_STATE_STOPPED; close_candev(priv->netdev); -- cgit v0.10.2 From 5e7e6e0c9b47a45576c38b4a72d67927a5e049f7 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 5 Jan 2015 12:57:13 -0500 Subject: can: kvaser_usb: Don't send a RESET_CHIP for non-existing channels Recent Leaf firmware versions (>= 3.1.557) do not allow to send commands for non-existing channels. If a command is sent for a non-existing channel, the firmware crashes. Reported-by: Christopher Storah Signed-off-by: Olivier Sobrie Signed-off-by: Ahmed S. Darwish Cc: linux-stable Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 9accc82..cc7bfc0 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -1503,6 +1503,10 @@ static int kvaser_usb_init_one(struct usb_interface *intf, struct kvaser_usb_net_priv *priv; int i, err; + err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, channel); + if (err) + return err; + netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); if (!netdev) { dev_err(&intf->dev, "Cannot alloc candev\n"); @@ -1607,9 +1611,6 @@ static int kvaser_usb_probe(struct usb_interface *intf, usb_set_intfdata(intf, dev); - for (i = 0; i < MAX_NET_DEVICES; i++) - kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, i); - err = kvaser_usb_get_software_info(dev); if (err) { dev_err(&intf->dev, -- cgit v0.10.2 From a58518ccf39f86f898a65201518dd8e799b3abeb Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Sun, 11 Jan 2015 15:49:52 -0500 Subject: can: kvaser_usb: Don't dereference skb after a netif_rx() We should not touch the packet after a netif_rx: it might get freed behind our back. Suggested-by: Marc Kleine-Budde Signed-off-by: Ahmed S. Darwish Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index cc7bfc0..c32cd61 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -520,10 +520,10 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, skb = alloc_can_err_skb(priv->netdev, &cf); if (skb) { cf->can_id |= CAN_ERR_RESTARTED; - netif_rx(skb); stats->rx_packets++; stats->rx_bytes += cf->can_dlc; + netif_rx(skb); } else { netdev_err(priv->netdev, "No memory left for err_skb\n"); @@ -770,10 +770,9 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, priv->can.state = new_state; - netif_rx(skb); - stats->rx_packets++; stats->rx_bytes += cf->can_dlc; + netif_rx(skb); } static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, @@ -805,10 +804,9 @@ static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, stats->rx_over_errors++; stats->rx_errors++; - netif_rx(skb); - stats->rx_packets++; stats->rx_bytes += cf->can_dlc; + netif_rx(skb); } } @@ -887,10 +885,9 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, cf->can_dlc); } - netif_rx(skb); - stats->rx_packets++; stats->rx_bytes += cf->can_dlc; + netif_rx(skb); } static void kvaser_usb_start_chip_reply(const struct kvaser_usb *dev, -- cgit v0.10.2 From d8a74e186949e1a2c2f1309212478b0659bf9225 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 15 Jan 2015 10:52:33 -0500 Subject: drm/radeon: use rv515_ring_start on r5xx This was accidently lost in 76a0df859def. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 850de57..121aff6 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -333,6 +333,20 @@ static struct radeon_asic_ring r300_gfx_ring = { .set_wptr = &r100_gfx_set_wptr, }; +static struct radeon_asic_ring rv515_gfx_ring = { + .ib_execute = &r100_ring_ib_execute, + .emit_fence = &r300_fence_ring_emit, + .emit_semaphore = &r100_semaphore_ring_emit, + .cs_parse = &r300_cs_parse, + .ring_start = &rv515_ring_start, + .ring_test = &r100_ring_test, + .ib_test = &r100_ib_test, + .is_lockup = &r100_gpu_is_lockup, + .get_rptr = &r100_gfx_get_rptr, + .get_wptr = &r100_gfx_get_wptr, + .set_wptr = &r100_gfx_set_wptr, +}; + static struct radeon_asic r300_asic = { .init = &r300_init, .fini = &r300_fini, @@ -748,7 +762,7 @@ static struct radeon_asic rv515_asic = { .set_page = &rv370_pcie_gart_set_page, }, .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = &r300_gfx_ring + [RADEON_RING_TYPE_GFX_INDEX] = &rv515_gfx_ring }, .irq = { .set = &rs600_irq_set, @@ -814,7 +828,7 @@ static struct radeon_asic r520_asic = { .set_page = &rv370_pcie_gart_set_page, }, .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = &r300_gfx_ring + [RADEON_RING_TYPE_GFX_INDEX] = &rv515_gfx_ring }, .irq = { .set = &rs600_irq_set, -- cgit v0.10.2 From 121b6a79955a3a3fd7bbb9b8cb88d5b9dad6283d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 13 Jan 2015 13:00:04 +0100 Subject: gpio: sysfs: fix gpio-chip device-attribute leak The gpio-chip device attributes were never destroyed when the device was removed. Fix by using device_create_with_groups() to create the device attributes of the chip class device. Note that this also fixes the attribute-creation race with userspace. Fixes: d8f388d8dc8d ("gpio: sysfs interface") Cc: stable # v2.6.27+ Signed-off-by: Johan Hovold Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 2ac1800..33cf4bd 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -400,16 +400,13 @@ static ssize_t chip_ngpio_show(struct device *dev, } static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL); -static const struct attribute *gpiochip_attrs[] = { +static struct attribute *gpiochip_attrs[] = { &dev_attr_base.attr, &dev_attr_label.attr, &dev_attr_ngpio.attr, NULL, }; - -static const struct attribute_group gpiochip_attr_group = { - .attrs = (struct attribute **) gpiochip_attrs, -}; +ATTRIBUTE_GROUPS(gpiochip); /* * /sys/class/gpio/export ... write-only @@ -750,13 +747,13 @@ int gpiochip_export(struct gpio_chip *chip) /* use chip->base for the ID; it's already known to be unique */ mutex_lock(&sysfs_lock); - dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip, - "gpiochip%d", chip->base); - if (!IS_ERR(dev)) { - status = sysfs_create_group(&dev->kobj, - &gpiochip_attr_group); - } else + dev = device_create_with_groups(&gpio_class, chip->dev, MKDEV(0, 0), + chip, gpiochip_groups, + "gpiochip%d", chip->base); + if (IS_ERR(dev)) status = PTR_ERR(dev); + else + status = 0; chip->exported = (status == 0); mutex_unlock(&sysfs_lock); -- cgit v0.10.2 From 0915e6feb38de8d3601819992a5bd050201a56fa Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 13 Jan 2015 13:00:05 +0100 Subject: gpio: sysfs: fix gpio device-attribute leak The gpio device attributes were never destroyed when the gpio was unexported (or on export failures). Use device_create_with_groups() to create the default device attributes of the gpio class device. Note that this also fixes the attribute-creation race with userspace for these attributes. Remove contingent attributes in export error path and on unexport. Fixes: d8f388d8dc8d ("gpio: sysfs interface") Cc: stable # v2.6.27+ Signed-off-by: Johan Hovold Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 33cf4bd..fd4d942 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -128,7 +128,7 @@ static ssize_t gpio_value_store(struct device *dev, return status; } -static const DEVICE_ATTR(value, 0644, +static DEVICE_ATTR(value, 0644, gpio_value_show, gpio_value_store); static irqreturn_t gpio_sysfs_irq(int irq, void *priv) @@ -353,18 +353,15 @@ static ssize_t gpio_active_low_store(struct device *dev, return status ? : size; } -static const DEVICE_ATTR(active_low, 0644, +static DEVICE_ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store); -static const struct attribute *gpio_attrs[] = { +static struct attribute *gpio_attrs[] = { &dev_attr_value.attr, &dev_attr_active_low.attr, NULL, }; - -static const struct attribute_group gpio_attr_group = { - .attrs = (struct attribute **) gpio_attrs, -}; +ATTRIBUTE_GROUPS(gpio); /* * /sys/class/gpio/gpiochipN/ @@ -561,18 +558,15 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) if (desc->chip->names && desc->chip->names[offset]) ioname = desc->chip->names[offset]; - dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), - desc, ioname ? ioname : "gpio%u", - desc_to_gpio(desc)); + dev = device_create_with_groups(&gpio_class, desc->chip->dev, + MKDEV(0, 0), desc, gpio_groups, + ioname ? ioname : "gpio%u", + desc_to_gpio(desc)); if (IS_ERR(dev)) { status = PTR_ERR(dev); goto fail_unlock; } - status = sysfs_create_group(&dev->kobj, &gpio_attr_group); - if (status) - goto fail_unregister_device; - if (direction_may_change) { status = device_create_file(dev, &dev_attr_direction); if (status) @@ -583,13 +577,15 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) !test_bit(FLAG_IS_OUT, &desc->flags))) { status = device_create_file(dev, &dev_attr_edge); if (status) - goto fail_unregister_device; + goto fail_remove_attr_direction; } set_bit(FLAG_EXPORT, &desc->flags); mutex_unlock(&sysfs_lock); return 0; +fail_remove_attr_direction: + device_remove_file(dev, &dev_attr_direction); fail_unregister_device: device_unregister(dev); fail_unlock: @@ -723,6 +719,8 @@ void gpiod_unexport(struct gpio_desc *desc) mutex_unlock(&sysfs_lock); if (dev) { + device_remove_file(dev, &dev_attr_edge); + device_remove_file(dev, &dev_attr_direction); device_unregister(dev); put_device(dev); } -- cgit v0.10.2 From ebbeba120ab2ec6ac5f3afc1425ec6ff0b77ad6f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 13 Jan 2015 13:00:06 +0100 Subject: gpio: sysfs: fix gpio attribute-creation race Fix attribute-creation race with userspace by using the default group to create also the contingent gpio device attributes. Fixes: d8f388d8dc8d ("gpio: sysfs interface") Signed-off-by: Johan Hovold Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index fd4d942..f62aa11 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -356,12 +356,44 @@ static ssize_t gpio_active_low_store(struct device *dev, static DEVICE_ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store); +static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr, + int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct gpio_desc *desc = dev_get_drvdata(dev); + umode_t mode = attr->mode; + bool show_direction = test_bit(FLAG_SYSFS_DIR, &desc->flags); + + if (attr == &dev_attr_direction.attr) { + if (!show_direction) + mode = 0; + } else if (attr == &dev_attr_edge.attr) { + if (gpiod_to_irq(desc) < 0) + mode = 0; + if (!show_direction && test_bit(FLAG_IS_OUT, &desc->flags)) + mode = 0; + } + + return mode; +} + static struct attribute *gpio_attrs[] = { + &dev_attr_direction.attr, + &dev_attr_edge.attr, &dev_attr_value.attr, &dev_attr_active_low.attr, NULL, }; -ATTRIBUTE_GROUPS(gpio); + +static const struct attribute_group gpio_group = { + .attrs = gpio_attrs, + .is_visible = gpio_is_visible, +}; + +static const struct attribute_group *gpio_groups[] = { + &gpio_group, + NULL +}; /* * /sys/class/gpio/gpiochipN/ @@ -550,8 +582,11 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) goto fail_unlock; } - if (!desc->chip->direction_input || !desc->chip->direction_output) - direction_may_change = false; + if (desc->chip->direction_input && desc->chip->direction_output && + direction_may_change) { + set_bit(FLAG_SYSFS_DIR, &desc->flags); + } + spin_unlock_irqrestore(&gpio_lock, flags); offset = gpio_chip_hwgpio(desc); @@ -567,27 +602,10 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) goto fail_unlock; } - if (direction_may_change) { - status = device_create_file(dev, &dev_attr_direction); - if (status) - goto fail_unregister_device; - } - - if (gpiod_to_irq(desc) >= 0 && (direction_may_change || - !test_bit(FLAG_IS_OUT, &desc->flags))) { - status = device_create_file(dev, &dev_attr_edge); - if (status) - goto fail_remove_attr_direction; - } - set_bit(FLAG_EXPORT, &desc->flags); mutex_unlock(&sysfs_lock); return 0; -fail_remove_attr_direction: - device_remove_file(dev, &dev_attr_direction); -fail_unregister_device: - device_unregister(dev); fail_unlock: mutex_unlock(&sysfs_lock); gpiod_dbg(desc, "%s: status %d\n", __func__, status); @@ -711,6 +729,7 @@ void gpiod_unexport(struct gpio_desc *desc) dev = class_find_device(&gpio_class, NULL, desc, match_export); if (dev) { gpio_setup_irq(desc, dev, 0); + clear_bit(FLAG_SYSFS_DIR, &desc->flags); clear_bit(FLAG_EXPORT, &desc->flags); } else status = -ENODEV; @@ -719,8 +738,6 @@ void gpiod_unexport(struct gpio_desc *desc) mutex_unlock(&sysfs_lock); if (dev) { - device_remove_file(dev, &dev_attr_edge); - device_remove_file(dev, &dev_attr_direction); device_unregister(dev); put_device(dev); } diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index e3a5211..550a5ea 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -77,6 +77,7 @@ struct gpio_desc { #define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */ #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ +#define FLAG_SYSFS_DIR 10 /* show sysfs direction attribute */ #define ID_SHIFT 16 /* add new flags before this one */ -- cgit v0.10.2 From 7b8792bbdffdff3abda704f89c6a45ea97afdc62 Mon Sep 17 00:00:00 2001 From: Hans Holmberg Date: Fri, 9 Jan 2015 09:40:43 +0100 Subject: gpiolib: of: Correct error handling in of_get_named_gpiod_flags of_get_named_gpiod_flags fails with -EPROBE_DEFER in cases where the gpio chip is available and the GPIO translation fails. This causes drivers to be re-probed erroneusly, and hides the real problem(i.e. the GPIO number being out of range). Cc: Stable Signed-off-by: Hans Holmberg Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 604dbe6..08261f2 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -45,8 +45,14 @@ static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) return false; ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags); - if (ret < 0) - return false; + if (ret < 0) { + /* We've found the gpio chip, but the translation failed. + * Return true to stop looking and return the translation + * error via out_gpio + */ + gg_data->out_gpio = ERR_PTR(ret); + return true; + } gg_data->out_gpio = gpiochip_get_desc(gc, ret); return true; -- cgit v0.10.2 From 8c6067355f72e330695968601f0aef3436b473ce Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 15 Jan 2015 09:38:03 -0600 Subject: arm: boot: dts: dra7: enable dwc3 suspend PHY quirk Whenever Suspend PHY bit is set on DRA7x devices, USB will not work due to Set EP Configuration command always failing. This was only found after a recent commit 2164a47 (usb: dwc3: set SUSPHY bit for all cores, which will be merged for v3.19) added a missing *required* step to dwc3 initialization. Synopsys Databook requires that we enable Suspend PHY bit after initialization but that, unfortunately, breaks DRA7x. Note that the same regression was already patched for AM437x. Reported-by: Roger Quadros Signed-off-by: Felipe Balbi Signed-off-by: Tony Lindgren diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 22771bc..63f8b00 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -1257,6 +1257,8 @@ tx-fifo-resize; maximum-speed = "super-speed"; dr_mode = "otg"; + snps,dis_u3_susphy_quirk; + snps,dis_u2_susphy_quirk; }; }; @@ -1278,6 +1280,8 @@ tx-fifo-resize; maximum-speed = "high-speed"; dr_mode = "otg"; + snps,dis_u3_susphy_quirk; + snps,dis_u2_susphy_quirk; }; }; @@ -1299,6 +1303,8 @@ tx-fifo-resize; maximum-speed = "high-speed"; dr_mode = "otg"; + snps,dis_u3_susphy_quirk; + snps,dis_u2_susphy_quirk; }; }; -- cgit v0.10.2 From 9f6bd8fa5860fc7b041b10f2d463c78d65bdb59d Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Thu, 15 Jan 2015 14:59:28 +0530 Subject: drivers: net: cpsw: fix cpsw hung with add vlan using vconfig while adding vlan in dual EMAC mode, only specific ports should be subscribed for the vlan, else it will lead to switching mode and if both ports connected to same switch cpsw will hung as it creates a network loop. Fixing this by adding only specific ports in case of dual EMAC. Signed-off-by: Mugunthan V N Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 64d1cef..e068d48 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -1634,16 +1634,24 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, unsigned short vid) { int ret; - int unreg_mcast_mask; + int unreg_mcast_mask = 0; + u32 port_mask; - if (priv->ndev->flags & IFF_ALLMULTI) - unreg_mcast_mask = ALE_ALL_PORTS; - else - unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; + if (priv->data.dual_emac) { + port_mask = (1 << (priv->emac_port + 1)) | ALE_PORT_HOST; + + if (priv->ndev->flags & IFF_ALLMULTI) + unreg_mcast_mask = port_mask; + } else { + port_mask = ALE_ALL_PORTS; + + if (priv->ndev->flags & IFF_ALLMULTI) + unreg_mcast_mask = ALE_ALL_PORTS; + else + unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; + } - ret = cpsw_ale_add_vlan(priv->ale, vid, - ALE_ALL_PORTS << priv->host_port, - 0, ALE_ALL_PORTS << priv->host_port, + ret = cpsw_ale_add_vlan(priv->ale, vid, port_mask, 0, port_mask, unreg_mcast_mask << priv->host_port); if (ret != 0) return ret; @@ -1654,8 +1662,7 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, goto clean_vid; ret = cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, - ALE_ALL_PORTS << priv->host_port, - ALE_VLAN, vid, 0); + port_mask, ALE_VLAN, vid, 0); if (ret != 0) goto clean_vlan_ucast; return 0; -- cgit v0.10.2 From 01fbd3f55cca25a6f9a4764d73da55615398c393 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 15 Jan 2015 11:52:19 +0100 Subject: sh_eth: Fix addition of .trscer_err_mask to wrong SoC data commit b284fbe3b3ef9cf8 ("sh_eth: Fix access to TRSCER register") wanted to add a .trscer_err_mask value to the R-Car Gen2 family-specific data structure (r8a779x_data), but it was accidentally added to the SH7724-specific data structure (sh7724_data). Presumably this happened due to a patch conflict with commit d407bc0203539031 ("sh-eth: Set fdr_value of R-Car SoCs"), which added another field at the same position. Move the field setting to fix this. Signed-off-by: Geert Uytterhoeven Fixes: b284fbe3b3ef9cf8 ("sh_eth: Fix access to TRSCER register") Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 37583a9..8d227d9 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -498,6 +498,8 @@ static struct sh_eth_cpu_data r8a779x_data = { EESR_ECI, .fdr_value = 0x00000f0f, + .trscer_err_mask = DESC_I_RINT8, + .apr = 1, .mpr = 1, .tpauser = 1, @@ -538,8 +540,6 @@ static struct sh_eth_cpu_data sh7724_data = { EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI, - .trscer_err_mask = DESC_I_RINT8, - .apr = 1, .mpr = 1, .tpauser = 1, -- cgit v0.10.2 From 6222d1721dd7d533b43747642419a8ff78ad6f99 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 15 Jan 2015 15:19:10 -0700 Subject: NVMe: cq_vector should be signed This was inadvertently dropped from an earlier commit, otherwise the check against cq_vector == -1 to prevent double free doesn't make any sense. Fixes: 2b25d981790b Signed-off-by: Jens Axboe diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index cb529e9..d826bf3 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c @@ -106,7 +106,7 @@ struct nvme_queue { dma_addr_t cq_dma_addr; u32 __iomem *q_db; u16 q_depth; - u16 cq_vector; + s16 cq_vector; u16 sq_head; u16 sq_tail; u16 cq_head; -- cgit v0.10.2 From 1c1832c7cd35db90b126a984685b44858ad63d01 Mon Sep 17 00:00:00 2001 From: "Girish K.S" Date: Thu, 15 Jan 2015 10:41:47 +0900 Subject: net: sxgbe: Fix NULL dereferece when using DT When the MAC address is provided in the device tree file, the condition is true and kernel crashes due to NULL dereference. Signed-off-by: Girish K.S Signed-off-by: Byungho An Signed-off-by: Kukjin Kim Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c index 866560e..b02eed1 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c @@ -108,10 +108,6 @@ static int sxgbe_platform_probe(struct platform_device *pdev) } } - /* Get MAC address if available (DT) */ - if (mac) - ether_addr_copy(priv->dev->dev_addr, mac); - priv = sxgbe_drv_probe(&(pdev->dev), plat_dat, addr); if (!priv) { pr_err("%s: main driver probe failed\n", __func__); @@ -125,6 +121,10 @@ static int sxgbe_platform_probe(struct platform_device *pdev) goto err_drv_remove; } + /* Get MAC address if available (DT) */ + if (mac) + ether_addr_copy(priv->dev->dev_addr, mac); + /* Get the TX/RX IRQ numbers */ for (i = 0, chan = 1; i < SXGBE_TX_QUEUES; i++) { priv->txq[i]->irq_no = irq_of_parse_and_map(node, chan++); -- cgit v0.10.2 From f7d855566ff69207be1052ceecbf455f89490b42 Mon Sep 17 00:00:00 2001 From: Byungho An Date: Thu, 15 Jan 2015 10:43:11 +0900 Subject: net: sxgbe: Fix waring for double kfree() This patch fixes double kfree() calls at init_rx_ring() because it causes static checker warning. Reported-by: Dan Carpenter Signed-off-by: Byungho An Signed-off-by: Kukjin Kim Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index 6984944..b1a2718 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -474,13 +474,19 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, /* allocate memory for RX skbuff array */ rx_ring->rx_skbuff_dma = kmalloc_array(rx_rsize, sizeof(dma_addr_t), GFP_KERNEL); - if (rx_ring->rx_skbuff_dma == NULL) - goto dmamem_err; + if (!rx_ring->rx_skbuff_dma) { + dma_free_coherent(priv->device, + rx_rsize * sizeof(struct sxgbe_rx_norm_desc), + rx_ring->dma_rx, rx_ring->dma_rx_phy); + goto error; + } rx_ring->rx_skbuff = kmalloc_array(rx_rsize, sizeof(struct sk_buff *), GFP_KERNEL); - if (rx_ring->rx_skbuff == NULL) - goto rxbuff_err; + if (!rx_ring->rx_skbuff) { + kfree(rx_ring->rx_skbuff_dma); + goto error; + } /* initialise the buffers */ for (desc_index = 0; desc_index < rx_rsize; desc_index++) { @@ -502,13 +508,6 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, err_init_rx_buffers: while (--desc_index >= 0) free_rx_ring(priv->device, rx_ring, desc_index); - kfree(rx_ring->rx_skbuff); -rxbuff_err: - kfree(rx_ring->rx_skbuff_dma); -dmamem_err: - dma_free_coherent(priv->device, - rx_rsize * sizeof(struct sxgbe_rx_norm_desc), - rx_ring->dma_rx, rx_ring->dma_rx_phy); error: return -ENOMEM; } -- cgit v0.10.2 From 5eff6dadb9f466d15692cc5dd45e1015bf0ec987 Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Thu, 15 Jan 2015 15:28:54 +0200 Subject: net/mlx4: Don't disable vxlan offloads under DMFS-A0 optimized steering Except for VXLAN steering rules, all offloads should work as they were under plain DMFS mode. Fix that by enabling all the offloads under DMFS-A0 mode, except for VXLAN steering rules. Fixes: d57febe1a478 "net/mlx4: Add A0 hybrid steering" Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 57ecc5b..9117b7a 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -1114,7 +1114,8 @@ static int mlx4_ib_tunnel_steer_add(struct ib_qp *qp, struct ib_flow_attr *flow_ struct mlx4_dev *dev = to_mdev(qp->device)->dev; int err = 0; - if (dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) + if (dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN || + dev->caps.dmfs_high_steer_mode == MLX4_STEERING_DMFS_A0_STATIC) return 0; /* do nothing */ ib_flow = flow_attr + 1; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index d0d6dc1..ac6a8f1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -475,7 +475,8 @@ static int mlx4_en_tunnel_steer_add(struct mlx4_en_priv *priv, unsigned char *ad { int err; - if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) + if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN || + priv->mdev->dev->caps.dmfs_high_steer_mode == MLX4_STEERING_DMFS_A0_STATIC) return 0; /* do nothing */ err = mlx4_tunnel_steer_add(priv->mdev->dev, addr, priv->port, qpn, diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 03e9eb0..6e08352 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1744,8 +1744,7 @@ static void choose_tunnel_offload_mode(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) { if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED && - dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS && - dev->caps.dmfs_high_steer_mode != MLX4_STEERING_DMFS_A0_STATIC) + dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS) dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_VXLAN; else dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_NONE; -- cgit v0.10.2 From f812116b174e59a350acc8e4856213a166a91222 Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Thu, 15 Jan 2015 13:18:40 -0500 Subject: ip: zero sockaddr returned on error queue The sockaddr is returned in IP(V6)_RECVERR as part of errhdr. That structure is defined and allocated on the stack as struct { struct sock_extended_err ee; struct sockaddr_in(6) offender; } errhdr; The second part is only initialized for certain SO_EE_ORIGIN values. Always initialize it completely. An MTU exceeded error on a SOCK_RAW/IPPROTO_RAW is one example that would return uninitialized bytes. Signed-off-by: Willem de Bruijn ---- Also verified that there is no padding between errhdr.ee and errhdr.offender that could leak additional kernel data. Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 8a89c73..6b85adb 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -461,17 +461,13 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); sin = &errhdr.offender; - sin->sin_family = AF_UNSPEC; + memset(sin, 0, sizeof(*sin)); if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP || ipv4_pktinfo_prepare_errqueue(sk, skb, serr->ee.ee_origin)) { - struct inet_sock *inet = inet_sk(sk); - sin->sin_family = AF_INET; sin->sin_addr.s_addr = ip_hdr(skb)->saddr; - sin->sin_port = 0; - memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); - if (inet->cmsg_flags) + if (inet_sk(sk)->cmsg_flags) ip_cmsg_recv(msg, skb); } diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 100c589..49f5e73 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -393,11 +393,10 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); sin = &errhdr.offender; - sin->sin6_family = AF_UNSPEC; + memset(sin, 0, sizeof(*sin)); + if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { sin->sin6_family = AF_INET6; - sin->sin6_flowinfo = 0; - sin->sin6_port = 0; if (np->rxopt.all) { if (serr->ee.ee_origin != SO_EE_ORIGIN_ICMP && serr->ee.ee_origin != SO_EE_ORIGIN_ICMP6) @@ -412,12 +411,9 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) ipv6_iface_scope_id(&sin->sin6_addr, IP6CB(skb)->iif); } else { - struct inet_sock *inet = inet_sk(sk); - ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, &sin->sin6_addr); - sin->sin6_scope_id = 0; - if (inet->cmsg_flags) + if (inet_sk(sk)->cmsg_flags) ip_cmsg_recv(msg, skb); } } -- cgit v0.10.2 From cd2d6d33e2c5be653d10cdc8fcd7dcf0be28de50 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2015 14:45:09 -0800 Subject: net: davinci_emac: Fix hangs with interrupts On davinci_emac, we have pulse interrupts. This means that we need to clear the EOI bits when disabling interrupts as otherwise the interrupts keep happening. And we also need to not clear the EOI bits again when enabling the interrupts as otherwise we will get tons of: unexpected IRQ trap at vector 00 These errors almost certainly mean that the omap-intc.c is signaling a spurious interrupt with the reserved irq 127 as we've seen earlier on omap3. Let's fix the issue by clearing the EOI bits when disabling the interrupts. Let's also keep the comment for "Rx Threshold and Misc interrupts are not enabled" for both enable and disable so people are aware of this when potentially adding more support. Note that eventually we should handle the RX and TX interrupts separately like cpsw is now doing. However, so far I have not seen any issues with this based on my testing, so it seems to behave a little different compared to the cpsw that had a similar issue. Cc: Brian Hutchinson Reviewed-by: Felipe Balbi Signed-off-by: Tony Lindgren Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index ea71251..383ed52 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -922,6 +922,16 @@ static void emac_int_disable(struct emac_priv *priv) if (priv->int_disable) priv->int_disable(); + /* NOTE: Rx Threshold and Misc interrupts are not enabled */ + + /* ack rxen only then a new pulse will be generated */ + emac_write(EMAC_DM646X_MACEOIVECTOR, + EMAC_DM646X_MAC_EOI_C0_RXEN); + + /* ack txen- only then a new pulse will be generated */ + emac_write(EMAC_DM646X_MACEOIVECTOR, + EMAC_DM646X_MAC_EOI_C0_TXEN); + local_irq_restore(flags); } else { @@ -951,15 +961,6 @@ static void emac_int_enable(struct emac_priv *priv) * register */ /* NOTE: Rx Threshold and Misc interrupts are not enabled */ - - /* ack rxen only then a new pulse will be generated */ - emac_write(EMAC_DM646X_MACEOIVECTOR, - EMAC_DM646X_MAC_EOI_C0_RXEN); - - /* ack txen- only then a new pulse will be generated */ - emac_write(EMAC_DM646X_MACEOIVECTOR, - EMAC_DM646X_MAC_EOI_C0_TXEN); - } else { /* Set DM644x control registers for interrupt control */ emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1); -- cgit v0.10.2 From b5133e7a988b2cf8e1cd2b23231f36aff35ceffc Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2015 14:45:10 -0800 Subject: net: davinci_emac: Fix runtime pm calls for davinci_emac Commit 3ba97381343b ("net: ethernet: davinci_emac: add pm_runtime support") added support for runtime PM, but it causes issues on omap3 related devices that actually gate the clocks: Unhandled fault: external abort on non-linefetch (0x1008) ... [] (emac_dev_getnetstats) from [] (dev_get_stats+0x78/0xc8) [] (dev_get_stats) from [] (rtnl_fill_ifinfo+0x3b8/0x938) [] (rtnl_fill_ifinfo) from [] (rtmsg_ifinfo+0x68/0xd8) [] (rtmsg_ifinfo) from [] (register_netdevice+0x3a0/0x4ec) [] (register_netdevice) from [] (register_netdev+0x14/0x24) [] (register_netdev) from [] (davinci_emac_probe+0x408/0x5c8) [] (davinci_emac_probe) from [] (platform_drv_probe+0x48/0xa4) Let's fix it by moving the pm_runtime_get() call earlier, and also add it to the emac_dev_getnetstats(). Also note that we want to use pm_runtime_get_sync() as we don't want to have deferred_resume happen. And let's also check the return value for pm_runtime_get_sync() as noted by Felipe Balbi . Cc: Brian Hutchinson Acked-by: Mark A. Greer Reviewed-by: Felipe Balbi Signed-off-by: Tony Lindgren Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 383ed52..5df339e 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1538,7 +1538,13 @@ static int emac_dev_open(struct net_device *ndev) int i = 0; struct emac_priv *priv = netdev_priv(ndev); - pm_runtime_get(&priv->pdev->dev); + ret = pm_runtime_get_sync(&priv->pdev->dev); + if (ret < 0) { + pm_runtime_put_noidle(&priv->pdev->dev); + dev_err(&priv->pdev->dev, "%s: failed to get_sync(%d)\n", + __func__, ret); + return ret; + } netif_carrier_off(ndev); for (cnt = 0; cnt < ETH_ALEN; cnt++) @@ -1725,6 +1731,15 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) struct emac_priv *priv = netdev_priv(ndev); u32 mac_control; u32 stats_clear_mask; + int err; + + err = pm_runtime_get_sync(&priv->pdev->dev); + if (err < 0) { + pm_runtime_put_noidle(&priv->pdev->dev); + dev_err(&priv->pdev->dev, "%s: failed to get_sync(%d)\n", + __func__, err); + return &ndev->stats; + } /* update emac hardware stats and reset the registers*/ @@ -1767,6 +1782,8 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) ndev->stats.tx_fifo_errors += emac_read(EMAC_TXUNDERRUN); emac_write(EMAC_TXUNDERRUN, stats_clear_mask); + pm_runtime_put(&priv->pdev->dev); + return &ndev->stats; } @@ -1981,12 +1998,22 @@ static int davinci_emac_probe(struct platform_device *pdev) ndev->ethtool_ops = ðtool_ops; netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); + pm_runtime_enable(&pdev->dev); + rc = pm_runtime_get_sync(&pdev->dev); + if (rc < 0) { + pm_runtime_put_noidle(&pdev->dev); + dev_err(&pdev->dev, "%s: failed to get_sync(%d)\n", + __func__, rc); + goto no_cpdma_chan; + } + /* register the network device */ SET_NETDEV_DEV(ndev, &pdev->dev); rc = register_netdev(ndev); if (rc) { dev_err(&pdev->dev, "error in register_netdev\n"); rc = -ENODEV; + pm_runtime_put(&pdev->dev); goto no_cpdma_chan; } @@ -1996,9 +2023,7 @@ static int davinci_emac_probe(struct platform_device *pdev) "(regs: %p, irq: %d)\n", (void *)priv->emac_base_phys, ndev->irq); } - - pm_runtime_enable(&pdev->dev); - pm_runtime_resume(&pdev->dev); + pm_runtime_put(&pdev->dev); return 0; -- cgit v0.10.2 From 0f5372731dc13655da9edd282437a290eaa7c258 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2015 14:45:11 -0800 Subject: net: davinci_emac: Free clock after checking the frequency We only use clk_get() to get the frequency, the rest is done by the runtime PM calls. Let's free the clock too. Cc: Brian Hutchinson Cc: Felipe Balbi Signed-off-by: Tony Lindgren Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 5df339e..59fdcdd 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1894,6 +1894,7 @@ static int davinci_emac_probe(struct platform_device *pdev) return -EBUSY; } emac_bus_frequency = clk_get_rate(emac_clk); + devm_clk_put(&pdev->dev, emac_clk); /* TODO: Probe PHY here if possible */ -- cgit v0.10.2 From 1d82ffa6ba0f645d449c1b0489bb698a9a7301ea Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2015 14:45:12 -0800 Subject: net: davinci_emac: Fix incomplete code for getting the phy from device tree Looks like the phy_id is never set up beyond getting the phandle. Note that we can remove the ifdef for phy_node as there is a stub for of_phy_connec() if CONFIG_OF is not set. Cc: Brian Hutchinson Cc: Felipe Balbi Signed-off-by: Tony Lindgren Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 59fdcdd..e44c8d8 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include @@ -343,9 +344,7 @@ struct emac_priv { u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS]; u32 rx_addr_type; const char *phy_id; -#ifdef CONFIG_OF struct device_node *phy_node; -#endif struct phy_device *phydev; spinlock_t lock; /*platform specific members*/ @@ -1603,8 +1602,20 @@ static int emac_dev_open(struct net_device *ndev) cpdma_ctlr_start(priv->dma); priv->phydev = NULL; + + if (priv->phy_node) { + priv->phydev = of_phy_connect(ndev, priv->phy_node, + &emac_adjust_link, 0, 0); + if (!priv->phydev) { + dev_err(emac_dev, "could not connect to phy %s\n", + priv->phy_node->full_name); + ret = -ENODEV; + goto err; + } + } + /* use the first phy on the bus if pdata did not give us a phy id */ - if (!priv->phy_id) { + if (!priv->phydev && !priv->phy_id) { struct device *phy; phy = bus_find_device(&mdio_bus_type, NULL, NULL, @@ -1613,7 +1624,7 @@ static int emac_dev_open(struct net_device *ndev) priv->phy_id = dev_name(phy); } - if (priv->phy_id && *priv->phy_id) { + if (!priv->phydev && priv->phy_id && *priv->phy_id) { priv->phydev = phy_connect(ndev, priv->phy_id, &emac_adjust_link, PHY_INTERFACE_MODE_MII); @@ -1634,7 +1645,9 @@ static int emac_dev_open(struct net_device *ndev) "(mii_bus:phy_addr=%s, id=%x)\n", priv->phydev->drv->name, dev_name(&priv->phydev->dev), priv->phydev->phy_id); - } else { + } + + if (!priv->phydev) { /* No PHY , fix the link, speed and duplex settings */ dev_notice(emac_dev, "no phy, defaulting to 100/full\n"); priv->link = 1; -- cgit v0.10.2 From a1594321a9bc55ad44e02b27773cb0ed05837531 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2015 14:45:13 -0800 Subject: net: davinci_emac: Fix ioremap for devices with MDIO within the EMAC address space Some devices like dm816x have the MDIO registers within the first EMAC instance address space. Let's fix the issue by allowing to pass an optional second IO range for the EMAC control register area. Cc: Brian Hutchinson Cc: Felipe Balbi Signed-off-by: Tony Lindgren Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index e44c8d8..1e5ea81 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1890,7 +1890,7 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv) static int davinci_emac_probe(struct platform_device *pdev) { int rc = 0; - struct resource *res; + struct resource *res, *res_ctrl; struct net_device *ndev; struct emac_priv *priv; unsigned long hw_ram_addr; @@ -1949,11 +1949,20 @@ static int davinci_emac_probe(struct platform_device *pdev) rc = PTR_ERR(priv->remap_addr); goto no_pdata; } + + res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res_ctrl) { + priv->ctrl_base = + devm_ioremap_resource(&pdev->dev, res_ctrl); + if (IS_ERR(priv->ctrl_base)) + goto no_pdata; + } else { + priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset; + } + priv->emac_base = priv->remap_addr + pdata->ctrl_reg_offset; ndev->base_addr = (unsigned long)priv->remap_addr; - priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset; - hw_ram_addr = pdata->hw_ram_addr; if (!hw_ram_addr) hw_ram_addr = (u32 __force)res->start + pdata->ctrl_ram_offset; -- cgit v0.10.2 From de3900833ee635d5658415fea9c8c4e13507d777 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2015 14:45:14 -0800 Subject: net: davinci_emac: Add support for emac on dm816x On dm816x we have two emac controllers with separate memory areas. Cc: Brian Hutchinson Cc: Felipe Balbi Signed-off-by: Tony Lindgren Signed-off-by: David S. Miller diff --git a/Documentation/devicetree/bindings/net/davinci_emac.txt b/Documentation/devicetree/bindings/net/davinci_emac.txt index 0328088..24c5cda 100644 --- a/Documentation/devicetree/bindings/net/davinci_emac.txt +++ b/Documentation/devicetree/bindings/net/davinci_emac.txt @@ -4,7 +4,8 @@ This file provides information, what the device node for the davinci_emac interface contains. Required properties: -- compatible: "ti,davinci-dm6467-emac" or "ti,am3517-emac" +- compatible: "ti,davinci-dm6467-emac", "ti,am3517-emac" or + "ti,dm816-emac" - reg: Offset and length of the register set for the device - ti,davinci-ctrl-reg-offset: offset to control register - ti,davinci-ctrl-mod-reg-offset: offset to control module register diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 1e5ea81..5fae435 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -2120,9 +2120,14 @@ static const struct emac_platform_data am3517_emac_data = { .hw_ram_addr = 0x01e20000, }; +static const struct emac_platform_data dm816_emac_data = { + .version = EMAC_VERSION_2, +}; + static const struct of_device_id davinci_emac_of_match[] = { {.compatible = "ti,davinci-dm6467-emac", }, {.compatible = "ti,am3517-emac", .data = &am3517_emac_data, }, + {.compatible = "ti,dm816-emac", .data = &dm816_emac_data, }, {}, }; MODULE_DEVICE_TABLE(of, davinci_emac_of_match); -- cgit v0.10.2 From ac64da0b83d82abe62f78b3d0e21cca31aea24fa Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 15 Jan 2015 17:04:22 -0800 Subject: net: rps: fix cpu unplug softnet_data.input_pkt_queue is protected by a spinlock that we must hold when transferring packets from victim queue to an active one. This is because other cpus could still be trying to enqueue packets into victim queue. A second problem is that when we transfert the NAPI poll_list from victim to current cpu, we absolutely need to special case the percpu backlog, because we do not want to add complex locking to protect process_queue : Only owner cpu is allowed to manipulate it, unless cpu is offline. Based on initial patch from Prasad Sodagudi & Subash Abhinov Kasiviswanathan. This version is better because we do not slow down packet processing, only make migration safer. Reported-by: Prasad Sodagudi Reported-by: Subash Abhinov Kasiviswanathan Signed-off-by: Eric Dumazet Cc: Tom Herbert Signed-off-by: David S. Miller diff --git a/net/core/dev.c b/net/core/dev.c index 683d493..171420e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -7072,10 +7072,20 @@ static int dev_cpu_callback(struct notifier_block *nfb, oldsd->output_queue = NULL; oldsd->output_queue_tailp = &oldsd->output_queue; } - /* Append NAPI poll list from offline CPU. */ - if (!list_empty(&oldsd->poll_list)) { - list_splice_init(&oldsd->poll_list, &sd->poll_list); - raise_softirq_irqoff(NET_RX_SOFTIRQ); + /* Append NAPI poll list from offline CPU, with one exception : + * process_backlog() must be called by cpu owning percpu backlog. + * We properly handle process_queue & input_pkt_queue later. + */ + while (!list_empty(&oldsd->poll_list)) { + struct napi_struct *napi = list_first_entry(&oldsd->poll_list, + struct napi_struct, + poll_list); + + list_del_init(&napi->poll_list); + if (napi->poll == process_backlog) + napi->state = 0; + else + ____napi_schedule(sd, napi); } raise_softirq_irqoff(NET_TX_SOFTIRQ); @@ -7086,7 +7096,7 @@ static int dev_cpu_callback(struct notifier_block *nfb, netif_rx_internal(skb); input_queue_head_incr(oldsd); } - while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) { + while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) { netif_rx_internal(skb); input_queue_head_incr(oldsd); } -- cgit v0.10.2 From 433678bdc6ed39f053c55da96b51de5bf0aeebb1 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 13 Jan 2015 23:59:53 +0100 Subject: perf/rapl: Fix sysfs_show() initialization for RAPL PMU This patch fixes a problem with the initialization of the sysfs_show() routine for the RAPL PMU. The current code was wrongly relying on the EVENT_ATTR_STR() macro which uses the events_sysfs_show() function in the x86 PMU code. That function itself was relying on the x86_pmu data structure. Yet RAPL and the core PMU (x86_pmu) have nothing to do with each other. They should therefore not interact with each other. The x86_pmu structure is initialized at boot time based on the host CPU model. When the host CPU is not supported, the x86_pmu remains uninitialized and some of the callbacks it contains are NULL. The false dependency with x86_pmu could potentially cause crashes in case the x86_pmu is not initialized while the RAPL PMU is. This may, for instance, be the case in virtualized environments. This patch fixes the problem by using a private sysfs_show() routine for exporting the RAPL PMU events. Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra (Intel) Link: http://lkml.kernel.org/r/20150113225953.GA21525@thinkpad Cc: vincent.weaver@maine.edu Cc: jolsa@redhat.com Cc: Arnaldo Carvalho de Melo Cc: Linus Torvalds Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 673f930..6e434f8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c @@ -103,6 +103,13 @@ static struct kobj_attribute format_attr_##_var = \ #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */ +#define RAPL_EVENT_ATTR_STR(_name, v, str) \ +static struct perf_pmu_events_attr event_attr_##v = { \ + .attr = __ATTR(_name, 0444, rapl_sysfs_show, NULL), \ + .id = 0, \ + .event_str = str, \ +}; + struct rapl_pmu { spinlock_t lock; int hw_unit; /* 1/2^hw_unit Joule */ @@ -379,23 +386,36 @@ static struct attribute_group rapl_pmu_attr_group = { .attrs = rapl_pmu_attrs, }; -EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); -EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); -EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); -EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); +static ssize_t rapl_sysfs_show(struct device *dev, + struct device_attribute *attr, + char *page) +{ + struct perf_pmu_events_attr *pmu_attr = \ + container_of(attr, struct perf_pmu_events_attr, attr); + + if (pmu_attr->event_str) + return sprintf(page, "%s", pmu_attr->event_str); + + return 0; +} + +RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); +RAPL_EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); +RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); +RAPL_EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); -EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); -EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); -EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); -EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); +RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); +RAPL_EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); +RAPL_EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); +RAPL_EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); /* * we compute in 0.23 nJ increments regardless of MSR */ -EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); -EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); -EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); -EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); +RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); +RAPL_EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); +RAPL_EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); +RAPL_EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); static struct attribute *rapl_events_srv_attr[] = { EVENT_PTR(rapl_cores), -- cgit v0.10.2 From 33636732dcd7cc738a5913bb730d663c6b03c8fb Mon Sep 17 00:00:00 2001 From: Kan Liang Date: Mon, 12 Jan 2015 17:42:21 +0000 Subject: perf/x86/intel: Fix bug for "cycles:p" and "cycles:pp" on SLM cycles:p and cycles:pp do not work on SLM since commit: 86a04461a99f ("perf/x86: Revamp PEBS event selection") UOPS_RETIRED.ALL is not a PEBS capable event, so it should not be used to count cycle number. Actually SLM calls intel_pebs_aliases_core2() which uses INST_RETIRED.ANY_P to count the number of cycles. It's a PEBS capable event. But inv and cmask must be set to count cycles. Considering SLM allows all events as PEBS with no flags, only INST_RETIRED.ANY_P, inv=1, cmask=16 needs to handled specially. Signed-off-by: Kan Liang Signed-off-by: Peter Zijlstra (Intel) Link: http://lkml.kernel.org/r/1421084541-31639-1-git-send-email-kan.liang@intel.com Cc: Arnaldo Carvalho de Melo Cc: Linus Torvalds Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 3c895d4..0739833 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -568,8 +568,8 @@ struct event_constraint intel_atom_pebs_event_constraints[] = { }; struct event_constraint intel_slm_pebs_event_constraints[] = { - /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */ - INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf), + /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */ + INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x1), /* Allow all events as PEBS with no flags */ INTEL_ALL_EVENT_CONSTRAINT(0, 0x1), EVENT_CONSTRAINT_END -- cgit v0.10.2 From 0145058c3d30b4319d747f64caa16a9cb15f0581 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 16 Jan 2015 13:56:38 +0000 Subject: arm64: partially revert "ARM: 8167/1: extend the reserved memory for initrd to be page aligned" This patch partially reverts commit 421520ba98290a73b35b7644e877a48f18e06004 (only the arm64 part). There is no guarantee that the boot-loader places other images like dtb in a different page than initrd start/end, especially when the kernel is built with 64KB pages. When this happens, such pages must not be freed. The free_reserved_area() already takes care of rounding up "start" and rounding down "end" to avoid freeing partially used pages. Cc: # 3.17+ Reported-by: Peter Maydell Signed-off-by: Catalin Marinas Signed-off-by: Will Deacon diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index bac492c..c95464a 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -335,14 +335,8 @@ static int keep_initrd; void free_initrd_mem(unsigned long start, unsigned long end) { - if (!keep_initrd) { - if (start == initrd_start) - start = round_down(start, PAGE_SIZE); - if (end == initrd_end) - end = round_up(end, PAGE_SIZE); - + if (!keep_initrd) free_reserved_area((void *)start, (void *)end, 0, "initrd"); - } } static int __init keepinitrd_setup(char *__unused) -- cgit v0.10.2 From f331a859e0ee5a898c1f47596eddad4c4f02d657 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Thu, 15 Jan 2015 18:16:04 -0600 Subject: PCI: Add flag for devices where we can't use bus reset Enable a mechanism for devices to quirk that they do not behave when doing a PCI bus reset. We require a modest level of spec compliant behavior in order to do a reset, for instance the device should come out of reset without throwing errors and PCI config space should be accessible after reset. This is too much to ask for some devices. Link: http://lkml.kernel.org/r/20140923210318.498dacbd@dualc.maya.org Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas CC: stable@vger.kernel.org # v3.14+ diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cab05f3..e9d4fd8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3271,7 +3271,8 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) { struct pci_dev *pdev; - if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self) + if (pci_is_root_bus(dev->bus) || dev->subordinate || + !dev->bus->self || dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) return -ENOTTY; list_for_each_entry(pdev, &dev->bus->devices, bus_list) @@ -3305,7 +3306,8 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe) { struct pci_dev *pdev; - if (dev->subordinate || !dev->slot) + if (dev->subordinate || !dev->slot || + dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) return -ENOTTY; list_for_each_entry(pdev, &dev->bus->devices, bus_list) @@ -3557,6 +3559,20 @@ int pci_try_reset_function(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_try_reset_function); +/* Do any devices on or below this bus prevent a bus reset? */ +static bool pci_bus_resetable(struct pci_bus *bus) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || + (dev->subordinate && !pci_bus_resetable(dev->subordinate))) + return false; + } + + return true; +} + /* Lock devices from the top of the tree down */ static void pci_bus_lock(struct pci_bus *bus) { @@ -3607,6 +3623,22 @@ unlock: return 0; } +/* Do any devices on or below this slot prevent a bus reset? */ +static bool pci_slot_resetable(struct pci_slot *slot) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &slot->bus->devices, bus_list) { + if (!dev->slot || dev->slot != slot) + continue; + if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || + (dev->subordinate && !pci_bus_resetable(dev->subordinate))) + return false; + } + + return true; +} + /* Lock devices from the top of the tree down */ static void pci_slot_lock(struct pci_slot *slot) { @@ -3728,7 +3760,7 @@ static int pci_slot_reset(struct pci_slot *slot, int probe) { int rc; - if (!slot) + if (!slot || !pci_slot_resetable(slot)) return -ENOTTY; if (!probe) @@ -3820,7 +3852,7 @@ EXPORT_SYMBOL_GPL(pci_try_reset_slot); static int pci_bus_reset(struct pci_bus *bus, int probe) { - if (!bus->self) + if (!bus->self || !pci_bus_resetable(bus)) return -ENOTTY; if (probe) diff --git a/include/linux/pci.h b/include/linux/pci.h index 360a966..44627f1 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -175,6 +175,8 @@ enum pci_dev_flags { PCI_DEV_FLAGS_DMA_ALIAS_DEVFN = (__force pci_dev_flags_t) (1 << 4), /* Use a PCIe-to-PCI bridge alias even if !pci_is_pcie */ PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS = (__force pci_dev_flags_t) (1 << 5), + /* Do not use bus resets for device */ + PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6), }; enum pci_irq_reroute_variant { -- cgit v0.10.2 From c3e59ee4e76686b0c84ca8faa1011d10cd4ca1b8 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Thu, 15 Jan 2015 18:17:12 -0600 Subject: PCI: Mark Atheros AR93xx to avoid bus reset Reports against the TL-WDN4800 card indicate that PCI bus reset of this Atheros device cause system lock-ups and resets. I've also been able to confirm this behavior on multiple systems. The device never returns from reset and attempts to access config space of the device after reset result in hangs. Blacklist bus reset for the device to avoid this issue. [bhelgaas: This regression appeared in v3.14. Andreas bisected it to 425c1b223dac ("PCI: Add Virtual Channel to save/restore support"), but we don't understand the mechanism by which that commit affects the reset path.] [bhelgaas: changelog, references] Link: http://lkml.kernel.org/r/20140923210318.498dacbd@dualc.maya.org Reported-by: Andreas Hartmann Tested-by: Andreas Hartmann Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas CC: stable@vger.kernel.org # v3.14+ diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ed6f89b..e52356a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3028,6 +3028,20 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169, DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID, quirk_broken_intx_masking); +static void quirk_no_bus_reset(struct pci_dev *dev) +{ + dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; +} + +/* + * Atheros AR93xx chips do not behave after a bus reset. The device will + * throw a Link Down error on AER-capable systems and regardless of AER, + * config space of the device is never accessible again and typically + * causes the system to hang or reset when access is attempted. + * http://www.spinics.net/lists/linux-pci/msg34797.html + */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); + #ifdef CONFIG_ACPI /* * Apple: Shutdown Cactus Ridge Thunderbolt controller. -- cgit v0.10.2 From 3f2f4dc456e9f80849b99d79600a7257690ca4b1 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 10:22:31 -0600 Subject: PCI: Pass bridge device, not bus, when updating bridge windows pci_setup_bridge_io(), pci_setup_bridge_mmio(), and pci_setup_bridge_mmio_pref() program the windows of PCI-PCI bridges. Previously they accepted a pointer to the pci_bus of the secondary bus, then looked up the bridge leading to that bus. Pass the bridge directly, which will make it more convenient for future callers. No functional change. [bhelgaas: changelog, split into separate patch] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: stable@vger.kernel.org # v3.16+ diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 0482235..802f56b 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -530,9 +530,8 @@ EXPORT_SYMBOL(pci_setup_cardbus); config space writes, so it's quite possible that an I/O window of the bridge will have some undesirable address (e.g. 0) after the first write. Ditto 64-bit prefetchable MMIO. */ -static void pci_setup_bridge_io(struct pci_bus *bus) +static void pci_setup_bridge_io(struct pci_dev *bridge) { - struct pci_dev *bridge = bus->self; struct resource *res; struct pci_bus_region region; unsigned long io_mask; @@ -545,7 +544,7 @@ static void pci_setup_bridge_io(struct pci_bus *bus) io_mask = PCI_IO_1K_RANGE_MASK; /* Set up the top and bottom of the PCI I/O segment for this bus. */ - res = bus->resource[0]; + res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0]; pcibios_resource_to_bus(bridge->bus, ®ion, res); if (res->flags & IORESOURCE_IO) { pci_read_config_word(bridge, PCI_IO_BASE, &l); @@ -568,15 +567,14 @@ static void pci_setup_bridge_io(struct pci_bus *bus) pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); } -static void pci_setup_bridge_mmio(struct pci_bus *bus) +static void pci_setup_bridge_mmio(struct pci_dev *bridge) { - struct pci_dev *bridge = bus->self; struct resource *res; struct pci_bus_region region; u32 l; /* Set up the top and bottom of the PCI Memory segment for this bus. */ - res = bus->resource[1]; + res = &bridge->resource[PCI_BRIDGE_RESOURCES + 1]; pcibios_resource_to_bus(bridge->bus, ®ion, res); if (res->flags & IORESOURCE_MEM) { l = (region.start >> 16) & 0xfff0; @@ -588,9 +586,8 @@ static void pci_setup_bridge_mmio(struct pci_bus *bus) pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); } -static void pci_setup_bridge_mmio_pref(struct pci_bus *bus) +static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge) { - struct pci_dev *bridge = bus->self; struct resource *res; struct pci_bus_region region; u32 l, bu, lu; @@ -602,7 +599,7 @@ static void pci_setup_bridge_mmio_pref(struct pci_bus *bus) /* Set up PREF base/limit. */ bu = lu = 0; - res = bus->resource[2]; + res = &bridge->resource[PCI_BRIDGE_RESOURCES + 2]; pcibios_resource_to_bus(bridge->bus, ®ion, res); if (res->flags & IORESOURCE_PREFETCH) { l = (region.start >> 16) & 0xfff0; @@ -630,13 +627,13 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type) &bus->busn_res); if (type & IORESOURCE_IO) - pci_setup_bridge_io(bus); + pci_setup_bridge_io(bridge); if (type & IORESOURCE_MEM) - pci_setup_bridge_mmio(bus); + pci_setup_bridge_mmio(bridge); if (type & IORESOURCE_PREFETCH) - pci_setup_bridge_mmio_pref(bus); + pci_setup_bridge_mmio_pref(bridge); pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); } -- cgit v0.10.2 From 0f7e7aee2f37119a32e6e8b63250922442528961 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:49 -0600 Subject: PCI: Add pci_bus_clip_resource() to clip to fit upstream window Add pci_bus_clip_resource(). If a PCI-PCI bridge window overlaps an upstream bridge window but is not completely contained by it, this clips the downstream window so it fits inside the upstream one. No functional change (this adds the function but no callers). [bhelgaas: changelog, split into separate patch] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: stable@vger.kernel.org # v3.16+ diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 73aef51..8fb1618 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -228,6 +228,49 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, } EXPORT_SYMBOL(pci_bus_alloc_resource); +/* + * The @idx resource of @dev should be a PCI-PCI bridge window. If this + * resource fits inside a window of an upstream bridge, do nothing. If it + * overlaps an upstream window but extends outside it, clip the resource so + * it fits completely inside. + */ +bool pci_bus_clip_resource(struct pci_dev *dev, int idx) +{ + struct pci_bus *bus = dev->bus; + struct resource *res = &dev->resource[idx]; + struct resource orig_res = *res; + struct resource *r; + int i; + + pci_bus_for_each_resource(bus, r, i) { + resource_size_t start, end; + + if (!r) + continue; + + if (resource_type(res) != resource_type(r)) + continue; + + start = max(r->start, res->start); + end = min(r->end, res->end); + + if (start > end) + continue; /* no overlap */ + + if (res->start == start && res->end == end) + return false; /* no change */ + + res->start = start; + res->end = end; + dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n", + &orig_res, res); + + return true; + } + + return false; +} + void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } /** diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 8aff29a..d54632a 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -208,6 +208,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus, void __pci_bus_assign_resources(const struct pci_bus *bus, struct list_head *realloc_head, struct list_head *fail_head); +bool pci_bus_clip_resource(struct pci_dev *dev, int idx); /** * pci_ari_enabled - query ARI forwarding status -- cgit v0.10.2 From 8505e729a2f6eb0803ff943a15f133dd10afff3a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:49 -0600 Subject: PCI: Add pci_claim_bridge_resource() to clip window if necessary Add pci_claim_bridge_resource() to claim a PCI-PCI bridge window. This is like regular pci_claim_resource(), except that if we fail to claim the window, we check to see if we can reduce the size of the window and try again. This is for scenarios like this: pci_bus 0000:00: root bus resource [mem 0xc0000000-0xffffffff] pci 0000:00:01.0: bridge window [mem 0xbdf00000-0xddefffff 64bit pref] pci 0000:01:00.0: reg 0x10: [mem 0xc0000000-0xcfffffff pref] The 00:01.0 window is illegal: it starts before the host bridge window, so we have to assume the [0xbdf00000-0xbfffffff] region is inaccessible. We can make it legal by clipping it to [mem 0xc0000000-0xddefffff 64bit pref]. Previously we discarded the 00:01.0 window and tried to reassign that part of the hierarchy from scratch. That is a problem because Linux doesn't always assign things optimally. For example, in this case, BIOS put the 01:00.0 device in a prefetchable window below 4GB, but after 5b28541552ef, Linux puts the prefetchable window above 4GB where the 32-bit 01:00.0 device can't use it. Clipping the 00:01.0 window is less intrusive than completely reassigning things and is sufficient to let us use most of the BIOS configuration. Of course, it's possible that devices below 00:01.0 will no longer fit. If that's the case, we'll have to reassign things. But that's a separate problem. [bhelgaas: changelog, split into separate patch] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: stable@vger.kernel.org # v3.16+ diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 802f56b..e3e17f3 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -646,6 +646,41 @@ void pci_setup_bridge(struct pci_bus *bus) __pci_setup_bridge(bus, type); } + +int pci_claim_bridge_resource(struct pci_dev *bridge, int i) +{ + if (i < PCI_BRIDGE_RESOURCES || i > PCI_BRIDGE_RESOURCE_END) + return 0; + + if (pci_claim_resource(bridge, i) == 0) + return 0; /* claimed the window */ + + if ((bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI) + return 0; + + if (!pci_bus_clip_resource(bridge, i)) + return -EINVAL; /* clipping didn't change anything */ + + switch (i - PCI_BRIDGE_RESOURCES) { + case 0: + pci_setup_bridge_io(bridge); + break; + case 1: + pci_setup_bridge_mmio(bridge); + break; + case 2: + pci_setup_bridge_mmio_pref(bridge); + break; + default: + return -EINVAL; + } + + if (pci_claim_resource(bridge, i) == 0) + return 0; /* claimed a smaller window */ + + return -EINVAL; +} + /* Check whether the bridge supports optional I/O and prefetchable memory ranges. If not, the respective base/limit registers must be read-only and read as 0. */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 44627f1..9603094 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1067,6 +1067,7 @@ resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx); void pci_bus_assign_resources(const struct pci_bus *bus); void pci_bus_size_bridges(struct pci_bus *bus); int pci_claim_resource(struct pci_dev *, int); +int pci_claim_bridge_resource(struct pci_dev *bridge, int i); void pci_assign_unassigned_resources(void); void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge); void pci_assign_unassigned_bus_resources(struct pci_bus *bus); -- cgit v0.10.2 From 851b09369255a91e77f56d83e3643439ac5b209a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:49 -0600 Subject: x86/PCI: Clip bridge windows to fit in upstream windows Every PCI-PCI bridge window should fit inside an upstream bridge window because orphaned address space is unreachable from the primary side of the upstream bridge. If we inherit invalid bridge windows that overlap an upstream window from firmware, clip them to fit and update the bridge accordingly. [bhelgaas: changelog] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Tested-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: Thomas Gleixner CC: Ingo Molnar CC: "H. Peter Anvin" CC: x86@kernel.org CC: stable@vger.kernel.org # v3.16+ diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 9b18ef3..349c0d3 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -216,7 +216,7 @@ static void pcibios_allocate_bridge_resources(struct pci_dev *dev) continue; if (r->parent) /* Already allocated */ continue; - if (!r->start || pci_claim_resource(dev, idx) < 0) { + if (!r->start || pci_claim_bridge_resource(dev, idx) < 0) { /* * Something is wrong with the region. * Invalidate the resource to prevent -- cgit v0.10.2 From b3e118224c011b885ef8331bd5b341f15b3bd69a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:49 -0600 Subject: alpha/PCI: Clip bridge windows to fit in upstream windows Every PCI-PCI bridge window should fit inside an upstream bridge window because orphaned address space is unreachable from the primary side of the upstream bridge. If we inherit invalid bridge windows that overlap an upstream window from firmware, clip them to fit and update the bridge accordingly. [bhelgaas: changelog] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: Richard Henderson CC: Ivan Kokshaysky CC: Matt Turner CC: linux-alpha@vger.kernel.org diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 076c35c..98a1525 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -285,8 +285,12 @@ pcibios_claim_one_bus(struct pci_bus *b) if (r->parent || !r->start || !r->flags) continue; if (pci_has_flag(PCI_PROBE_ONLY) || - (r->flags & IORESOURCE_PCI_FIXED)) - pci_claim_resource(dev, i); + (r->flags & IORESOURCE_PCI_FIXED)) { + if (pci_claim_resource(dev, i) == 0) + continue; + + pci_claim_bridge_resource(dev, i); + } } } -- cgit v0.10.2 From b0c568de32bad5dc19722ba90ebe07e358675e51 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:49 -0600 Subject: frv/PCI: Clip bridge windows to fit in upstream windows Every PCI-PCI bridge window should fit inside an upstream bridge window because orphaned address space is unreachable from the primary side of the upstream bridge. If we inherit invalid bridge windows that overlap an upstream window from firmware, clip them to fit and update the bridge accordingly. [bhelgaas: changelog] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: David Howells CC: Paul Gortmaker diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c index 67b1d16..0635bd6 100644 --- a/arch/frv/mb93090-mb00/pci-frv.c +++ b/arch/frv/mb93090-mb00/pci-frv.c @@ -94,7 +94,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) r = &dev->resource[idx]; if (!r->start) continue; - pci_claim_resource(dev, idx); + pci_claim_bridge_resource(dev, idx); } } pcibios_allocate_bus_resources(&bus->children); -- cgit v0.10.2 From ce821ef0333fc130154ed3091144a590c1909f4d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:50 -0600 Subject: ia64/PCI: Clip bridge windows to fit in upstream windows Every PCI-PCI bridge window should fit inside an upstream bridge window because orphaned address space is unreachable from the primary side of the upstream bridge. If we inherit invalid bridge windows that overlap an upstream window from firmware, clip them to fit and update the bridge accordingly. [bhelgaas: changelog] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: Tony Luck CC: Fenghua Yu CC: "Rafael J. Wysocki" CC: linux-ia64@vger.kernel.org diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 291a582..900cc93 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -487,45 +487,39 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) return 0; } -static int is_valid_resource(struct pci_dev *dev, int idx) +void pcibios_fixup_device_resources(struct pci_dev *dev) { - unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; - struct resource *devr = &dev->resource[idx], *busr; + int idx; if (!dev->bus) - return 0; - - pci_bus_for_each_resource(dev->bus, busr, i) { - if (!busr || ((busr->flags ^ devr->flags) & type_mask)) - continue; - if ((devr->start) && (devr->start >= busr->start) && - (devr->end <= busr->end)) - return 1; - } - return 0; -} + return; -static void pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) -{ - int i; + for (idx = 0; idx < PCI_BRIDGE_RESOURCES; idx++) { + struct resource *r = &dev->resource[idx]; - for (i = start; i < limit; i++) { - if (!dev->resource[i].flags) + if (!r->flags || r->parent || !r->start) continue; - if ((is_valid_resource(dev, i))) - pci_claim_resource(dev, i); - } -} -void pcibios_fixup_device_resources(struct pci_dev *dev) -{ - pcibios_fixup_resources(dev, 0, PCI_BRIDGE_RESOURCES); + pci_claim_resource(dev, idx); + } } EXPORT_SYMBOL_GPL(pcibios_fixup_device_resources); static void pcibios_fixup_bridge_resources(struct pci_dev *dev) { - pcibios_fixup_resources(dev, PCI_BRIDGE_RESOURCES, PCI_NUM_RESOURCES); + int idx; + + if (!dev->bus) + return; + + for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { + struct resource *r = &dev->resource[idx]; + + if (!r->flags || r->parent || !r->start) + continue; + + pci_claim_bridge_resource(dev, idx); + } } /* -- cgit v0.10.2 From 576e4385ff59f52ca0e9a6a953a55f1f76fc196b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:50 -0600 Subject: microblaze/PCI: Clip bridge windows to fit in upstream windows Every PCI-PCI bridge window should fit inside an upstream bridge window because orphaned address space is unreachable from the primary side of the upstream bridge. If we inherit invalid bridge windows that overlap an upstream window from firmware, clip them to fit and update the bridge accordingly. [bhelgaas: changelog] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: Michal Simek CC: Benjamin Herrenschmidt CC: Sebastian Ott diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index b30e41c..48528fb 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -1026,6 +1026,8 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus) pr, (pr && pr->name) ? pr->name : "nil"); if (pr && !(pr->flags & IORESOURCE_UNSET)) { + struct pci_dev *dev = bus->self; + if (request_resource(pr, res) == 0) continue; /* @@ -1035,6 +1037,12 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus) */ if (reparent_resources(pr, res) == 0) continue; + + if (dev && i < PCI_BRIDGE_RESOURCE_NUM && + pci_claim_bridge_resource(dev, + i + PCI_BRIDGE_RESOURCES) == 0) + continue; + } pr_warn("PCI: Cannot allocate resource region "); pr_cont("%d of PCI bridge %d, will remap\n", i, bus->number); @@ -1227,7 +1235,10 @@ void pcibios_claim_one_bus(struct pci_bus *bus) (unsigned long long)r->end, (unsigned int)r->flags); - pci_claim_resource(dev, i); + if (pci_claim_resource(dev, i) == 0) + continue; + + pci_claim_bridge_resource(dev, i); } } -- cgit v0.10.2 From 4e348ba2dd1c1d6ea191566d7591655bbe9dde64 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:50 -0600 Subject: mn10300/PCI: Clip bridge windows to fit in upstream windows Every PCI-PCI bridge window should fit inside an upstream bridge window because orphaned address space is unreachable from the primary side of the upstream bridge. If we inherit invalid bridge windows that overlap an upstream window from firmware, clip them to fit and update the bridge accordingly. [bhelgaas: changelog] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: David Howells CC: Koichi Yasutake CC: linux-am33-list@redhat.com diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c index febb9cd..b5b036f 100644 --- a/arch/mn10300/unit-asb2305/pci-asb2305.c +++ b/arch/mn10300/unit-asb2305/pci-asb2305.c @@ -106,7 +106,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) if (!r->flags) continue; if (!r->start || - pci_claim_resource(dev, idx) < 0) { + pci_claim_bridge_resource(dev, idx) < 0) { printk(KERN_ERR "PCI:" " Cannot allocate resource" " region %d of bridge %s\n", diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index 6b4339f..471ff39 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c @@ -281,42 +281,37 @@ static int __init pci_check_direct(void) return -ENODEV; } -static int is_valid_resource(struct pci_dev *dev, int idx) +static void pcibios_fixup_device_resources(struct pci_dev *dev) { - unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; - struct resource *devr = &dev->resource[idx], *busr; - - if (dev->bus) { - pci_bus_for_each_resource(dev->bus, busr, i) { - if (!busr || (busr->flags ^ devr->flags) & type_mask) - continue; - - if (devr->start && - devr->start >= busr->start && - devr->end <= busr->end) - return 1; - } - } + int idx; - return 0; + if (!dev->bus) + return; + + for (idx = 0; idx < PCI_BRIDGE_RESOURCES; idx++) { + struct resource *r = &dev->resource[idx]; + + if (!r->flags || r->parent || !r->start) + continue; + + pci_claim_resource(dev, idx); + } } -static void pcibios_fixup_device_resources(struct pci_dev *dev) +static void pcibios_fixup_bridge_resources(struct pci_dev *dev) { - int limit, i; + int idx; - if (dev->bus->number != 0) + if (!dev->bus) return; - limit = (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) ? - PCI_BRIDGE_RESOURCES : PCI_NUM_RESOURCES; + for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { + struct resource *r = &dev->resource[idx]; - for (i = 0; i < limit; i++) { - if (!dev->resource[i].flags) + if (!r->flags || r->parent || !r->start) continue; - if (is_valid_resource(dev, i)) - pci_claim_resource(dev, i); + pci_claim_bridge_resource(dev, idx); } } @@ -330,7 +325,7 @@ void pcibios_fixup_bus(struct pci_bus *bus) if (bus->self) { pci_read_bridge_bases(bus); - pcibios_fixup_device_resources(bus->self); + pcibios_fixup_bridge_resources(bus->self); } list_for_each_entry(dev, &bus->devices, bus_list) -- cgit v0.10.2 From 2e5e804a836ec89e126443c8efe666b56e4e58a9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:50 -0600 Subject: parisc/PCI: Clip bridge windows to fit in upstream windows Every PCI-PCI bridge window should fit inside an upstream bridge window because orphaned address space is unreachable from the primary side of the upstream bridge. If we inherit invalid bridge windows that overlap an upstream window from firmware, clip them to fit and update the bridge accordingly. [bhelgaas: changelog] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: "James E.J. Bottomley" CC: Helge Deller CC: linux-parisc@vger.kernel.org diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 37e71ff..dceb9dd 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -694,9 +694,8 @@ lba_fixup_bus(struct pci_bus *bus) int i; /* PCI-PCI Bridge */ pci_read_bridge_bases(bus); - for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { - pci_claim_resource(bus->self, i); - } + for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) + pci_claim_bridge_resource(bus->self, i); } else { /* Host-PCI Bridge */ int err; -- cgit v0.10.2 From 3ebfe46ac72c0bda0fee3d33dd4cfe88f43cefd9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:51 -0600 Subject: powerpc/PCI: Clip bridge windows to fit in upstream windows Every PCI-PCI bridge window should fit inside an upstream bridge window because orphaned address space is unreachable from the primary side of the upstream bridge. If we inherit invalid bridge windows that overlap an upstream window from firmware, clip them to fit and update the bridge accordingly. [bhelgaas: changelog] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas CC: Benjamin Herrenschmidt CC: Paul Mackerras CC: Michael Ellerman CC: Gavin Shan CC: Anton Blanchard CC: Sebastian Ott CC: Wei Yang CC: Andrew Murray CC: linuxppc-dev@lists.ozlabs.org diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 37d512d..2a525c9 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1184,6 +1184,8 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus) pr, (pr && pr->name) ? pr->name : "nil"); if (pr && !(pr->flags & IORESOURCE_UNSET)) { + struct pci_dev *dev = bus->self; + if (request_resource(pr, res) == 0) continue; /* @@ -1193,6 +1195,11 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus) */ if (reparent_resources(pr, res) == 0) continue; + + if (dev && i < PCI_BRIDGE_RESOURCE_NUM && + pci_claim_bridge_resource(dev, + i + PCI_BRIDGE_RESOURCES) == 0) + continue; } pr_warning("PCI: Cannot allocate resource region " "%d of PCI bridge %d, will remap\n", i, bus->number); @@ -1401,7 +1408,10 @@ void pcibios_claim_one_bus(struct pci_bus *bus) (unsigned long long)r->end, (unsigned int)r->flags); - pci_claim_resource(dev, i); + if (pci_claim_resource(dev, i) == 0) + continue; + + pci_claim_bridge_resource(dev, i); } } -- cgit v0.10.2 From d63e2e1f3df904bf6bd150bdafb42ddbb3257ea8 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 15 Jan 2015 16:21:51 -0600 Subject: sparc/PCI: Clip bridge windows to fit in upstream windows Every PCI-PCI bridge window should fit inside an upstream bridge window because orphaned address space is unreachable from the primary side of the upstream bridge. If we inherit invalid bridge windows that overlap an upstream window from firmware, clip them to fit and update the bridge accordingly. [bhelgaas: changelog] Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 Reported-by: Marek Kordik Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas Acked-by: David S. Miller CC: Paul Gortmaker CC: Yijing Wang CC: Sam Ravnborg CC: sparclinux@vger.kernel.org diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index b36365f..9ce5afe 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -639,7 +639,10 @@ static void pci_claim_bus_resources(struct pci_bus *bus) (unsigned long long)r->end, (unsigned int)r->flags); - pci_claim_resource(dev, i); + if (pci_claim_resource(dev, i) == 0) + continue; + + pci_claim_bridge_resource(dev, i); } } -- cgit v0.10.2 From 29187a9eeaf362d8422e62e17a22a6e115277a49 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 16 Jan 2015 14:21:16 -0500 Subject: workqueue: fix subtle pool management issue which can stall whole worker_pool A worker_pool's forward progress is guaranteed by the fact that the last idle worker assumes the manager role to create more workers and summon the rescuers if creating workers doesn't succeed in timely manner before proceeding to execute work items. This manager role is implemented in manage_workers(), which indicates whether the worker may proceed to work item execution with its return value. This is necessary because multiple workers may contend for the manager role, and, if there already is a manager, others should proceed to work item execution. Unfortunately, the function also indicates that the worker may proceed to work item execution if need_to_create_worker() is false at the head of the function. need_to_create_worker() tests the following conditions. pending work items && !nr_running && !nr_idle The first and third conditions are protected by pool->lock and thus won't change while holding pool->lock; however, nr_running can change asynchronously as other workers block and resume and while it's likely to be zero, as someone woke this worker up in the first place, some other workers could have become runnable inbetween making it non-zero. If this happens, manage_worker() could return false even with zero nr_idle making the worker, the last idle one, proceed to execute work items. If then all workers of the pool end up blocking on a resource which can only be released by a work item which is pending on that pool, the whole pool can deadlock as there's no one to create more workers or summon the rescuers. This patch fixes the problem by removing the early exit condition from maybe_create_worker() and making manage_workers() return false iff there's already another manager, which ensures that the last worker doesn't start executing work items. We can leave the early exit condition alone and just ignore the return value but the only reason it was put there is because the manage_workers() used to perform both creations and destructions of workers and thus the function may be invoked while the pool is trying to reduce the number of workers. Now that manage_workers() is called only when more workers are needed, the only case this early exit condition is triggered is rare race conditions rendering it pointless. Tested with simulated workload and modified workqueue code which trigger the pool deadlock reliably without this patch. Signed-off-by: Tejun Heo Reported-by: Eric Sandeen Link: http://lkml.kernel.org/g/54B019F4.8030009@sandeen.net Cc: Dave Chinner Cc: Lai Jiangshan Cc: stable@vger.kernel.org diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 6202b08..beeeac9 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -1841,17 +1841,11 @@ static void pool_mayday_timeout(unsigned long __pool) * spin_lock_irq(pool->lock) which may be released and regrabbed * multiple times. Does GFP_KERNEL allocations. Called only from * manager. - * - * Return: - * %false if no action was taken and pool->lock stayed locked, %true - * otherwise. */ -static bool maybe_create_worker(struct worker_pool *pool) +static void maybe_create_worker(struct worker_pool *pool) __releases(&pool->lock) __acquires(&pool->lock) { - if (!need_to_create_worker(pool)) - return false; restart: spin_unlock_irq(&pool->lock); @@ -1877,7 +1871,6 @@ restart: */ if (need_to_create_worker(pool)) goto restart; - return true; } /** @@ -1897,16 +1890,14 @@ restart: * multiple times. Does GFP_KERNEL allocations. * * Return: - * %false if the pool don't need management and the caller can safely start - * processing works, %true indicates that the function released pool->lock - * and reacquired it to perform some management function and that the - * conditions that the caller verified while holding the lock before - * calling the function might no longer be true. + * %false if the pool doesn't need management and the caller can safely + * start processing works, %true if management function was performed and + * the conditions that the caller verified before calling the function may + * no longer be true. */ static bool manage_workers(struct worker *worker) { struct worker_pool *pool = worker->pool; - bool ret = false; /* * Anyone who successfully grabs manager_arb wins the arbitration @@ -1919,12 +1910,12 @@ static bool manage_workers(struct worker *worker) * actual management, the pool may stall indefinitely. */ if (!mutex_trylock(&pool->manager_arb)) - return ret; + return false; - ret |= maybe_create_worker(pool); + maybe_create_worker(pool); mutex_unlock(&pool->manager_arb); - return ret; + return true; } /** -- cgit v0.10.2 From 7949ba1fa249caa7e611abb8d92f40b0a46c8617 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Sat, 10 Jan 2015 19:33:48 +0900 Subject: perf probe: Propagate error code when write(2) failed When it failed to write probe commands to the probe_event file in debugfs, it needs to propagate the error code properly. Current code blindly uses the return value of the write(2) so it always uses -1 (-EPERM) and it might confuse users. Signed-off-by: Namhyung Kim Acked-by: Masami Hiramatsu Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1420886028-15135-4-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 7f9b863..94a717b 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2052,9 +2052,11 @@ static int write_probe_trace_event(int fd, struct probe_trace_event *tev) pr_debug("Writing event: %s\n", buf); if (!probe_event_dry_run) { ret = write(fd, buf, strlen(buf)); - if (ret <= 0) + if (ret <= 0) { + ret = -errno; pr_warning("Failed to write event: %s\n", strerror_r(errno, sbuf, sizeof(sbuf))); + } } free(buf); return ret; -- cgit v0.10.2 From c6e5e9fbc3ea1c1a5648a3498d085fc3978df2d4 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 12 Jan 2015 10:20:55 +0800 Subject: perf tools: Fix building error in x86_64 when dwarf unwind is on When build with 'make ARCH=x86' and dwarf unwind is on, there is a compiling error: CC /home/wn/perf/arch/x86/util/unwind-libdw.o CC /home/wn/perf/arch/x86/tests/regs_load.o arch/x86/tests/regs_load.S: Assembler messages: arch/x86/tests/regs_load.S:65: Error: operand type mismatch for `push' arch/x86/tests/regs_load.S:72: Error: operand type mismatch for `pop' make[1]: *** [/home/wn/perf/arch/x86/tests/regs_load.o] Error 1 make[1]: INTERNAL: Exiting with 25 jobserver tokens available; should be 24! make: *** [all] Error 2 ... Which is caused by incorrectly undefine macro HAVE_ARCH_X86_64_SUPPORT. 'config/Makefile.arch' tests __x86_64__ only when 'ARCH=x86_64'. However, when building x86_64 kernel, ARCH=x86 is valid and commonly used. Build systems, such as yocto, uses x86_64 compiler with 'ARCH=x86' to build x86_64 perf, which causes mismatching. As __LP64__ is defined for x86_64 as well, we can consolidate the __x86_64__ check to the __LP64__ check and get rid of the IS_X86_64 IMHO. (This patch is made by Namhyung Kim when replying my v1 patch: https://lkml.org/lkml/2015/1/7/17 I modified the code to remove dependency on RAW_ARCH: https://lkml.org/lkml/2015/1/7/865 Namhyung Kim didn't provide his SOB in his original email. I add mine only for my modification.) Signed-off-by: Namhyung Kim Signed-off-by: Wang Nan Acked-by: Jiri Olsa Cc: Jiri Olsa Cc: Li Zefan Cc: Ingo Molnar Cc: Namhyung Kim Link: http://lkml.kernel.org/r/1421029255-23039-1-git-send-email-wangnan0@huawei.com [ Namhyung provided his S-o-B on a followup to this patch thread on lkml ] Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 67a03a82..1f71a32 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -462,10 +462,12 @@ BUILTIN_OBJS += $(OUTPUT)builtin-bench.o # Benchmark modules BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o -ifeq ($(RAW_ARCH),x86_64) +ifeq ($(ARCH), x86) +ifeq ($(IS_64_BIT), 1) BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o endif +endif BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 5d4b039..648e31f 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -20,7 +20,7 @@ NO_PERF_REGS := 1 # Additional ARCH settings for x86 ifeq ($(ARCH),x86) - ifeq (${IS_X86_64}, 1) + ifeq (${IS_64_BIT}, 1) CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 diff --git a/tools/perf/config/Makefile.arch b/tools/perf/config/Makefile.arch index 851cd01..ff95a68 100644 --- a/tools/perf/config/Makefile.arch +++ b/tools/perf/config/Makefile.arch @@ -1,7 +1,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not) -ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ +RAW_ARCH := $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ -e s/arm.*/arm/ -e s/sa110/arm/ \ -e s/s390x/s390/ -e s/parisc64/parisc/ \ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ @@ -9,23 +9,23 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ -e s/tile.*/tile/ ) # Additional ARCH settings for x86 -ifeq ($(ARCH),i386) - override ARCH := x86 +ifeq ($(RAW_ARCH),i386) + ARCH ?= x86 endif -ifeq ($(ARCH),x86_64) - override ARCH := x86 - IS_X86_64 := 0 - ifeq (, $(findstring m32,$(CFLAGS))) - IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1) - RAW_ARCH := x86_64 +ifeq ($(RAW_ARCH),x86_64) + ARCH ?= x86 + + ifneq (, $(findstring m32,$(CFLAGS))) + RAW_ARCH := x86_32 endif endif -ifeq (${IS_X86_64}, 1) +ARCH ?= $(RAW_ARCH) + +LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) +ifeq ($(LP64), 1) IS_64_BIT := 1 -else ifeq ($(ARCH),x86) - IS_64_BIT := 0 else - IS_64_BIT := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) + IS_64_BIT := 0 endif -- cgit v0.10.2 From 260d819e3abdbdaa2b88fb983d1314f1b263f9e2 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 9 Jan 2015 09:38:12 +0900 Subject: perf machine: Fix __machine__findnew_thread() error path When thread__init_map_groups() fails, a new thread should be removed from the rbtree since it's gonna be freed. Also update last match cache only if the function succeeded. Reported-by: David Ahern Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1420763892-15535-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 94de3e4..1bca3a9 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -389,7 +389,6 @@ static struct thread *__machine__findnew_thread(struct machine *machine, if (th != NULL) { rb_link_node(&th->rb_node, parent, p); rb_insert_color(&th->rb_node, &machine->threads); - machine->last_match = th; /* * We have to initialize map_groups separately @@ -400,9 +399,12 @@ static struct thread *__machine__findnew_thread(struct machine *machine, * leader and that would screwed the rb tree. */ if (thread__init_map_groups(th, machine)) { + rb_erase(&th->rb_node, &machine->threads); thread__delete(th); return NULL; } + + machine->last_match = th; } return th; -- cgit v0.10.2 From 25cd480e447eba47b8bdad1c9f95cadc074abc75 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 13 Jan 2015 10:19:12 -0300 Subject: tools: Remove bitops/hweight usage of bits in tools/perf We need to use lib/hweight.c for that, just like we do for lib/rbtree.c, so tools need to link hweight.o. For now do it directly, but we need to have a tools/lib/lk.a or .so that collects these goodies... Reported-by: Jan Beulich Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-a1e91dx3apzqw5kbdt7ut21s@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/include/asm-generic/bitops.h b/tools/include/asm-generic/bitops.h index 6eedba1..653d1ba 100644 --- a/tools/include/asm-generic/bitops.h +++ b/tools/include/asm-generic/bitops.h @@ -22,6 +22,8 @@ #error only can be included directly #endif +#include + #include #endif /* __TOOLS_ASM_GENERIC_BITOPS_H */ diff --git a/tools/include/asm-generic/bitops/arch_hweight.h b/tools/include/asm-generic/bitops/arch_hweight.h new file mode 100644 index 0000000..318bb2b --- /dev/null +++ b/tools/include/asm-generic/bitops/arch_hweight.h @@ -0,0 +1 @@ +#include "../../../../include/asm-generic/bitops/arch_hweight.h" diff --git a/tools/include/asm-generic/bitops/const_hweight.h b/tools/include/asm-generic/bitops/const_hweight.h new file mode 100644 index 0000000..0afd644 --- /dev/null +++ b/tools/include/asm-generic/bitops/const_hweight.h @@ -0,0 +1 @@ +#include "../../../../include/asm-generic/bitops/const_hweight.h" diff --git a/tools/include/asm-generic/bitops/hweight.h b/tools/include/asm-generic/bitops/hweight.h new file mode 100644 index 0000000..290120c --- /dev/null +++ b/tools/include/asm-generic/bitops/hweight.h @@ -0,0 +1,7 @@ +#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_HWEIGHT_H_ +#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_HWEIGHT_H_ + +#include +#include + +#endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS_HWEIGHT_H_ */ diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h index 26005a15..5ad9ee1 100644 --- a/tools/include/linux/bitops.h +++ b/tools/include/linux/bitops.h @@ -1,9 +1,9 @@ #ifndef _TOOLS_LINUX_BITOPS_H_ #define _TOOLS_LINUX_BITOPS_H_ +#include #include #include -#include #ifndef __WORDSIZE #define __WORDSIZE (__SIZEOF_LONG__ * 8) @@ -19,6 +19,11 @@ #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) #define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE) +extern unsigned int __sw_hweight8(unsigned int w); +extern unsigned int __sw_hweight16(unsigned int w); +extern unsigned int __sw_hweight32(unsigned int w); +extern unsigned long __sw_hweight64(__u64 w); + /* * Include this here because some architectures need generic_ffs/fls in * scope diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 83e2887..fbbfdc3 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -6,12 +6,15 @@ tools/lib/symbol/kallsyms.c tools/lib/symbol/kallsyms.h tools/lib/util/find_next_bit.c tools/include/asm/bug.h +tools/include/asm-generic/bitops/arch_hweight.h tools/include/asm-generic/bitops/atomic.h +tools/include/asm-generic/bitops/const_hweight.h tools/include/asm-generic/bitops/__ffs.h tools/include/asm-generic/bitops/__fls.h tools/include/asm-generic/bitops/find.h tools/include/asm-generic/bitops/fls64.h tools/include/asm-generic/bitops/fls.h +tools/include/asm-generic/bitops/hweight.h tools/include/asm-generic/bitops.h tools/include/linux/bitops.h tools/include/linux/compiler.h @@ -19,6 +22,8 @@ tools/include/linux/export.h tools/include/linux/hash.h tools/include/linux/log2.h tools/include/linux/types.h +include/asm-generic/bitops/arch_hweight.h +include/asm-generic/bitops/const_hweight.h include/asm-generic/bitops/fls64.h include/asm-generic/bitops/__fls.h include/asm-generic/bitops/fls.h @@ -29,6 +34,7 @@ include/linux/list.h include/linux/hash.h include/linux/stringify.h lib/find_next_bit.c +lib/hweight.c lib/rbtree.c include/linux/swab.h arch/*/include/asm/unistd*.h diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 1f71a32..aa6a504 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -232,12 +232,15 @@ LIB_H += ../include/linux/hash.h LIB_H += ../../include/linux/stringify.h LIB_H += util/include/linux/bitmap.h LIB_H += ../include/linux/bitops.h +LIB_H += ../include/asm-generic/bitops/arch_hweight.h LIB_H += ../include/asm-generic/bitops/atomic.h +LIB_H += ../include/asm-generic/bitops/const_hweight.h LIB_H += ../include/asm-generic/bitops/find.h LIB_H += ../include/asm-generic/bitops/fls64.h LIB_H += ../include/asm-generic/bitops/fls.h LIB_H += ../include/asm-generic/bitops/__ffs.h LIB_H += ../include/asm-generic/bitops/__fls.h +LIB_H += ../include/asm-generic/bitops/hweight.h LIB_H += ../include/asm-generic/bitops.h LIB_H += ../include/linux/compiler.h LIB_H += ../include/linux/log2.h @@ -255,7 +258,6 @@ LIB_H += util/include/linux/linkage.h LIB_H += util/include/asm/asm-offsets.h LIB_H += ../include/asm/bug.h LIB_H += util/include/asm/byteorder.h -LIB_H += util/include/asm/hweight.h LIB_H += util/include/asm/swab.h LIB_H += util/include/asm/system.h LIB_H += util/include/asm/uaccess.h @@ -745,6 +747,9 @@ $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< +$(OUTPUT)util/hweight.o: ../../lib/hweight.c $(OUTPUT)PERF-CFLAGS + $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< + $(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< diff --git a/tools/perf/util/hweight.c b/tools/perf/util/hweight.c deleted file mode 100644 index 5c1d0d0..0000000 --- a/tools/perf/util/hweight.c +++ /dev/null @@ -1,31 +0,0 @@ -#include - -/** - * hweightN - returns the hamming weight of a N-bit word - * @x: the word to weigh - * - * The Hamming Weight of a number is the total number of bits set in it. - */ - -unsigned int hweight32(unsigned int w) -{ - unsigned int res = w - ((w >> 1) & 0x55555555); - res = (res & 0x33333333) + ((res >> 2) & 0x33333333); - res = (res + (res >> 4)) & 0x0F0F0F0F; - res = res + (res >> 8); - return (res + (res >> 16)) & 0x000000FF; -} - -unsigned long hweight64(__u64 w) -{ -#if BITS_PER_LONG == 32 - return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); -#elif BITS_PER_LONG == 64 - __u64 res = w - ((w >> 1) & 0x5555555555555555ul); - res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); - res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful; - res = res + (res >> 8); - res = res + (res >> 16); - return (res + (res >> 32)) & 0x00000000000000FFul; -#endif -} diff --git a/tools/perf/util/include/asm/hweight.h b/tools/perf/util/include/asm/hweight.h deleted file mode 100644 index 36cf26d..0000000 --- a/tools/perf/util/include/asm/hweight.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PERF_HWEIGHT_H -#define PERF_HWEIGHT_H - -#include -unsigned int hweight32(unsigned int w); -unsigned long hweight64(__u64 w); - -#endif /* PERF_HWEIGHT_H */ diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 16a475a..6c6a695 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -10,7 +10,7 @@ util/ctype.c util/evlist.c util/evsel.c util/cpumap.c -util/hweight.c +../../lib/hweight.c util/thread_map.c util/util.c util/xyarray.c -- cgit v0.10.2 From db1806edcfef007d9594435a331dcf7e7f1b8fac Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Sat, 10 Jan 2015 16:40:50 +0530 Subject: perf tools: Fix statfs.f_type data type mismatch build error with uclibc ARC Linux uses the no legacy syscalls abi and corresponding uClibc headers statfs defines f_type to be U32 which causes perf build breakage http://git.uclibc.org/uClibc/tree/libc/sysdeps/linux/common-generic/bits/statfs.h ----------->8--------------- CC fs/fs.o fs/fs.c: In function 'fs__valid_mount': fs/fs.c:82:24: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare] else if (st_fs.f_type != magic) ^ cc1: all warnings being treated as errors ----------->8--------------- Signed-off-by: Alexey Brodkin Acked-by: Jiri Olsa Cc: Borislav Petkov Cc: Cody P Schafer Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Vineet Gupta Link: http://lkml.kernel.org/r/1420888254-17504-2-git-send-email-vgupta@synopsys.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c index a74fba6..86ea2d7 100644 --- a/tools/lib/api/fs/debugfs.c +++ b/tools/lib/api/fs/debugfs.c @@ -67,7 +67,7 @@ int debugfs_valid_mountpoint(const char *debugfs) if (statfs(debugfs, &st_fs) < 0) return -ENOENT; - else if (st_fs.f_type != (long) DEBUGFS_MAGIC) + else if ((long)st_fs.f_type != (long)DEBUGFS_MAGIC) return -ENOENT; return 0; diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c index 65d9be3..128ef63 100644 --- a/tools/lib/api/fs/fs.c +++ b/tools/lib/api/fs/fs.c @@ -79,7 +79,7 @@ static int fs__valid_mount(const char *fs, long magic) if (statfs(fs, &st_fs) < 0) return -ENOENT; - else if (st_fs.f_type != magic) + else if ((long)st_fs.f_type != magic) return -ENOENT; return 0; -- cgit v0.10.2 From a83d869f300bf91df07443b5272db7a5a8eb18b7 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Tue, 13 Jan 2015 19:13:21 +0530 Subject: perf tools: Elide strlcpy warning with uclibc ----------------->8------------------ CC bench/sched-pipe.o In file included from builtin-annotate.c:13:0: util/cache.h:76:15: warning: redundant redeclaration of 'strlcpy' [-Wredundant-decls] extern size_t strlcpy(char *dest, const char *src, size_t size); ^ In file included from util/util.h:55:0, from builtin.h:4, from builtin-annotate.c:8: ~/vineetg/arc/gnu/INSTALL_1412-arc-2014.12-rc1/arc-snps-linux-uclibc/sysroot/usr/include/string.h:396:15: note: previous declaration of 'strlcpy' was here extern size_t strlcpy(char *__restrict dst, const char *__restrict src, ----------------->8------------------ Signed-off-by: Vineet Gupta Cc: Alexey Brodkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1421156604-30603-3-git-send-email-vgupta@synopsys.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 5cf9e1b..d04d770 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -71,7 +71,9 @@ extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2 extern char *perf_pathdup(const char *fmt, ...) __attribute__((format (printf, 1, 2))); +#ifndef __UCLIBC__ /* Matches the libc/libbsd function attribute so we declare this unconditionally: */ extern size_t strlcpy(char *dest, const char *src, size_t size); +#endif #endif /* __PERF_CACHE_H */ -- cgit v0.10.2 From ea1fe3a88763d4dfef7e2529ba606f96e8e6b271 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Tue, 13 Jan 2015 19:13:22 +0530 Subject: perf tools: Avoid build splat for syscall numbers with uclibc This is due to duplicated unistd inclusion (via uClibc headers + kernel headers) Also seen on ARM uClibc based tools ------- ARC build ---------->8------------- CC util/evlist.o In file included from ~/arc/k.org/arch/arc/include/uapi/asm/unistd.h:25:0, from util/../perf-sys.h:10, from util/../perf.h:15, from util/event.h:7, from util/event.c:3: ~/arc/k.org/include/uapi/asm-generic/unistd.h:906:0: warning: "__NR_fcntl64" redefined [enabled by default] #define __NR_fcntl64 __NR3264_fcntl ^ In file included from ~/arc/gnu/INSTALL_1412-arc-2014.12-rc1/arc-snps-linux-uclibc/sysroot/usr/include/sys/syscall.h:24:0, from util/../perf-sys.h:6, ----------------->8------------------- ------- ARM build ---------->8------------- CC FPIC plugin_scsi.o In file included from util/../perf-sys.h:9:0, from util/../perf.h:15, from util/cache.h:7, from perf.c:12: ~/arc/k.org/arch/arm/include/uapi/asm/unistd.h:28:0: warning: "__NR_restart_syscall" redefined [enabled by default] In file included from ~/buildroot/host/usr/arm-buildroot-linux-uclibcgnueabi/sysroot/usr/include/sys/syscall.h:25:0, from util/../perf-sys.h:6, from util/../perf.h:15, from util/cache.h:7, from perf.c:12: ~/buildroot/host/usr/arm-buildroot-linux-uclibcgnueabi/sysroot/usr/include/bits/sysnum.h:17:0: note: this is the location of the previous definition ----------------->8------------------- Signed-off-by: Vineet Gupta Cc: Alexey Brodkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1421156604-30603-4-git-send-email-vgupta@synopsys.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index 07a8d76..005cc28 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c @@ -19,12 +19,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 961cea1..616f0fc 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -66,7 +66,6 @@ #include #include -#include #include static volatile int done; diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h index a3b13d7..6ef6816 100644 --- a/tools/perf/perf-sys.h +++ b/tools/perf/perf-sys.h @@ -6,7 +6,6 @@ #include #include #include -#include #if defined(__i386__) #define mb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") -- cgit v0.10.2 From b93b0967826a4a00297dde1cbbda8df673c1689e Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Wed, 14 Jan 2015 10:36:47 +0800 Subject: perf test: Fix dwarf unwind using libunwind. Perf tool fails to unwind user stack if the event raises in a shared object. This patch improves tests/dwarf-unwind.c to demonstrate the problem by utilizing commonly used glibc function "bsearch". If perf is not statically linked, the testcase will try to unwind a mixed call trace. By debugging libunwind I found that there is a bug in unwind-libunwind: it always passes 0 as segbase to libunwind, cause libunwind unable to locate debug_frame entry fir first level ip address (I add some more debugging output into libunwind to make things clear): >_Uarm_dwarf_find_debug_frame: start_ip = 10be98, end_ip = 10c2a4 >_Uarm_dwarf_find_debug_frame: found debug_frame table `/lib/libc-2.18.so': segbase=0x0, len=7, gp=0x0, table_data=0x449388 >_Uarm_dwarf_search_unwind_table: call lookup:ip = b6cd3bcc, segbase = 0, rel_ip = b6cd3bcc >lookup: e->start_ip_offset = bcf18 (rel_ip = b6cd3bcc) >lookup: e->start_ip_offset = 6d314 (rel_ip = b6cd3bcc) >lookup: e->start_ip_offset = 33d0c (rel_ip = b6cd3bcc) ... >lookup: e->start_ip_offset = 15d0c (rel_ip = b6cd3bcc) >lookup: e->start_ip_offset = 15c40 (rel_ip = b6cd3bcc) >_Uarm_dwarf_search_unwind_table: IP b6cd3bcc inside range b6c12000-b6d4c000, but no explicit unwind info found >put_rs_cache: unmasking signals/interrupts and releasing lock >_Uarm_dwarf_step: returning -10 >_Uarm_step: dwarf_step()=-10 This patch passes map->start as segbase to dwarf_find_debug_frame(), so di will be initialized correctly. In addition, dso and executable are different when setting segbase. This patch first check whether the elf is executable, and pass segbase only for shared object. Signed-off-by: Wang Nan Acked-by: Jiri Olsa Cc: Ingo Molnar Cc: Jiri Olsa Cc: Li Zefan Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1421203007-75799-1-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index ab28cca..0bf06be 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -11,6 +11,9 @@ #include "thread.h" #include "callchain.h" +/* For bsearch. We try to unwind functions in shared object. */ +#include + static int mmap_handler(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused, @@ -28,7 +31,7 @@ static int init_live_machine(struct machine *machine) mmap_handler, machine, true); } -#define MAX_STACK 6 +#define MAX_STACK 8 static int unwind_entry(struct unwind_entry *entry, void *arg) { @@ -37,6 +40,8 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) static const char *funcs[MAX_STACK] = { "test__arch_unwind_sample", "unwind_thread", + "compare", + "bsearch", "krava_3", "krava_2", "krava_1", @@ -88,10 +93,37 @@ static int unwind_thread(struct thread *thread) return err; } +static int global_unwind_retval = -INT_MAX; + +__attribute__ ((noinline)) +static int compare(void *p1, void *p2) +{ + /* Any possible value should be 'thread' */ + struct thread *thread = *(struct thread **)p1; + + if (global_unwind_retval == -INT_MAX) + global_unwind_retval = unwind_thread(thread); + + return p1 - p2; +} + __attribute__ ((noinline)) static int krava_3(struct thread *thread) { - return unwind_thread(thread); + struct thread *array[2] = {thread, thread}; + void *fp = &bsearch; + /* + * make _bsearch a volatile function pointer to + * prevent potential optimization, which may expand + * bsearch and call compare directly from this function, + * instead of libc shared object. + */ + void *(*volatile _bsearch)(void *, void *, size_t, + size_t, int (*)(void *, void *)); + + _bsearch = fp; + _bsearch(array, &thread, 2, sizeof(struct thread **), compare); + return global_unwind_retval; } __attribute__ ((noinline)) diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 371219a..6edf535 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -185,6 +185,28 @@ static u64 elf_section_offset(int fd, const char *name) return offset; } +#ifndef NO_LIBUNWIND_DEBUG_FRAME +static int elf_is_exec(int fd, const char *name) +{ + Elf *elf; + GElf_Ehdr ehdr; + int retval = 0; + + elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); + if (elf == NULL) + return 0; + if (gelf_getehdr(elf, &ehdr) == NULL) + goto out; + + retval = (ehdr.e_type == ET_EXEC); + +out: + elf_end(elf); + pr_debug("unwind: elf_is_exec(%s): %d\n", name, retval); + return retval; +} +#endif + struct table_entry { u32 start_ip_offset; u32 fde_offset; @@ -322,8 +344,12 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, #ifndef NO_LIBUNWIND_DEBUG_FRAME /* Check the .debug_frame section for unwinding info */ if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { + int fd = dso__data_fd(map->dso, ui->machine); + int is_exec = elf_is_exec(fd, map->dso->name); + unw_word_t base = is_exec ? 0 : map->start; + memset(&di, 0, sizeof(di)); - if (dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name, + if (dwarf_find_debug_frame(0, &di, ip, base, map->dso->name, map->start, map->end)) return dwarf_search_unwind_table(as, ip, &di, pi, need_unwind_info, arg); -- cgit v0.10.2 From 813ccd15452ed34e97aa526ffc70d6d8e6c466c5 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 14 Jan 2015 20:18:05 +0900 Subject: perf tools: Fix segfault for symbol annotation on TUI Currently the symbol structure is allocated with symbol_conf.priv_size to carry sideband information like annotation, map browser on TUI and sort-by-name tree node. So retrieving these information from symbol needs to care about the details of such placement. However the annotation code just assumes that the symbol is placed after the struct annotation. But actually there's other info between them. So accessing those struct will lead to an undefined behavior (usually a crash) after they write their info to the same location. To reproduce the problem, please follow the steps below: 1. run perf report (TUI of course) with -v option 2. open map browser (by pressing right arrow key for any entry) 3. search any function (by pressing '/' key and input whatever..) 4. return to the hist browser (by pressing 'q' or left arrow key) 5. open annotation window for the same entry (by pressing 'a' key) Signed-off-by: Namhyung Kim Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1421234288-22758-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 0784a94..cadbdc9 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -116,11 +116,6 @@ struct annotation { struct annotated_source *src; }; -struct sannotation { - struct annotation annotation; - struct symbol symbol; -}; - static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx) { return (((void *)¬es->src->histograms) + @@ -129,8 +124,7 @@ static inline struct sym_hist *annotation__histogram(struct annotation *notes, i static inline struct annotation *symbol__annotation(struct symbol *sym) { - struct sannotation *a = container_of(sym, struct sannotation, symbol); - return &a->annotation; + return (void *)sym - symbol_conf.priv_size; } int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx); -- cgit v0.10.2 From 6bcf9c1ff3ec22fd81eba336737d9865476509b1 Mon Sep 17 00:00:00 2001 From: Sukadev Bhattiprolu Date: Fri, 21 Nov 2014 20:33:53 -0500 Subject: perf tools powerpc: Use dwfl_report_elf() instead of offline. dwfl_report_offline() works only when libraries are prelinked. Replace dwfl_report_offline() with dwfl_report_elf() so we correctly extract debug info even from libraries that are not prelinked. Reported-by: Jiri Olsa Signed-off-by: Sukadev Bhattiprolu Tested-by: Jiri Olsa Cc: Jiri Olsa Cc: Michael Ellerman Link: http://lkml.kernel.org/r/20150114221045.GA17703@us.ibm.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index 3bb50ea..0c370f8 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c @@ -103,7 +103,7 @@ static Dwarf_Frame *get_eh_frame(Dwfl_Module *mod, Dwarf_Addr pc) return NULL; } - result = dwarf_cfi_addrframe(cfi, pc, &frame); + result = dwarf_cfi_addrframe(cfi, pc-bias, &frame); if (result) { pr_debug("%s(): %s\n", __func__, dwfl_errmsg(-1)); return NULL; @@ -128,7 +128,7 @@ static Dwarf_Frame *get_dwarf_frame(Dwfl_Module *mod, Dwarf_Addr pc) return NULL; } - result = dwarf_cfi_addrframe(cfi, pc, &frame); + result = dwarf_cfi_addrframe(cfi, pc-bias, &frame); if (result) { pr_debug("%s(): %s\n", __func__, dwfl_errmsg(-1)); return NULL; @@ -145,7 +145,7 @@ static Dwarf_Frame *get_dwarf_frame(Dwfl_Module *mod, Dwarf_Addr pc) * yet used) * -1 in case of errors */ -static int check_return_addr(struct dso *dso, Dwarf_Addr pc) +static int check_return_addr(struct dso *dso, u64 map_start, Dwarf_Addr pc) { int rc = -1; Dwfl *dwfl; @@ -155,6 +155,7 @@ static int check_return_addr(struct dso *dso, Dwarf_Addr pc) Dwarf_Addr start = pc; Dwarf_Addr end = pc; bool signalp; + const char *exec_file = dso->long_name; dwfl = dso->dwfl; @@ -165,8 +166,10 @@ static int check_return_addr(struct dso *dso, Dwarf_Addr pc) return -1; } - if (dwfl_report_offline(dwfl, "", dso->long_name, -1) == NULL) { - pr_debug("dwfl_report_offline() failed %s\n", + mod = dwfl_report_elf(dwfl, exec_file, exec_file, -1, + map_start, false); + if (!mod) { + pr_debug("dwfl_report_elf() failed %s\n", dwarf_errmsg(-1)); /* * We normally cache the DWARF debug info and never @@ -256,10 +259,10 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain) return skip_slot; } - rc = check_return_addr(dso, ip); + rc = check_return_addr(dso, al.map->start, ip); - pr_debug("DSO %s, nr %" PRIx64 ", ip 0x%" PRIx64 "rc %d\n", - dso->long_name, chain->nr, ip, rc); + pr_debug("[DSO %s, sym %s, ip 0x%" PRIx64 "] rc %d\n", + dso->long_name, al.sym->name, ip, rc); if (rc == 0) { /* -- cgit v0.10.2 From fc7f0dd381720ea5ee5818645f7d0e9dece41cb0 Mon Sep 17 00:00:00 2001 From: Louis Langholtz Date: Thu, 15 Jan 2015 22:04:46 -0700 Subject: kernel: avoid overflow in cmp_range Avoid overflow possibility. [ The overflow is purely theoretical, since this is used for memory ranges that aren't even close to using the full 64 bits, but this is the right thing to do regardless. - Linus ] Signed-off-by: Louis Langholtz Cc: Yinghai Lu Cc: Peter Anvin Cc: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/range.c b/kernel/range.c index 322ea8e..82cfc28 100644 --- a/kernel/range.c +++ b/kernel/range.c @@ -113,12 +113,12 @@ static int cmp_range(const void *x1, const void *x2) { const struct range *r1 = x1; const struct range *r2 = x2; - s64 start1, start2; - start1 = r1->start; - start2 = r2->start; - - return start1 - start2; + if (r1->start < r2->start) + return -1; + if (r1->start > r2->start) + return 1; + return 0; } int clean_sort_range(struct range *range, int az) -- cgit v0.10.2 From 5c697e5b46efea2c0a5da55208bc71db46698fd1 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 25 Nov 2014 22:52:24 +0100 Subject: ALSA: firewire-lib: remove rx_blocks_for_midi quirk There are several devices that expect to receive MIDI data only in the first eight data blocks of a packet. If the driver restricts the data rate to the allowed rate (as mandated by the specification, but not yet implemented by this driver), this happens naturally. Therefore, there is no reason to ever try to use more data packets with any device. Signed-off-by: Clemens Ladisch Reviewed-by: Takashi Sakamoto Tested-by: Takashi Sakamoto Signed-off-by: Takashi Iwai diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 3badc70..ef399ca 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -21,7 +21,13 @@ #define CYCLES_PER_SECOND 8000 #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) -#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ +/* + * Several devices look only at the first eight data blocks. + * In any case, this is more than enough for the MIDI data rate. + */ +#define MAX_MIDI_RX_BLOCKS 8 + +#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ /* isochronous header parameters */ #define ISO_DATA_LENGTH_SHIFT 16 @@ -78,8 +84,6 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, s->callbacked = false; s->sync_slave = NULL; - s->rx_blocks_for_midi = UINT_MAX; - return 0; } EXPORT_SYMBOL(amdtp_stream_init); @@ -474,7 +478,7 @@ static void amdtp_fill_midi(struct amdtp_stream *s, b = (u8 *)&buffer[s->midi_position]; port = (s->data_block_counter + f) % 8; - if ((f >= s->rx_blocks_for_midi) || + if ((f >= MAX_MIDI_RX_BLOCKS) || (s->midi[port] == NULL) || (snd_rawmidi_transmit(s->midi[port], b + 1, 1) <= 0)) b[0] = 0x80; diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index e6e8926..cd4c4df 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -152,9 +152,6 @@ struct amdtp_stream { /* quirk: fixed interval of dbc between previos/current packets. */ unsigned int tx_dbc_interval; - /* quirk: the first count of data blocks in an rx packet for MIDI */ - unsigned int rx_blocks_for_midi; - bool callbacked; wait_queue_head_t callback_wait; struct amdtp_stream *sync_slave; diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c index 1aab0a32..0ebcabf 100644 --- a/sound/firewire/bebob/bebob_stream.c +++ b/sound/firewire/bebob/bebob_stream.c @@ -484,13 +484,6 @@ int snd_bebob_stream_init_duplex(struct snd_bebob *bebob) amdtp_stream_destroy(&bebob->rx_stream); destroy_both_connections(bebob); } - /* - * The firmware for these devices ignore MIDI messages in more than - * first 8 data blocks of an received AMDTP packet. - */ - if (bebob->spec == &maudio_fw410_spec || - bebob->spec == &maudio_special_spec) - bebob->rx_stream.rx_blocks_for_midi = 8; end: return err; } diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index b985fc5..4f440e1 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c @@ -179,11 +179,6 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw) destroy_stream(efw, &efw->tx_stream); goto end; } - /* - * Fireworks ignores MIDI messages in more than first 8 data - * blocks of an received AMDTP packet. - */ - efw->rx_stream.rx_blocks_for_midi = 8; /* set IEC61883 compliant mode (actually not fully compliant...) */ err = snd_efw_command_set_tx_mode(efw, SND_EFW_TRANSPORT_MODE_IEC61883); -- cgit v0.10.2 From 25ca917c0fcdd1d2c4a701905e11751275186310 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 25 Nov 2014 22:54:10 +0100 Subject: ALSA: firewire-lib: limit the MIDI data rate Do no send MIDI bytes at the full rate at which FireWire packets happen to be sent, but restrict them to the actual rate of a real MIDI port. This is required by the specification, and prevents data loss when the device's buffer overruns. Signed-off-by: Clemens Ladisch Reviewed-by: Takashi Sakamoto Tested-by: Takashi Sakamoto Signed-off-by: Takashi Iwai diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index ef399ca..0d58018 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -22,6 +22,12 @@ #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) /* + * Nominally 3125 bytes/second, but the MIDI port's clock might be + * 1% too slow, and the bus clock 100 ppm too fast. + */ +#define MIDI_BYTES_PER_SECOND 3093 + +/* * Several devices look only at the first eight data blocks. * In any case, this is more than enough for the MIDI data rate. */ @@ -226,6 +232,14 @@ sfc_found: for (i = 0; i < pcm_channels; i++) s->pcm_positions[i] = i; s->midi_position = s->pcm_channels; + + /* + * We do not know the actual MIDI FIFO size of most devices. Just + * assume two bytes, i.e., one byte can be received over the bus while + * the previous one is transmitted over MIDI. + * (The value here is adjusted for midi_ratelimit_per_packet().) + */ + s->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1; } EXPORT_SYMBOL(amdtp_stream_set_parameters); @@ -467,6 +481,36 @@ static void amdtp_fill_pcm_silence(struct amdtp_stream *s, } } +/* + * To avoid sending MIDI bytes at too high a rate, assume that the receiving + * device has a FIFO, and track how much it is filled. This values increases + * by one whenever we send one byte in a packet, but the FIFO empties at + * a constant rate independent of our packet rate. One packet has syt_interval + * samples, so the number of bytes that empty out of the FIFO, per packet(!), + * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate. To avoid storing + * fractional values, the values in midi_fifo_used[] are measured in bytes + * multiplied by the sample rate. + */ +static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port) +{ + int used; + + used = s->midi_fifo_used[port]; + if (used == 0) /* common shortcut */ + return true; + + used -= MIDI_BYTES_PER_SECOND * s->syt_interval; + used = max(used, 0); + s->midi_fifo_used[port] = used; + + return used < s->midi_fifo_limit; +} + +static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port) +{ + s->midi_fifo_used[port] += amdtp_rate_table[s->sfc]; +} + static void amdtp_fill_midi(struct amdtp_stream *s, __be32 *buffer, unsigned int frames) { @@ -474,16 +518,21 @@ static void amdtp_fill_midi(struct amdtp_stream *s, u8 *b; for (f = 0; f < frames; f++) { - buffer[s->midi_position] = 0; b = (u8 *)&buffer[s->midi_position]; port = (s->data_block_counter + f) % 8; - if ((f >= MAX_MIDI_RX_BLOCKS) || - (s->midi[port] == NULL) || - (snd_rawmidi_transmit(s->midi[port], b + 1, 1) <= 0)) - b[0] = 0x80; - else + if (f < MAX_MIDI_RX_BLOCKS && + midi_ratelimit_per_packet(s, port) && + s->midi[port] != NULL && + snd_rawmidi_transmit(s->midi[port], &b[1], 1) == 1) { + midi_rate_use_one_byte(s, port); b[0] = 0x81; + } else { + b[0] = 0x80; + b[1] = 0; + } + b[2] = 0; + b[3] = 0; buffer += s->data_block_quadlets; } diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index cd4c4df..8a03a91 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -148,6 +148,8 @@ struct amdtp_stream { bool double_pcm_frames; struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; + int midi_fifo_limit; + int midi_fifo_used[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; /* quirk: fixed interval of dbc between previos/current packets. */ unsigned int tx_dbc_interval; -- cgit v0.10.2 From f555f3d76aaade29c7e221a37ee64fe722955c09 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 Jan 2015 11:37:12 +0100 Subject: genetlink: document parallel_ops The kernel-doc for the parallel_ops family struct member is missing, add it. Signed-off-by: Johannes Berg Signed-off-by: David S. Miller diff --git a/include/net/genetlink.h b/include/net/genetlink.h index 8412508..2ea2c55 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -27,6 +27,8 @@ struct genl_info; * @maxattr: maximum number of attributes supported * @netnsok: set to true if the family can handle network * namespaces and should be presented in all of them + * @parallel_ops: operations can be called in parallel and aren't + * synchronized by the core genetlink code * @pre_doit: called before an operation's doit callback, it may * do additional, common, filtering and return an error * @post_doit: called after an operation's doit callback, it may -- cgit v0.10.2 From 5ad6300524c0332ac67e912c20d6e5cf262ba58f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 Jan 2015 11:37:13 +0100 Subject: genetlink: disallow subscribing to unknown mcast groups Jeff Layton reported that he could trigger the multicast unbind warning in generic netlink using trinity. I originally thought it was a race condition between unregistering the generic netlink family and closing the socket, but there's a far simpler explanation: genetlink currently allows subscribing to groups that don't (yet) exist, and the warning is triggered when unsubscribing again while the group still doesn't exist. Originally, I had a warning in the subscribe case and accepted it out of userspace API concerns, but the warning was of course wrong and removed later. However, I now think that allowing userspace to subscribe to groups that don't exist is wrong and could possibly become a security problem: Consider a (new) genetlink family implementing a permission check in the mcast_bind() function similar to the like the audit code does today; it would be possible to bypass the permission check by guessing the ID and subscribing to the group it exists. This is only possible in case a family like that would be dynamically loaded, but it doesn't seem like a huge stretch, for example wireless may be loaded when you plug in a USB device. To avoid this reject such subscription attempts. If this ends up causing userspace issues we may need to add a workaround in af_netlink to deny such requests but not return an error. Reported-by: Jeff Layton Signed-off-by: Johannes Berg Signed-off-by: David S. Miller diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 2e11061..c18d3f5 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -985,7 +985,7 @@ static struct genl_multicast_group genl_ctrl_groups[] = { static int genl_bind(struct net *net, int group) { - int i, err = 0; + int i, err = -ENOENT; down_read(&cb_lock); for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { -- cgit v0.10.2 From ee1c244219fd652964710a6cc3e4f922e86aa492 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 Jan 2015 11:37:14 +0100 Subject: genetlink: synchronize socket closing and family removal In addition to the problem Jeff Layton reported, I looked at the code and reproduced the same warning by subscribing and removing the genl family with a socket still open. This is a fairly tricky race which originates in the fact that generic netlink allows the family to go away while sockets are still open - unlike regular netlink which has a module refcount for every open socket so in general this cannot be triggered. Trying to resolve this issue by the obvious locking isn't possible as it will result in deadlocks between unregistration and group unbind notification (which incidentally lockdep doesn't find due to the home grown locking in the netlink table.) To really resolve this, introduce a "closing socket" reference counter (for generic netlink only, as it's the only affected family) in the core netlink code and use that in generic netlink to wait for all the sockets that are being closed at the same time as a generic netlink family is removed. This fixes the race that when a socket is closed, it will should call the unbind, but if the family is removed at the same time the unbind will not find it, leading to the warning. The real problem though is that in this case the unbind could actually find a new family that is registered to have a multicast group with the same ID, and call its mcast_unbind() leading to confusing. Also remove the warning since it would still trigger, but is now no longer a problem. This also moves the code in af_netlink.c to before unreferencing the module to avoid having the same problem in the normal non-genl case. Signed-off-by: Johannes Berg Signed-off-by: David S. Miller diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h index 55b6857..09460d6 100644 --- a/include/linux/genetlink.h +++ b/include/linux/genetlink.h @@ -11,6 +11,10 @@ extern void genl_unlock(void); extern int lockdep_genl_is_held(void); #endif +/* for synchronisation between af_netlink and genetlink */ +extern atomic_t genl_sk_destructing_cnt; +extern wait_queue_head_t genl_sk_destructing_waitq; + /** * rcu_dereference_genl - rcu_dereference with debug checking * @p: The pointer to read, prior to dereferencing diff --git a/include/net/genetlink.h b/include/net/genetlink.h index 2ea2c55..6c92415 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -35,7 +35,10 @@ struct genl_info; * undo operations done by pre_doit, for example release locks * @mcast_bind: a socket bound to the given multicast group (which * is given as the offset into the groups array) - * @mcast_unbind: a socket was unbound from the given multicast group + * @mcast_unbind: a socket was unbound from the given multicast group. + * Note that unbind() will not be called symmetrically if the + * generic netlink family is removed while there are still open + * sockets. * @attrbuf: buffer to store parsed attributes * @family_list: family list * @mcgrps: multicast groups used by this family (private) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 84ea76c..02fdde2 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include @@ -1095,6 +1096,8 @@ static void netlink_remove(struct sock *sk) __sk_del_bind_node(sk); netlink_update_listeners(sk); } + if (sk->sk_protocol == NETLINK_GENERIC) + atomic_inc(&genl_sk_destructing_cnt); netlink_table_ungrab(); } @@ -1211,6 +1214,20 @@ static int netlink_release(struct socket *sock) * will be purged. */ + /* must not acquire netlink_table_lock in any way again before unbind + * and notifying genetlink is done as otherwise it might deadlock + */ + if (nlk->netlink_unbind) { + int i; + + for (i = 0; i < nlk->ngroups; i++) + if (test_bit(i, nlk->groups)) + nlk->netlink_unbind(sock_net(sk), i + 1); + } + if (sk->sk_protocol == NETLINK_GENERIC && + atomic_dec_return(&genl_sk_destructing_cnt) == 0) + wake_up(&genl_sk_destructing_waitq); + sock->sk = NULL; wake_up_interruptible_all(&nlk->wait); @@ -1246,13 +1263,6 @@ static int netlink_release(struct socket *sock) netlink_table_ungrab(); } - if (nlk->netlink_unbind) { - int i; - - for (i = 0; i < nlk->ngroups; i++) - if (test_bit(i, nlk->groups)) - nlk->netlink_unbind(sock_net(sk), i + 1); - } kfree(nlk->groups); nlk->groups = NULL; diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h index f123a88..f1c31b3 100644 --- a/net/netlink/af_netlink.h +++ b/net/netlink/af_netlink.h @@ -2,6 +2,7 @@ #define _AF_NETLINK_H #include +#include #include #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index c18d3f5..ee57459 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -23,6 +23,9 @@ static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */ static DECLARE_RWSEM(cb_lock); +atomic_t genl_sk_destructing_cnt = ATOMIC_INIT(0); +DECLARE_WAIT_QUEUE_HEAD(genl_sk_destructing_waitq); + void genl_lock(void) { mutex_lock(&genl_mutex); @@ -435,15 +438,18 @@ int genl_unregister_family(struct genl_family *family) genl_lock_all(); - genl_unregister_mc_groups(family); - list_for_each_entry(rc, genl_family_chain(family->id), family_list) { if (family->id != rc->id || strcmp(rc->name, family->name)) continue; + genl_unregister_mc_groups(family); + list_del(&rc->family_list); family->n_ops = 0; - genl_unlock_all(); + up_write(&cb_lock); + wait_event(genl_sk_destructing_waitq, + atomic_read(&genl_sk_destructing_cnt) == 0); + genl_unlock(); kfree(family->attrbuf); genl_ctrl_event(CTRL_CMD_DELFAMILY, family, NULL, 0); @@ -1014,7 +1020,6 @@ static int genl_bind(struct net *net, int group) static void genl_unbind(struct net *net, int group) { int i; - bool found = false; down_read(&cb_lock); for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { @@ -1027,14 +1032,11 @@ static void genl_unbind(struct net *net, int group) if (f->mcast_unbind) f->mcast_unbind(net, fam_grp); - found = true; break; } } } up_read(&cb_lock); - - WARN_ON(!found); } static int __net_init genl_pernet_init(struct net *net) -- cgit v0.10.2 From 1fbbc3f0c5440a4c674b3d6de0a9dd447666b508 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 16 Jan 2015 10:17:10 +0900 Subject: ARM: shmobile: r8a7778: Instantiate GIC from C board code in legacy builds As of commit 9a1091ef0017c40a ("irqchip: gic: Support hierarchy irq domain."), Bock-W legacy hangs during boot with: Unable to handle kernel paging request at virtual address cf86a128 pgd = c0004000 [cf86a128] *pgd=6f80041e(bad) Internal error: Oops: 8000000d [#1] SMP ARM CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.19.0-rc4 #1 Hardware name: bockw task: cf823b40 ti: cf824000 task.ti: cf824000 PC is at 0xcf86a128 LR is at request_threaded_irq+0xbc/0x124 This happens because the IRQ numbers of the GIC are now virtual, and no longer match the hardcoded hardware IRQ numbers in the platform board code. To fix this, instantiate the GIC from platform board code when compiling a legacy kernel, like is done for the sh73a0 and r8a7740 legacy code. Follows same style as the r8a7740 legacy GIC fix by Geert Uytterhoeven, thanks to him for the initial work. Signed-off-by: Magnus Damm Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 85fe016..5d7a009 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -586,11 +586,18 @@ void __init r8a7778_init_delay(void) void __init r8a7778_init_irq_dt(void) { void __iomem *base = ioremap_nocache(0xfe700000, 0x00100000); +#ifdef CONFIG_ARCH_SHMOBILE_LEGACY + void __iomem *gic_dist_base = ioremap_nocache(0xfe438000, 0x1000); + void __iomem *gic_cpu_base = ioremap_nocache(0xfe430000, 0x1000); +#endif BUG_ON(!base); +#ifdef CONFIG_ARCH_SHMOBILE_LEGACY + gic_init(0, 29, gic_dist_base, gic_cpu_base); +#else irqchip_init(); - +#endif /* route all interrupts to ARM */ __raw_writel(0x73ffffff, base + INT2NTSR0); __raw_writel(0xffffffff, base + INT2NTSR1); -- cgit v0.10.2 From f469cde20a7ee342070b4a459b6fce469a3186db Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 16 Jan 2015 10:49:19 +0900 Subject: ARM: shmobile: r8a7779: Instantiate GIC from C board code in legacy builds As of commit 9a1091ef0017c40a ("irqchip: gic: Support hierarchy irq domain."), Marzen legacy hangs during boot with: Image Name: 'Linux-3.19.0-rc4' Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 3445880 Bytes = 3.3 MiB Load Address: 60008000 Entry Point: 60008000 Verifying Checksum ... OK Loading Kernel Image ... OK OK Starting kernel ... Enabling DEBUG_LL does not seem to change the situation, however this patch by itself fixes this issue and re-enables normal boot. This issue happens because the IRQ numbers of the GIC are now virtual, and no longer match the hardcoded hardware IRQ numbers in the platform board code. To fix this, instantiate the GIC from platform board code when compiling a legacy kernel, like is done for the sh73a0, r8a7740 and r8a7778 legacy code. Follows same style as the r8a7740 legacy GIC fix by Geert Uytterhoeven, thanks to him for the initial work. Signed-off-by: Magnus Damm Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 434d150..ca60683 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -724,10 +724,17 @@ static int r8a7779_set_wake(struct irq_data *data, unsigned int on) void __init r8a7779_init_irq_dt(void) { +#ifdef CONFIG_ARCH_SHMOBILE_LEGACY + void __iomem *gic_dist_base = ioremap_nocache(0xf0001000, 0x1000); + void __iomem *gic_cpu_base = ioremap_nocache(0xf0000100, 0x1000); +#endif gic_arch_extn.irq_set_wake = r8a7779_set_wake; +#ifdef CONFIG_ARCH_SHMOBILE_LEGACY + gic_init(0, 29, gic_dist_base, gic_cpu_base); +#else irqchip_init(); - +#endif /* route all interrupts to ARM */ __raw_writel(0xffffffff, INT2NTSR0); __raw_writel(0x3fffffff, INT2NTSR1); -- cgit v0.10.2 From 259e43844c46abe545214d0d5c9a538422d2e69a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 9 Jan 2015 20:11:20 +0100 Subject: ARM: nomadik: fix up leftover device tree pins We altered the device tree bindings for the Nomadik family of pin controllers to be standard, this file was merged out-of-order so we missed fixing this. Fix it up. Signed-off-by: Linus Walleij Signed-off-by: Olof Johansson diff --git a/arch/arm/boot/dts/ste-nomadik-nhk15.dts b/arch/arm/boot/dts/ste-nomadik-nhk15.dts index a8c00ee..3d0b875 100644 --- a/arch/arm/boot/dts/ste-nomadik-nhk15.dts +++ b/arch/arm/boot/dts/ste-nomadik-nhk15.dts @@ -25,11 +25,11 @@ stmpe2401_1 { stmpe2401_1_nhk_mode: stmpe2401_1_nhk { nhk_cfg1 { - ste,pins = "GPIO76_B20"; // IRQ line + pins = "GPIO76_B20"; // IRQ line ste,input = <0>; }; nhk_cfg2 { - ste,pins = "GPIO77_B8"; // reset line + pins = "GPIO77_B8"; // reset line ste,output = <1>; }; }; @@ -37,11 +37,11 @@ stmpe2401_2 { stmpe2401_2_nhk_mode: stmpe2401_2_nhk { nhk_cfg1 { - ste,pins = "GPIO78_A8"; // IRQ line + pins = "GPIO78_A8"; // IRQ line ste,input = <0>; }; nhk_cfg2 { - ste,pins = "GPIO79_C9"; // reset line + pins = "GPIO79_C9"; // reset line ste,output = <1>; }; }; -- cgit v0.10.2 From c9b75d51c940c25587a2ad72ec7ec60490abfb6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 11 Jan 2015 23:09:23 +0100 Subject: ARM: rockchip: disable jtag/sdmmc autoswitching on rk3288 rk3288 SoCs have a function to automatically switch between jtag/sdmmc pinmux settings depending on the card state. This collides with a lot of assumptions. It only works when using the internal card-detect mechanism and breaks horribly when using either the normal card-detect via the slot-gpio function or via any other pin. Also there is of course no link between the mmc and jtag on the software-side, so the jtag clocks may very well be disabled when the card is ejected and the soc switches back to the jtag pinmux. Leaving the switching function enabled did result in mmc timeouts and rcu stalls thus hanging the system on 3.19-rc1. Therefore disable it in all cases, as we expect the devicetree to explicitly select either mmc or jtag pinmuxes anyway. Signed-off-by: Heiko Stuebner Signed-off-by: Olof Johansson diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c index d226b71..a611f48 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rockchip.c @@ -19,11 +19,37 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include "core.h" +#define RK3288_GRF_SOC_CON0 0x244 + +static void __init rockchip_timer_init(void) +{ + if (of_machine_is_compatible("rockchip,rk3288")) { + struct regmap *grf; + + /* + * Disable auto jtag/sdmmc switching that causes issues + * with the mmc controllers making them unreliable + */ + grf = syscon_regmap_lookup_by_compatible("rockchip,rk3288-grf"); + if (!IS_ERR(grf)) + regmap_write(grf, RK3288_GRF_SOC_CON0, 0x10000000); + else + pr_err("rockchip: could not get grf syscon\n"); + } + + of_clk_init(NULL); + clocksource_of_init(); +} + static void __init rockchip_dt_init(void) { of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); @@ -42,6 +68,7 @@ static const char * const rockchip_board_dt_compat[] = { DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)") .l2c_aux_val = 0, .l2c_aux_mask = ~0, + .init_time = rockchip_timer_init, .dt_compat = rockchip_board_dt_compat, .init_machine = rockchip_dt_init, MACHINE_END -- cgit v0.10.2 From 896ddd600ba4a3426aeb11710ae9c28dd7ce68ce Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Sat, 10 Jan 2015 08:41:35 +0530 Subject: drivers: bus: check cci device tree node status The arm-cci driver completes the probe sequence even if the cci node is marked as disabled. Add a check in the driver to honour the cci status in the device tree. Signed-off-by: Abhilash Kesavan Acked-by: Sudeep Holla Acked-by: Nicolas Pitre Tested-by: Sudeep Holla Tested-by: Kevin Hilman Signed-off-by: Olof Johansson diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 860da40..0ce5e2d 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -1312,6 +1312,9 @@ static int cci_probe(void) if (!np) return -ENODEV; + if (!of_device_is_available(np)) + return -ENODEV; + cci_config = of_match_node(arm_cci_matches, np)->data; if (!cci_config) return -ENODEV; -- cgit v0.10.2 From 25217fef355174209eff68c0eb438a8af5d7b01c Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Sat, 10 Jan 2015 08:41:36 +0530 Subject: ARM: dts: disable CCI on exynos5420 based arndale-octa The arndale-octa board was giving "imprecise external aborts" during boot-up with MCPM enabled. CCI enablement of the boot cluster was found to be the cause of these aborts (possibly because the secure f/w was not allowing it). Hence, disable CCI for the arndale-octa board. Signed-off-by: Abhilash Kesavan Tested-by: Krzysztof Kozlowski Tested-by: Kevin Hilman Tested-by: Tyler Baker Signed-off-by: Olof Johansson diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts index aa7a7d7..db2c1c4 100644 --- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -372,3 +372,7 @@ &usbdrd_dwc3_1 { dr_mode = "host"; }; + +&cci { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 517e50f..0a82ae7 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -120,7 +120,7 @@ }; }; - cci@10d20000 { + cci: cci@10d20000 { compatible = "arm,cci-400"; #address-cells = <1>; #size-cells = <1>; -- cgit v0.10.2 From 41544f9f38f19cb46dc9a8fa37c58677a0300899 Mon Sep 17 00:00:00 2001 From: Tyler Baker Date: Mon, 12 Jan 2015 07:54:46 -0800 Subject: reset: sunxi: fix spinlock initialization Call spin_lock_init() before the spinlocks are used, both in early init and probe functions preventing a lockdep splat. I have been observing lockdep complaining [1] during boot on my a80 optimus [2] when CONFIG_PROVE_LOCKING has been enabled. This patch resolves the splat, and has been tested on a few other sunxi platforms without issue. [1] http://storage.kernelci.org/next/next-20150107/arm-multi_v7_defconfig+CONFIG_PROVE_LOCKING=y/lab-tbaker/boot-sun9i-a80-optimus.html [2] http://kernelci.org/boot/?a80-optimus Signed-off-by: Tyler Baker Cc: Acked-by: Philipp Zabel Signed-off-by: Kevin Hilman Signed-off-by: Olof Johansson diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index eebc52c..3d95c87 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -102,6 +102,8 @@ static int sunxi_reset_init(struct device_node *np) goto err_alloc; } + spin_lock_init(&data->lock); + data->rcdev.owner = THIS_MODULE; data->rcdev.nr_resets = size * 32; data->rcdev.ops = &sunxi_reset_ops; @@ -157,6 +159,8 @@ static int sunxi_reset_probe(struct platform_device *pdev) if (IS_ERR(data->membase)) return PTR_ERR(data->membase); + spin_lock_init(&data->lock); + data->rcdev.owner = THIS_MODULE; data->rcdev.nr_resets = resource_size(res) * 32; data->rcdev.ops = &sunxi_reset_ops; -- cgit v0.10.2 From 0fb22a8fb7f3bc1b00a36d4a97ce4f93191f7559 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 17 Jan 2015 10:21:08 +0000 Subject: ARM: OMAP: Work around hardcoded interrupts Commit 9a1091ef0017 ("irqchip: gic: Support hierarchy irq domain") changed the GIC driver to use a non-legacy IRQ domain on DT platforms. This patch assumes that DT-driven systems are getting all of their interrupts from device tree. Turns out that OMAP has quite a few hidden gems, and still uses hardcoded interrupts despite having fairly complete DTs. This patch attempts to work around these by offering a translation method that can be called directly from the hwmod code, if present. The same hack is sprinkled over PRCM and TWL. It isn't pretty, but it seems to do the job without having to add more hacks to the interrupt controller code. Tested on OMAP4 (Panda-ES) and OMAP5 (UEVM5432). Signed-off-by: Marc Zyngier Acked-by: Nishanth Menon [tony@atomide.com: updated to fix make randconfig issue] Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index db57741..64e44d6 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -211,6 +211,7 @@ extern struct device *omap2_get_iva_device(void); extern struct device *omap2_get_l3_device(void); extern struct device *omap4_get_dsp_device(void); +unsigned int omap4_xlate_irq(unsigned int hwirq); void omap_gic_of_init(void); #ifdef CONFIG_CACHE_L2X0 diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index b7cb44a..cc30e49 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -256,6 +256,38 @@ static int __init omap4_sar_ram_init(void) } omap_early_initcall(omap4_sar_ram_init); +static struct of_device_id gic_match[] = { + { .compatible = "arm,cortex-a9-gic", }, + { .compatible = "arm,cortex-a15-gic", }, + { }, +}; + +static struct device_node *gic_node; + +unsigned int omap4_xlate_irq(unsigned int hwirq) +{ + struct of_phandle_args irq_data; + unsigned int irq; + + if (!gic_node) + gic_node = of_find_matching_node(NULL, gic_match); + + if (WARN_ON(!gic_node)) + return hwirq; + + irq_data.np = gic_node; + irq_data.args_count = 3; + irq_data.args[0] = 0; + irq_data.args[1] = hwirq - OMAP44XX_IRQ_GIC_START; + irq_data.args[2] = IRQ_TYPE_LEVEL_HIGH; + + irq = irq_create_of_mapping(&irq_data); + if (WARN_ON(!irq)) + irq = hwirq; + + return irq; +} + void __init omap_gic_of_init(void) { struct device_node *np; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index cbb908d..9025fff 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3534,9 +3534,15 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) mpu_irqs_cnt = _count_mpu_irqs(oh); for (i = 0; i < mpu_irqs_cnt; i++) { + unsigned int irq; + + if (oh->xlate_irq) + irq = oh->xlate_irq((oh->mpu_irqs + i)->irq); + else + irq = (oh->mpu_irqs + i)->irq; (res + r)->name = (oh->mpu_irqs + i)->name; - (res + r)->start = (oh->mpu_irqs + i)->irq; - (res + r)->end = (oh->mpu_irqs + i)->irq; + (res + r)->start = irq; + (res + r)->end = irq; (res + r)->flags = IORESOURCE_IRQ; r++; } diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 35ca6ef..5b42faf 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -676,6 +676,7 @@ struct omap_hwmod { spinlock_t _lock; struct list_head node; struct omap_hwmod_ocp_if *_mpu_port; + unsigned int (*xlate_irq)(unsigned int); u16 flags; u8 mpu_rt_idx; u8 response_lat; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index c314b3c..f5e68a7 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -479,6 +479,7 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = { .class = &omap44xx_dma_hwmod_class, .clkdm_name = "l3_dma_clkdm", .mpu_irqs = omap44xx_dma_system_irqs, + .xlate_irq = omap4_xlate_irq, .main_clk = "l3_div_ck", .prcm = { .omap4 = { @@ -640,6 +641,7 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = { .class = &omap44xx_dispc_hwmod_class, .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_dispc_irqs, + .xlate_irq = omap4_xlate_irq, .sdma_reqs = omap44xx_dss_dispc_sdma_reqs, .main_clk = "dss_dss_clk", .prcm = { @@ -693,6 +695,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { .class = &omap44xx_dsi_hwmod_class, .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_dsi1_irqs, + .xlate_irq = omap4_xlate_irq, .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs, .main_clk = "dss_dss_clk", .prcm = { @@ -726,6 +729,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { .class = &omap44xx_dsi_hwmod_class, .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_dsi2_irqs, + .xlate_irq = omap4_xlate_irq, .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs, .main_clk = "dss_dss_clk", .prcm = { @@ -784,6 +788,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { */ .flags = HWMOD_SWSUP_SIDLE, .mpu_irqs = omap44xx_dss_hdmi_irqs, + .xlate_irq = omap4_xlate_irq, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, .main_clk = "dss_48mhz_clk", .prcm = { diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index 3e95230..7c3fac0 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -288,6 +288,7 @@ static struct omap_hwmod omap54xx_dma_system_hwmod = { .class = &omap54xx_dma_hwmod_class, .clkdm_name = "dma_clkdm", .mpu_irqs = omap54xx_dma_system_irqs, + .xlate_irq = omap4_xlate_irq, .main_clk = "l3_iclk_div", .prcm = { .omap4 = { diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index a8e4b58..6163d66 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -498,6 +498,7 @@ struct omap_prcm_irq_setup { u8 nr_irqs; const struct omap_prcm_irq *irqs; int irq; + unsigned int (*xlate_irq)(unsigned int); void (*read_pending_irqs)(unsigned long *events); void (*ocp_barrier)(void); void (*save_and_clear_irqen)(u32 *saved_mask); diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index cc170fb..408c64e 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -49,6 +49,7 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = { .irqs = omap4_prcm_irqs, .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs), .irq = 11 + OMAP44XX_IRQ_GIC_START, + .xlate_irq = omap4_xlate_irq, .read_pending_irqs = &omap44xx_prm_read_pending_irqs, .ocp_barrier = &omap44xx_prm_ocp_barrier, .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen, @@ -751,8 +752,10 @@ static int omap44xx_prm_late_init(void) } /* Once OMAP4 DT is filled as well */ - if (irq_num >= 0) + if (irq_num >= 0) { omap4_prcm_irq_setup.irq = irq_num; + omap4_prcm_irq_setup.xlate_irq = NULL; + } } omap44xx_prm_enable_io_wakeup(); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 779940c..dea2833 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -187,6 +187,7 @@ int omap_prcm_event_to_irq(const char *name) */ void omap_prcm_irq_cleanup(void) { + unsigned int irq; int i; if (!prcm_irq_setup) { @@ -211,7 +212,11 @@ void omap_prcm_irq_cleanup(void) kfree(prcm_irq_setup->priority_mask); prcm_irq_setup->priority_mask = NULL; - irq_set_chained_handler(prcm_irq_setup->irq, NULL); + if (prcm_irq_setup->xlate_irq) + irq = prcm_irq_setup->xlate_irq(prcm_irq_setup->irq); + else + irq = prcm_irq_setup->irq; + irq_set_chained_handler(irq, NULL); if (prcm_irq_setup->base_irq > 0) irq_free_descs(prcm_irq_setup->base_irq, @@ -259,6 +264,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) int offset, i; struct irq_chip_generic *gc; struct irq_chip_type *ct; + unsigned int irq; if (!irq_setup) return -EINVAL; @@ -298,7 +304,11 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) 1 << (offset & 0x1f); } - irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler); + if (irq_setup->xlate_irq) + irq = irq_setup->xlate_irq(irq_setup->irq); + else + irq = irq_setup->irq; + irq_set_chained_handler(irq, omap_prcm_irq_handler); irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32, 0); diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 4457e73..292eca0 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -66,19 +66,24 @@ void __init omap_pmic_init(int bus, u32 clkrate, omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1); } +#ifdef CONFIG_ARCH_OMAP4 void __init omap4_pmic_init(const char *pmic_type, struct twl4030_platform_data *pmic_data, struct i2c_board_info *devices, int nr_devices) { /* PMIC part*/ + unsigned int irq; + omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT); - omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data); + irq = omap4_xlate_irq(7 + OMAP44XX_IRQ_GIC_START); + omap_pmic_init(1, 400, pmic_type, irq, pmic_data); /* Register additional devices on i2c1 bus if needed */ if (devices) i2c_register_board_info(1, devices, nr_devices); } +#endif void __init omap_pmic_late_init(void) { -- cgit v0.10.2 From 8f1e8ee28660018a935c7576b9af8ffe1feab54c Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Fri, 16 Jan 2015 17:11:27 +0100 Subject: ARM: mvebu: completely disable hardware I/O coherency The current hardware I/O coherency is known to cause problems with DMA coherent buffers, as it still requires explicit I/O synchronization barriers, which is not compatible with the semantics expected by the Linux DMA coherent buffers API. So, in order to have enough time to validate a new solution based on automatic I/O synchronization barriers, this commit disables hardware I/O coherency entirely. Future patches will re-enable it. Signed-off-by: Thomas Petazzoni Cc: # v3.8+ Signed-off-by: Andrew Lunn diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 3585cb3..caa21e9 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -246,9 +246,14 @@ static int coherency_type(void) return type; } +/* + * As a precaution, we currently completely disable hardware I/O + * coherency, until enough testing is done with automatic I/O + * synchronization barriers to validate that it is a proper solution. + */ int coherency_available(void) { - return coherency_type() != COHERENCY_FABRIC_TYPE_NONE; + return false; } int __init coherency_init(void) -- cgit v0.10.2 From a5e1baf7dca10f8cf945394034013260297bc416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Fri, 16 Jan 2015 17:52:44 +0100 Subject: clk: rockchip: fix deadlock possibility in cpuclk Lockdep reported a possible deadlock between the cpuclk lock and for example the i2c driver. CPU0 CPU1 ---- ---- lock(clk_lock); local_irq_disable(); lock(&(&i2c->lock)->rlock); lock(clk_lock); lock(&(&i2c->lock)->rlock); *** DEADLOCK *** The generic clock-types of the core ccf already use spin_lock_irqsave when touching clock registers, so do the same for the cpuclk. Signed-off-by: Heiko Stuebner Reviewed-by: Doug Anderson Signed-off-by: Michael Turquette [mturquette@linaro.org: removed initialization of "flags"] diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index 75c8c45..8539c4f 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -124,10 +124,11 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk, { const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; unsigned long alt_prate, alt_div; + unsigned long flags; alt_prate = clk_get_rate(cpuclk->alt_parent); - spin_lock(cpuclk->lock); + spin_lock_irqsave(cpuclk->lock, flags); /* * If the old parent clock speed is less than the clock speed @@ -164,7 +165,7 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk, cpuclk->reg_base + reg_data->core_reg); } - spin_unlock(cpuclk->lock); + spin_unlock_irqrestore(cpuclk->lock, flags); return 0; } @@ -173,6 +174,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, { const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; const struct rockchip_cpuclk_rate_table *rate; + unsigned long flags; rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate); if (!rate) { @@ -181,7 +183,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, return -EINVAL; } - spin_lock(cpuclk->lock); + spin_lock_irqsave(cpuclk->lock, flags); if (ndata->old_rate < ndata->new_rate) rockchip_cpuclk_set_dividers(cpuclk, rate); @@ -201,7 +203,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, if (ndata->old_rate > ndata->new_rate) rockchip_cpuclk_set_dividers(cpuclk, rate); - spin_unlock(cpuclk->lock); + spin_unlock_irqrestore(cpuclk->lock, flags); return 0; } -- cgit v0.10.2 From 176a107b868781c8d6868454aea7d07e0b82d6b8 Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Wed, 3 Dec 2014 16:53:51 +0800 Subject: Revert "clk: ppc-corenet: Fix Section mismatch warning" This reverts commit da788acb28386aa896224e784954bb73c99ff26c. That commit tried to fix the section mismatch warning by moving the ppc_corenet_clk_driver struct to init section. This is definitely wrong because the kernel would free the memories occupied by this struct after boot while this driver is still registered in the driver core. The kernel would panic when accessing this driver struct. Cc: stable@vger.kernel.org # 3.17 Signed-off-by: Kevin Hao Acked-by: Scott Wood Signed-off-by: Michael Turquette diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c index b6e6c85..0a47d6f 100644 --- a/drivers/clk/clk-ppc-corenet.c +++ b/drivers/clk/clk-ppc-corenet.c @@ -291,7 +291,7 @@ static const struct of_device_id ppc_clk_ids[] __initconst = { {} }; -static struct platform_driver ppc_corenet_clk_driver __initdata = { +static struct platform_driver ppc_corenet_clk_driver = { .driver = { .name = "ppc_corenet_clock", .of_match_table = ppc_clk_ids, -- cgit v0.10.2 From c7662fc59ca38517e0ec04ceaa123ed8209ab6bf Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Mon, 5 Jan 2015 18:04:23 +0200 Subject: clk: fix possible null pointer dereference The commit 646cafc6 (clk: Change clk_ops->determine_rate to return a clk_hw as the best parent) opens a possibility for null pointer dereference, fix this. Signed-off-by: Stanimir Varbanov Reviewed-by: Stephen Boyd Signed-off-by: Michael Turquette diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index f4963b7..d48ac71 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1366,7 +1366,7 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate) new_rate = clk->ops->determine_rate(clk->hw, rate, &best_parent_rate, &parent_hw); - parent = parent_hw->clk; + parent = parent_hw ? parent_hw->clk : NULL; } else if (clk->ops->round_rate) { new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate); -- cgit v0.10.2 From 2061dcd6bff8b774b4fac8b0739b6be3f87bc9f2 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Thu, 15 Jan 2015 16:34:35 +0100 Subject: net: sctp: fix race for one-to-many sockets in sendmsg's auto associate I.e. one-to-many sockets in SCTP are not required to explicitly call into connect(2) or sctp_connectx(2) prior to data exchange. Instead, they can directly invoke sendmsg(2) and the SCTP stack will automatically trigger connection establishment through 4WHS via sctp_primitive_ASSOCIATE(). However, this in its current implementation is racy: INIT is being sent out immediately (as it cannot be bundled anyway) and the rest of the DATA chunks are queued up for later xmit when connection is established, meaning sendmsg(2) will return successfully. This behaviour can result in an undesired side-effect that the kernel made the application think the data has already been transmitted, although none of it has actually left the machine, worst case even after close(2)'ing the socket. Instead, when the association from client side has been shut down e.g. first gracefully through SCTP_EOF and then close(2), the client could afterwards still receive the server's INIT_ACK due to a connection with higher latency. This INIT_ACK is then considered out of the blue and hence responded with ABORT as there was no alive assoc found anymore. This can be easily reproduced f.e. with sctp_test application from lksctp. One way to fix this race is to wait for the handshake to actually complete. The fix defers waiting after sctp_primitive_ASSOCIATE() and sctp_primitive_SEND() succeeded, so that DATA chunks cooked up from sctp_sendmsg() have already been placed into the output queue through the side-effect interpreter, and therefore can then be bundeled together with COOKIE_ECHO control chunks. strace from example application (shortened): socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP) = 3 sendmsg(3, {msg_name(28)={sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("192.168.1.115")}, msg_iov(1)=[{"hello", 5}], msg_controllen=0, msg_flags=0}, 0) = 5 sendmsg(3, {msg_name(28)={sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("192.168.1.115")}, msg_iov(1)=[{"hello", 5}], msg_controllen=0, msg_flags=0}, 0) = 5 sendmsg(3, {msg_name(28)={sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("192.168.1.115")}, msg_iov(1)=[{"hello", 5}], msg_controllen=0, msg_flags=0}, 0) = 5 sendmsg(3, {msg_name(28)={sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("192.168.1.115")}, msg_iov(1)=[{"hello", 5}], msg_controllen=0, msg_flags=0}, 0) = 5 sendmsg(3, {msg_name(28)={sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("192.168.1.115")}, msg_iov(0)=[], msg_controllen=48, {cmsg_len=48, cmsg_level=0x84 /* SOL_??? */, cmsg_type=, ...}, msg_flags=0}, 0) = 0 // graceful shutdown for SOCK_SEQPACKET via SCTP_EOF close(3) = 0 tcpdump before patch (fooling the application): 22:33:36.306142 IP 192.168.1.114.41462 > 192.168.1.115.8888: sctp (1) [INIT] [init tag: 3879023686] [rwnd: 106496] [OS: 10] [MIS: 65535] [init TSN: 3139201684] 22:33:36.316619 IP 192.168.1.115.8888 > 192.168.1.114.41462: sctp (1) [INIT ACK] [init tag: 3345394793] [rwnd: 106496] [OS: 10] [MIS: 10] [init TSN: 3380109591] 22:33:36.317600 IP 192.168.1.114.41462 > 192.168.1.115.8888: sctp (1) [ABORT] tcpdump after patch: 14:28:58.884116 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [INIT] [init tag: 438593213] [rwnd: 106496] [OS: 10] [MIS: 65535] [init TSN: 3092969729] 14:28:58.888414 IP 192.168.1.115.8888 > 192.168.1.114.35846: sctp (1) [INIT ACK] [init tag: 381429855] [rwnd: 106496] [OS: 10] [MIS: 10] [init TSN: 2141904492] 14:28:58.888638 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [COOKIE ECHO] , (2) [DATA] (B)(E) [TSN: 3092969729] [...] 14:28:58.893278 IP 192.168.1.115.8888 > 192.168.1.114.35846: sctp (1) [COOKIE ACK] , (2) [SACK] [cum ack 3092969729] [a_rwnd 106491] [#gap acks 0] [#dup tsns 0] 14:28:58.893591 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [DATA] (B)(E) [TSN: 3092969730] [...] 14:28:59.096963 IP 192.168.1.115.8888 > 192.168.1.114.35846: sctp (1) [SACK] [cum ack 3092969730] [a_rwnd 106496] [#gap acks 0] [#dup tsns 0] 14:28:59.097086 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [DATA] (B)(E) [TSN: 3092969731] [...] , (2) [DATA] (B)(E) [TSN: 3092969732] [...] 14:28:59.103218 IP 192.168.1.115.8888 > 192.168.1.114.35846: sctp (1) [SACK] [cum ack 3092969732] [a_rwnd 106486] [#gap acks 0] [#dup tsns 0] 14:28:59.103330 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [SHUTDOWN] 14:28:59.107793 IP 192.168.1.115.8888 > 192.168.1.114.35846: sctp (1) [SHUTDOWN ACK] 14:28:59.107890 IP 192.168.1.114.35846 > 192.168.1.115.8888: sctp (1) [SHUTDOWN COMPLETE] Looks like this bug is from the pre-git history museum. ;) Fixes: 08707d5482df ("lksctp-2_5_31-0_5_1.patch") Signed-off-by: Daniel Borkmann Acked-by: Vlad Yasevich Signed-off-by: David S. Miller diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 2625ecc..aafe94b 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1603,7 +1603,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, sctp_assoc_t associd = 0; sctp_cmsgs_t cmsgs = { NULL }; sctp_scope_t scope; - bool fill_sinfo_ttl = false; + bool fill_sinfo_ttl = false, wait_connect = false; struct sctp_datamsg *datamsg; int msg_flags = msg->msg_flags; __u16 sinfo_flags = 0; @@ -1943,6 +1943,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, if (err < 0) goto out_free; + wait_connect = true; pr_debug("%s: we associated primitively\n", __func__); } @@ -1980,6 +1981,11 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, sctp_datamsg_put(datamsg); err = msg_len; + if (unlikely(wait_connect)) { + timeo = sock_sndtimeo(sk, msg_flags & MSG_DONTWAIT); + sctp_wait_for_connect(asoc, &timeo); + } + /* If we are already past ASSOCIATE, the lower * layers are responsible for association cleanup. */ -- cgit v0.10.2 From ec6f34e5b552fb0a52e6aae1a5afbbb1605cc6cc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 18 Jan 2015 18:02:20 +1200 Subject: Linux 3.19-rc5 diff --git a/Makefile b/Makefile index e41a335..fb93350 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 19 SUBLEVEL = 0 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc5 NAME = Diseased Newt # *DOCUMENTATION* -- cgit v0.10.2 From 265134a0009e2c5893c0211563daae178066dd06 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Mon, 12 Jan 2015 14:35:16 +0900 Subject: drm/exynos: fix reset codes for memory mapped hdmi phy This fixes reset codes to support memory mapped hdmi phy as well as hdmi phy dedicated i2c lines. Signed-off-by: Joonyoung Shim Signed-off-by: Inki Dae diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 5765a16..98051e8 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1669,7 +1669,6 @@ static void hdmi_mode_apply(struct hdmi_context *hdata) static void hdmiphy_conf_reset(struct hdmi_context *hdata) { - u8 buffer[2]; u32 reg; clk_disable_unprepare(hdata->res.sclk_hdmi); @@ -1677,11 +1676,8 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata) clk_prepare_enable(hdata->res.sclk_hdmi); /* operation mode */ - buffer[0] = 0x1f; - buffer[1] = 0x00; - - if (hdata->hdmiphy_port) - i2c_master_send(hdata->hdmiphy_port, buffer, 2); + hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, + HDMI_PHY_ENABLE_MODE_SET); if (hdata->type == HDMI_TYPE13) reg = HDMI_V13_PHY_RSTOUT; -- cgit v0.10.2 From bd508666e58ecf1712f8a132ab435cf0ef2d3d3c Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Sun, 18 Jan 2015 17:34:15 +0900 Subject: drm/exynos: remove unnecessary runtime pm operations In booting, we can see a below message. [ 3.241728] exynos-mixer 14450000.mixer: Unbalanced pm_runtime_enable! Already pm_runtime_enable is called by probe function. Remove pm_runtime_enable/disable from mixer_bind and mixer_unbind. Signed-off-by: Joonyoung Shim Signed-off-by: Inki Dae diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 820b762..71f1688 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1262,8 +1262,6 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data) return ret; } - pm_runtime_enable(dev); - return 0; } @@ -1272,8 +1270,6 @@ static void mixer_unbind(struct device *dev, struct device *master, void *data) struct mixer_context *ctx = dev_get_drvdata(dev); mixer_mgr_remove(&ctx->manager); - - pm_runtime_disable(dev); } static const struct component_ops mixer_component_ops = { -- cgit v0.10.2 From 7c4c55845ca40b56c9486064cc5c6d9b884d4d76 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Sun, 18 Jan 2015 17:48:29 +0900 Subject: drm/exynos: fix warning of vblank reference count Prevented re-enabling the vblank interrupt by drm_vblank_off and drm_vblank_get from mixer_wait_for_vblank returns error after drm_vblank_off. We get below warnings without this error handling because vblank reference count is mismatched by above sequence. setting mode 1920x1080-60Hz@XR24 on connectors 16, crtc 13 [ 19.900793] ------------[ cut here ]------------ [ 19.903959] WARNING: CPU: 0 PID: 0 at drivers/gpu/drm/drm_irq.c:1072 exynos_drm_crtc_finish_pageflip+0xac/0xdc() [ 19.914076] Modules linked in: [ 19.917116] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.19.0-rc4-00040-g3d729789-dirty #46 [ 19.925342] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 19.931437] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 19.939131] [] (show_stack) from [] (dump_stack+0x84/0xc4) [ 19.946329] [] (dump_stack) from [] (warn_slowpath_common+0x80/0xb0) [ 19.954382] [] (warn_slowpath_common) from [] (warn_slowpath_null+0x1c/0x24) [ 19.963132] [] (warn_slowpath_null) from [] (exynos_drm_crtc_finish_pageflip+0xac/0xdc) [ 19.972841] [] (exynos_drm_crtc_finish_pageflip) from [] (mixer_irq_handler+0xdc/0x104) [ 19.982546] [] (mixer_irq_handler) from [] (handle_irq_event_percpu+0x78/0x134) [ 19.991555] [] (handle_irq_event_percpu) from [] (handle_irq_event+0x3c/0x5c) [ 20.000395] [] (handle_irq_event) from [] (handle_fasteoi_irq+0xe0/0x1ac) [ 20.008885] [] (handle_fasteoi_irq) from [] (generic_handle_irq+0x2c/0x3c) [ 20.017463] [] (generic_handle_irq) from [] (__handle_domain_irq+0x7c/0xec) [ 20.026128] [] (__handle_domain_irq) from [] (gic_handle_irq+0x30/0x68) [ 20.034449] [] (gic_handle_irq) from [] (__irq_svc+0x40/0x74) [ 20.041893] Exception stack(0xc06fff68 to 0xc06fffb0) [ 20.046923] ff60: 00000000 00000000 000052f6 c001b460 c06fe000 c07064e8 [ 20.055070] ff80: c04d743c c07392a2 c0739440 c06da340 ef7fca80 00000000 01000000 c06fffb0 [ 20.063212] ffa0: c000f24c c000f250 60000013 ffffffff [ 20.068245] [] (__irq_svc) from [] (arch_cpu_idle+0x38/0x3c) [ 20.075611] [] (arch_cpu_idle) from [] (cpu_startup_entry+0x108/0x16c) [ 20.083846] [] (cpu_startup_entry) from [] (start_kernel+0x3a0/0x3ac) [ 20.091980] ---[ end trace 2c76ee0500489d1b ]--- Signed-off-by: Joonyoung Shim Signed-off-by: Inki Dae diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 71f1688..064ed65 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1026,6 +1026,7 @@ static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) { struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); + int err; mutex_lock(&mixer_ctx->mixer_mutex); if (!mixer_ctx->powered) { @@ -1034,7 +1035,11 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) } mutex_unlock(&mixer_ctx->mixer_mutex); - drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); + err = drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); + if (err < 0) { + DRM_DEBUG_KMS("failed to acquire vblank counter\n"); + return; + } atomic_set(&mixer_ctx->wait_vsync_event, 1); -- cgit v0.10.2 From 6455931186bff407493135e74c5f32efd30860e2 Mon Sep 17 00:00:00 2001 From: Jason Lee Cragg Date: Sat, 17 Jan 2015 12:28:29 -0500 Subject: ALSA: usb-audio: Add mic volume fix quirk for Logitech Webcam C210 Signed-off-by: Jason Lee Cragg Cc: Signed-off-by: Takashi Iwai diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 41650d5..3e2ef61 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -913,6 +913,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */ case USB_ID(0x046d, 0x0808): case USB_ID(0x046d, 0x0809): + case USB_ID(0x046d, 0x0819): /* Logitech Webcam C210 */ case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ -- cgit v0.10.2 From e6eb2eba494d6f99e69ca3c3748cd37a2544ab38 Mon Sep 17 00:00:00 2001 From: Laurent Dufour Date: Thu, 15 Jan 2015 18:23:47 +0100 Subject: powerpc/xmon: Fix another endiannes issue in RTAS call from xmon The commit 3b8a3c010969 ("powerpc/pseries: Fix endiannes issue in RTAS call from xmon") was fixing an endianness issue in the call made from xmon to RTAS. However, as Michael Ellerman noticed, this fix was not complete, the token value was not byte swapped. This lead to call an unexpected and most of the time unexisting RTAS function, which is silently ignored by RTAS. This fix addresses this hole. Reported-by: Michael Ellerman Cc: stable@vger.kernel.org Signed-off-by: Laurent Dufour Signed-off-by: Michael Ellerman diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 5b150f0..13c6e20 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -337,6 +337,7 @@ static inline void disable_surveillance(void) args.token = rtas_token("set-indicator"); if (args.token == RTAS_UNKNOWN_SERVICE) return; + args.token = cpu_to_be32(args.token); args.nargs = cpu_to_be32(3); args.nret = cpu_to_be32(1); args.rets = &args.args[3]; -- cgit v0.10.2 From f2c3c67f008f18f22a5fc68c0c279a6a59705042 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Sun, 18 Jan 2015 16:45:21 -0800 Subject: Merge tag 'mvebu-fixes-3.19-3' of git://git.infradead.org/linux-mvebu into fixes Merge " mvebu fixes for 3.19-rc (part #3)" from Andrew Lunn: mvebu: completely disable hardware I/O coherency * tag 'mvebu-fixes-3.19-3' of git://git.infradead.org/linux-mvebu: ARM: mvebu: completely disable hardware I/O coherency Signed-off-by: Olof Johansson diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 3585cb3..caa21e9 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -246,9 +246,14 @@ static int coherency_type(void) return type; } +/* + * As a precaution, we currently completely disable hardware I/O + * coherency, until enough testing is done with automatic I/O + * synchronization barriers to validate that it is a proper solution. + */ int coherency_available(void) { - return coherency_type() != COHERENCY_FABRIC_TYPE_NONE; + return false; } int __init coherency_init(void) -- cgit v0.10.2 From 378ff1a53b5724f3ac97b0aba3c9ecac072f6fcd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 18 Jan 2015 23:37:32 -0500 Subject: fix deadlock in cifs_ioctl_clone() It really needs to check that src is non-directory *and* use {un,}lock_two_nodirectories(). As it is, it's trivial to cause double-lock (ioctl(fd, CIFS_IOC_COPYCHUNK_FILE, fd)) and if the last argument is an fd of directory, we are asking for trouble by violating the locking order - all directories go before all non-directories. If the last argument is an fd of parent directory, it has 50% odds of locking child before parent, which will cause AB-BA deadlock if we race with unlink(). Cc: stable@vger.kernel.org @ 3.13+ Signed-off-by: Al Viro diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 45cb59b..8b7898b 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -86,21 +86,16 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, } src_inode = file_inode(src_file.file); + rc = -EINVAL; + if (S_ISDIR(src_inode->i_mode)) + goto out_fput; /* * Note: cifs case is easier than btrfs since server responsible for * checks for proper open modes and file type and if it wants * server could even support copy of range where source = target */ - - /* so we do not deadlock racing two ioctls on same files */ - if (target_inode < src_inode) { - mutex_lock_nested(&target_inode->i_mutex, I_MUTEX_PARENT); - mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_CHILD); - } else { - mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_PARENT); - mutex_lock_nested(&target_inode->i_mutex, I_MUTEX_CHILD); - } + lock_two_nondirectories(target_inode, src_inode); /* determine range to clone */ rc = -EINVAL; @@ -124,13 +119,7 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, out_unlock: /* although unlocking in the reverse order from locking is not strictly necessary here it is a little cleaner to be consistent */ - if (target_inode < src_inode) { - mutex_unlock(&src_inode->i_mutex); - mutex_unlock(&target_inode->i_mutex); - } else { - mutex_unlock(&target_inode->i_mutex); - mutex_unlock(&src_inode->i_mutex); - } + unlock_two_nondirectories(src_inode, target_inode); out_fput: fdput(src_file); out_drop_write: -- cgit v0.10.2 From 6cdb08172bc89f0a39e1643c5e7eab362692fd1b Mon Sep 17 00:00:00 2001 From: Brian King Date: Thu, 30 Oct 2014 17:27:10 -0500 Subject: ipr: wait for aborted command responses Fixes a race condition in abort handling that was injected when multiple interrupt support was added. When only a single interrupt is present, the adapter guarantees it will send responses for aborted commands prior to the response for the abort command itself. With multiple interrupts, these responses generally come back on different interrupts, so we need to ensure the abort thread waits until the aborted command is complete so we don't perform a double completion. This race condition was being hit frequently in environments which were triggering command timeouts, which was resulting in a double completion causing a kernel oops. Cc: Signed-off-by: Brian King Reviewed-by: Wendy Xiong Tested-by: Wendy Xiong Signed-off-by: Christoph Hellwig diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index df4e27c..9219953 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -683,6 +683,7 @@ static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd, ipr_reinit_ipr_cmnd(ipr_cmd); ipr_cmd->u.scratch = 0; ipr_cmd->sibling = NULL; + ipr_cmd->eh_comp = NULL; ipr_cmd->fast_done = fast_done; init_timer(&ipr_cmd->timer); } @@ -848,6 +849,8 @@ static void ipr_scsi_eh_done(struct ipr_cmnd *ipr_cmd) scsi_dma_unmap(ipr_cmd->scsi_cmd); scsi_cmd->scsi_done(scsi_cmd); + if (ipr_cmd->eh_comp) + complete(ipr_cmd->eh_comp); list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); } @@ -4811,6 +4814,84 @@ static int ipr_slave_alloc(struct scsi_device *sdev) return rc; } +/** + * ipr_match_lun - Match function for specified LUN + * @ipr_cmd: ipr command struct + * @device: device to match (sdev) + * + * Returns: + * 1 if command matches sdev / 0 if command does not match sdev + **/ +static int ipr_match_lun(struct ipr_cmnd *ipr_cmd, void *device) +{ + if (ipr_cmd->scsi_cmd && ipr_cmd->scsi_cmd->device == device) + return 1; + return 0; +} + +/** + * ipr_wait_for_ops - Wait for matching commands to complete + * @ipr_cmd: ipr command struct + * @device: device to match (sdev) + * @match: match function to use + * + * Returns: + * SUCCESS / FAILED + **/ +static int ipr_wait_for_ops(struct ipr_ioa_cfg *ioa_cfg, void *device, + int (*match)(struct ipr_cmnd *, void *)) +{ + struct ipr_cmnd *ipr_cmd; + int wait; + unsigned long flags; + struct ipr_hrr_queue *hrrq; + signed long timeout = IPR_ABORT_TASK_TIMEOUT; + DECLARE_COMPLETION_ONSTACK(comp); + + ENTER; + do { + wait = 0; + + for_each_hrrq(hrrq, ioa_cfg) { + spin_lock_irqsave(hrrq->lock, flags); + list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { + if (match(ipr_cmd, device)) { + ipr_cmd->eh_comp = ∁ + wait++; + } + } + spin_unlock_irqrestore(hrrq->lock, flags); + } + + if (wait) { + timeout = wait_for_completion_timeout(&comp, timeout); + + if (!timeout) { + wait = 0; + + for_each_hrrq(hrrq, ioa_cfg) { + spin_lock_irqsave(hrrq->lock, flags); + list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { + if (match(ipr_cmd, device)) { + ipr_cmd->eh_comp = NULL; + wait++; + } + } + spin_unlock_irqrestore(hrrq->lock, flags); + } + + if (wait) + dev_err(&ioa_cfg->pdev->dev, "Timed out waiting for aborted commands\n"); + LEAVE; + return wait ? FAILED : SUCCESS; + } + } + } while (wait); + + LEAVE; + return SUCCESS; +} + static int ipr_eh_host_reset(struct scsi_cmnd *cmd) { struct ipr_ioa_cfg *ioa_cfg; @@ -5030,11 +5111,17 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd) static int ipr_eh_dev_reset(struct scsi_cmnd *cmd) { int rc; + struct ipr_ioa_cfg *ioa_cfg; + + ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata; spin_lock_irq(cmd->device->host->host_lock); rc = __ipr_eh_dev_reset(cmd); spin_unlock_irq(cmd->device->host->host_lock); + if (rc == SUCCESS) + rc = ipr_wait_for_ops(ioa_cfg, cmd->device, ipr_match_lun); + return rc; } @@ -5234,13 +5321,18 @@ static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) { unsigned long flags; int rc; + struct ipr_ioa_cfg *ioa_cfg; ENTER; + ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; + spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); rc = ipr_cancel_op(scsi_cmd); spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); + if (rc == SUCCESS) + rc = ipr_wait_for_ops(ioa_cfg, scsi_cmd->device, ipr_match_lun); LEAVE; return rc; } diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index b4f3eec..ec03b42 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -1606,6 +1606,7 @@ struct ipr_cmnd { struct scsi_device *sdev; } u; + struct completion *eh_comp; struct ipr_hrr_queue *hrrq; struct ipr_ioa_cfg *ioa_cfg; }; -- cgit v0.10.2 From cdef511985374dd042a40bb32c1c346c2662c9dc Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Thu, 15 Jan 2015 15:21:19 +0100 Subject: KVM: fix sparse warning in include/trace/events/kvm.h sparse complains about include/trace/events/kvm.h:163:1: error: directive in argument list include/trace/events/kvm.h:167:1: error: directive in argument list include/trace/events/kvm.h:169:1: error: directive in argument list and sparse is right. Preprocessing directives in an argument of a macro are undefined behaviour as of C99 6.10.3p11. Lets use an indirection to fix this. Signed-off-by: Christian Borntraeger Signed-off-by: Paolo Bonzini diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index 6edf1f2..86b399c 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -146,6 +146,14 @@ TRACE_EVENT(kvm_msi_set_irq, #if defined(CONFIG_HAVE_KVM_IRQFD) +#ifdef kvm_irqchips +#define kvm_ack_irq_string "irqchip %s pin %u" +#define kvm_ack_irq_parm __print_symbolic(__entry->irqchip, kvm_irqchips), __entry->pin +#else +#define kvm_ack_irq_string "irqchip %d pin %u" +#define kvm_ack_irq_parm __entry->irqchip, __entry->pin +#endif + TRACE_EVENT(kvm_ack_irq, TP_PROTO(unsigned int irqchip, unsigned int pin), TP_ARGS(irqchip, pin), @@ -160,13 +168,7 @@ TRACE_EVENT(kvm_ack_irq, __entry->pin = pin; ), -#ifdef kvm_irqchips - TP_printk("irqchip %s pin %u", - __print_symbolic(__entry->irqchip, kvm_irqchips), - __entry->pin) -#else - TP_printk("irqchip %d pin %u", __entry->irqchip, __entry->pin) -#endif + TP_printk(kvm_ack_irq_string, kvm_ack_irq_parm) ); #endif /* defined(CONFIG_HAVE_KVM_IRQFD) */ -- cgit v0.10.2 From bcd53f858d87f52843cc87764b283999126a50d6 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 19 Jan 2015 11:17:45 +0100 Subject: pinctrl: qcom: Don't iterate past end of function array Timur reports that this code crashes if nfunctions is 0. Fix the loop iteration to only consider valid elements of the functions array. Reported-by: Timur Tabi Cc: Pramod Gurav Cc: Bjorn Andersson Cc: Ivan T. Ivanov Cc: Andy Gross Fixes: 327455817a92 "pinctrl: qcom: Add support for reset for apq8064" Signed-off-by: Stephen Boyd Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index e730935..ed7017d 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -865,10 +865,10 @@ static int msm_ps_hold_restart(struct notifier_block *nb, unsigned long action, static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) { - int i = 0; + int i; const struct msm_function *func = pctrl->soc->functions; - for (; i <= pctrl->soc->nfunctions; i++) + for (i = 0; i < pctrl->soc->nfunctions; i++) if (!strcmp(func[i].name, "ps_hold")) { pctrl->restart_nb.notifier_call = msm_ps_hold_restart; pctrl->restart_nb.priority = 128; -- cgit v0.10.2 From dbe752a34d4bd862de154d1e1f8eb9b649601f77 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 19 Jan 2015 11:27:19 +0100 Subject: pinctrl: MAINTAINERS: add git tree reference Reference my pinctrl GIT tree @kernel.org Reported-by: Sergei Shtylyov Signed-off-by: Linus Walleij diff --git a/MAINTAINERS b/MAINTAINERS index 3589d67..cdc238c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7400,6 +7400,7 @@ F: drivers/crypto/picoxcell* PIN CONTROL SUBSYSTEM M: Linus Walleij L: linux-gpio@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git S: Maintained F: drivers/pinctrl/ F: include/linux/pinctrl/ -- cgit v0.10.2 From e3f31175a3eeb492a6ab788e4fa136c19b43aab4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Jan 2015 14:17:36 +0100 Subject: ath9k: fix race condition in irq processing during hardware reset To fix invalid hardware accesses, the commit 872b5d814f99 ("ath9k: do not access hardware on IRQs during reset") made the irq handler ignore interrupts emitted after queueing a hardware reset (which disables the IRQ). This left a small time window for the IRQ to get re-enabled by the tasklet, which caused IRQ storms. Instead of returning IRQ_NONE when ATH_OP_HW_RESET is set, disable the IRQ entirely for the duration of the reset. Signed-off-by: Felix Fietkau Signed-off-by: Kalle Valo diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9a72640..62b0bf4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -285,6 +285,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) __ath_cancel_work(sc); + disable_irq(sc->irq); tasklet_disable(&sc->intr_tq); tasklet_disable(&sc->bcon_tasklet); spin_lock_bh(&sc->sc_pcu_lock); @@ -331,6 +332,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) r = -EIO; out: + enable_irq(sc->irq); spin_unlock_bh(&sc->sc_pcu_lock); tasklet_enable(&sc->bcon_tasklet); tasklet_enable(&sc->intr_tq); @@ -512,9 +514,6 @@ irqreturn_t ath_isr(int irq, void *dev) if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags)) return IRQ_NONE; - if (!AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags)) - return IRQ_NONE; - /* shared irq, not for us */ if (!ath9k_hw_intrpend(ah)) return IRQ_NONE; @@ -529,7 +528,7 @@ irqreturn_t ath_isr(int irq, void *dev) ath9k_debug_sync_cause(sc, sync_cause); status &= ah->imask; /* discard unasked-for bits */ - if (AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags)) + if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) return IRQ_HANDLED; /* -- cgit v0.10.2 From 72dd299d5039a336493993dcc63413cf31d0e662 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 16 Jan 2015 15:13:02 -0800 Subject: libata: allow sata_sil24 to opt-out of tag ordered submission Ronny reports: https://bugzilla.kernel.org/show_bug.cgi?id=87101 "Since commit 8a4aeec8d "libata/ahci: accommodate tag ordered controllers" the access to the harddisk on the first SATA-port is failing on its first access. The access to the harddisk on the second port is working normal. When reverting the above commit, access to both harddisks is working fine again." Maintain tag ordered submission as the default, but allow sata_sil24 to continue with the old behavior. Cc: Cc: Tejun Heo Reported-by: Ronny Hegewald Signed-off-by: Dan Williams Signed-off-by: Tejun Heo diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 23c2ae0..d1a05f9 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4771,7 +4771,10 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) return NULL; for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) { - tag = tag < max_queue ? tag : 0; + if (ap->flags & ATA_FLAG_LOWTAG) + tag = i; + else + tag = tag < max_queue ? tag : 0; /* the last tag is reserved for internal command. */ if (tag == ATA_TAG_INTERNAL) diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index d81b20d..ea65594 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -246,7 +246,7 @@ enum { /* host flags */ SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA | - ATA_FLAG_AN | ATA_FLAG_PMP, + ATA_FLAG_AN | ATA_FLAG_PMP | ATA_FLAG_LOWTAG, SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ IRQ_STAT_4PORTS = 0xf, diff --git a/include/linux/libata.h b/include/linux/libata.h index f2b440e..91f705d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -231,6 +231,7 @@ enum { ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity * led */ ATA_FLAG_NO_DIPM = (1 << 23), /* host not happy with DIPM */ + ATA_FLAG_LOWTAG = (1 << 24), /* host wants lowest available tag */ /* bits 24:31 of ap->flags are reserved for LLD specific flags */ -- cgit v0.10.2 From 1caf6aaaa47471831d77c75f094d4e00ad1ec808 Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Sun, 18 Jan 2015 00:36:15 +0100 Subject: scripts/recordmcount.pl: There is no -m32 gcc option on Super-H anymore Compiling SH with gcc-4.8 fails due to the -m32 option not being supported. From http://buildd.debian-ports.org/status/fetch.php?pkg=linux&arch=sh4&ver=3.16.7-ckt4-1&stamp=1421425783 CC init/main.o gcc-4.8: error: unrecognized command line option '-m32' ld: cannot find init/.tmp_mc_main.o: No such file or directory objcopy: 'init/.tmp_mx_main.o': No such file rm: cannot remove 'init/.tmp_mx_main.o': No such file or directory rm: cannot remove 'init/.tmp_mc_main.o': No such file or directory Link: http://lkml.kernel.org/r/1421537778-29001-1-git-send-email-kernel@mkarcher.dialup.fu-berlin.de Link: http://lkml.kernel.org/r/54BCBDD4.10102@physik.fu-berlin.de Cc: stable@vger.kernel.org Cc: Matt Fleming Reported-by: John Paul Adrian Glaubitz Signed-off-by: Michael Karcher Signed-off-by: Steven Rostedt diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 56ea99a..537c38c 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -255,7 +255,6 @@ if ($arch eq "x86_64") { # force flags for this arch $ld .= " -m shlelf_linux"; $objcopy .= " -O elf32-sh-linux"; - $cc .= " -m32"; } elsif ($arch eq "powerpc") { $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)"; -- cgit v0.10.2 From ce7514526742c0898b837d4395f515b79dfb5a12 Mon Sep 17 00:00:00 2001 From: David Jeffery Date: Mon, 19 Jan 2015 13:03:25 -0600 Subject: libata: prevent HSM state change race between ISR and PIO It is possible for ata_sff_flush_pio_task() to set ap->hsm_task_state to HSM_ST_IDLE in between the time __ata_sff_port_intr() checks for HSM_ST_IDLE and before it calls ata_sff_hsm_move() causing ata_sff_hsm_move() to BUG(). This problem is hard to reproduce making this patch hard to verify, but this fix will prevent the race. I have not been able to reproduce the problem, but here is a crash dump from a 2.6.32 kernel. On examining the ata port's state, its hsm_task_state field has a value of HSM_ST_IDLE: crash> struct ata_port.hsm_task_state ffff881c1121c000 hsm_task_state = 0 Normally, this should not be possible as ata_sff_hsm_move() was called from ata_sff_host_intr(), which checks hsm_task_state and won't call ata_sff_hsm_move() if it has a HSM_ST_IDLE value. PID: 11053 TASK: ffff8816e846cae0 CPU: 0 COMMAND: "sshd" #0 [ffff88008ba03960] machine_kexec at ffffffff81038f3b #1 [ffff88008ba039c0] crash_kexec at ffffffff810c5d92 #2 [ffff88008ba03a90] oops_end at ffffffff8152b510 #3 [ffff88008ba03ac0] die at ffffffff81010e0b #4 [ffff88008ba03af0] do_trap at ffffffff8152ad74 #5 [ffff88008ba03b50] do_invalid_op at ffffffff8100cf95 #6 [ffff88008ba03bf0] invalid_op at ffffffff8100bf9b [exception RIP: ata_sff_hsm_move+317] RIP: ffffffff813a77ad RSP: ffff88008ba03ca0 RFLAGS: 00010097 RAX: 0000000000000000 RBX: ffff881c1121dc60 RCX: 0000000000000000 RDX: ffff881c1121dd10 RSI: ffff881c1121dc60 RDI: ffff881c1121c000 RBP: ffff88008ba03d00 R8: 0000000000000000 R9: 000000000000002e R10: 000000000001003f R11: 000000000000009b R12: ffff881c1121c000 R13: 0000000000000000 R14: 0000000000000050 R15: ffff881c1121dd78 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #7 [ffff88008ba03d08] ata_sff_host_intr at ffffffff813a7fbd #8 [ffff88008ba03d38] ata_sff_interrupt at ffffffff813a821e #9 [ffff88008ba03d78] handle_IRQ_event at ffffffff810e6ec0 --- --- [exception RIP: pipe_poll+48] RIP: ffffffff81192780 RSP: ffff880f26d459b8 RFLAGS: 00000246 RAX: 0000000000000000 RBX: ffff880f26d459c8 RCX: 0000000000000000 RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff881a0539fa80 RBP: ffffffff8100bb8e R8: ffff8803b23324a0 R9: 0000000000000000 R10: ffff880f26d45dd0 R11: 0000000000000008 R12: ffffffff8109b646 R13: ffff880f26d45948 R14: 0000000000000246 R15: 0000000000000246 ORIG_RAX: ffffffffffffff10 CS: 0010 SS: 0018 RIP: 00007f26017435c3 RSP: 00007fffe020c420 RFLAGS: 00000206 RAX: 0000000000000017 RBX: ffffffff8100b072 RCX: 00007fffe020c45c RDX: 00007f2604a3f120 RSI: 00007f2604a3f140 RDI: 000000000000000d RBP: 0000000000000000 R8: 00007fffe020e570 R9: 0101010101010101 R10: 0000000000000000 R11: 0000000000000246 R12: 00007fffe020e5f0 R13: 00007fffe020e5f4 R14: 00007f26045f373c R15: 00007fffe020e5e0 ORIG_RAX: 0000000000000017 CS: 0033 SS: 002b Somewhere between the ata_sff_hsm_move() check and the ata_sff_host_intr() check, the value changed. On examining the other cpus to see what else was running, another cpu was running the error handler routines: PID: 326 TASK: ffff881c11014aa0 CPU: 1 COMMAND: "scsi_eh_1" #0 [ffff88008ba27e90] crash_nmi_callback at ffffffff8102fee6 #1 [ffff88008ba27ea0] notifier_call_chain at ffffffff8152d515 #2 [ffff88008ba27ee0] atomic_notifier_call_chain at ffffffff8152d57a #3 [ffff88008ba27ef0] notify_die at ffffffff810a154e #4 [ffff88008ba27f20] do_nmi at ffffffff8152b1db #5 [ffff88008ba27f50] nmi at ffffffff8152aaa0 [exception RIP: _spin_lock_irqsave+47] RIP: ffffffff8152a1ff RSP: ffff881c11a73aa0 RFLAGS: 00000006 RAX: 0000000000000001 RBX: ffff881c1121deb8 RCX: 0000000000000000 RDX: 0000000000000246 RSI: 0000000000000020 RDI: ffff881c122612d8 RBP: ffff881c11a73aa0 R8: ffff881c17083800 R9: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffff881c1121c000 R13: 000000000000001f R14: ffff881c1121dd50 R15: ffff881c1121dc60 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0000 --- --- #6 [ffff881c11a73aa0] _spin_lock_irqsave at ffffffff8152a1ff #7 [ffff881c11a73aa8] ata_exec_internal_sg at ffffffff81396fb5 #8 [ffff881c11a73b58] ata_exec_internal at ffffffff81397109 #9 [ffff881c11a73bd8] atapi_eh_request_sense at ffffffff813a34eb Before it tried to acquire a spinlock, ata_exec_internal_sg() called ata_sff_flush_pio_task(). This function will set ap->hsm_task_state to HSM_ST_IDLE, and has no locking around setting this value. ata_sff_flush_pio_task() can then race with the interrupt handler and potentially set HSM_ST_IDLE at a fatal moment, which will trigger a kernel BUG. v2: Fixup comment in ata_sff_flush_pio_task() tj: Further updated comment. Use ap->lock instead of shost lock and use the [un]lock_irq variant instead of the irqsave/restore one. Signed-off-by: David Milburn Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index db90aa3..2e86e3b 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1333,7 +1333,19 @@ void ata_sff_flush_pio_task(struct ata_port *ap) DPRINTK("ENTER\n"); cancel_delayed_work_sync(&ap->sff_pio_task); + + /* + * We wanna reset the HSM state to IDLE. If we do so without + * grabbing the port lock, critical sections protected by it which + * expect the HSM state to stay stable may get surprised. For + * example, we may set IDLE in between the time + * __ata_sff_port_intr() checks for HSM_ST_IDLE and before it calls + * ata_sff_hsm_move() causing ata_sff_hsm_move() to BUG(). + */ + spin_lock_irq(ap->lock); ap->hsm_task_state = HSM_ST_IDLE; + spin_unlock_irq(ap->lock); + ap->sff_pio_task_link = NULL; if (ata_msg_ctl(ap)) -- cgit v0.10.2 From 9d289715eb5c252ae15bd547cb252ca547a3c4f2 Mon Sep 17 00:00:00 2001 From: Hagen Paul Pfeifer Date: Thu, 15 Jan 2015 22:34:25 +0100 Subject: ipv6: stop sending PTB packets for MTU < 1280 Reduce the attack vector and stop generating IPv6 Fragment Header for paths with an MTU smaller than the minimum required IPv6 MTU size (1280 byte) - called atomic fragments. See IETF I-D "Deprecating the Generation of IPv6 Atomic Fragments" [1] for more information and how this "feature" can be misused. [1] https://tools.ietf.org/html/draft-ietf-6man-deprecate-atomfrag-generation-00 Signed-off-by: Fernando Gont Signed-off-by: Hagen Paul Pfeifer Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c910831..166e33b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1160,12 +1160,9 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, struct net *net = dev_net(dst->dev); rt6->rt6i_flags |= RTF_MODIFIED; - if (mtu < IPV6_MIN_MTU) { - u32 features = dst_metric(dst, RTAX_FEATURES); + if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; - features |= RTAX_FEATURE_ALLFRAG; - dst_metric_set(dst, RTAX_FEATURES, features); - } + dst_metric_set(dst, RTAX_MTU, mtu); rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires); } -- cgit v0.10.2 From b37feed7c2803cce71a746623594f19bbb5a21aa Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 16 Jan 2015 17:51:12 +0000 Subject: sh_eth: Fix promiscuous mode on chips without TSU Currently net_device_ops::set_rx_mode is only implemented for chips with a TSU (multiple address table). However we do need to turn the PRM (promiscuous) flag on and off for other chips. - Remove the unlikely() from the TSU functions that we may safely call for chips without a TSU - Make setting of the MCT flag conditional on the tsu capability flag - Rename sh_eth_set_multicast_list() to sh_eth_set_rx_mode() and plumb it into both net_device_ops structures - Remove the previously-unreachable branch in sh_eth_rx_mode() that would otherwise reset the flags to defaults for non-TSU chips Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 8d227d9..01dfae4 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2417,7 +2417,7 @@ static int sh_eth_tsu_purge_all(struct net_device *ndev) struct sh_eth_private *mdp = netdev_priv(ndev); int i, ret; - if (unlikely(!mdp->cd->tsu)) + if (!mdp->cd->tsu) return 0; for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) { @@ -2440,7 +2440,7 @@ static void sh_eth_tsu_purge_mcast(struct net_device *ndev) void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); int i; - if (unlikely(!mdp->cd->tsu)) + if (!mdp->cd->tsu) return; for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) { @@ -2450,8 +2450,8 @@ static void sh_eth_tsu_purge_mcast(struct net_device *ndev) } } -/* Multicast reception directions set */ -static void sh_eth_set_multicast_list(struct net_device *ndev) +/* Update promiscuous flag and multicast filter */ +static void sh_eth_set_rx_mode(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); u32 ecmr_bits; @@ -2462,7 +2462,9 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) /* Initial condition is MCT = 1, PRM = 0. * Depending on ndev->flags, set PRM or clear MCT */ - ecmr_bits = (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) | ECMR_MCT; + ecmr_bits = sh_eth_read(ndev, ECMR) & ~ECMR_PRM; + if (mdp->cd->tsu) + ecmr_bits |= ECMR_MCT; if (!(ndev->flags & IFF_MULTICAST)) { sh_eth_tsu_purge_mcast(ndev); @@ -2491,9 +2493,6 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) } } } - } else { - /* Normal, unicast/broadcast-only mode. */ - ecmr_bits = (ecmr_bits & ~ECMR_PRM) | ECMR_MCT; } /* update the ethernet mode */ @@ -2701,6 +2700,7 @@ static const struct net_device_ops sh_eth_netdev_ops = { .ndo_stop = sh_eth_close, .ndo_start_xmit = sh_eth_start_xmit, .ndo_get_stats = sh_eth_get_stats, + .ndo_set_rx_mode = sh_eth_set_rx_mode, .ndo_tx_timeout = sh_eth_tx_timeout, .ndo_do_ioctl = sh_eth_do_ioctl, .ndo_validate_addr = eth_validate_addr, @@ -2713,7 +2713,7 @@ static const struct net_device_ops sh_eth_netdev_ops_tsu = { .ndo_stop = sh_eth_close, .ndo_start_xmit = sh_eth_start_xmit, .ndo_get_stats = sh_eth_get_stats, - .ndo_set_rx_mode = sh_eth_set_multicast_list, + .ndo_set_rx_mode = sh_eth_set_rx_mode, .ndo_vlan_rx_add_vid = sh_eth_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = sh_eth_vlan_rx_kill_vid, .ndo_tx_timeout = sh_eth_tx_timeout, -- cgit v0.10.2 From 4f9dce230b32eec45cec8c28cae61efdfa2f7d57 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 16 Jan 2015 17:51:25 +0000 Subject: sh_eth: Fix ethtool operation crash when net device is down The driver connects and disconnects the PHY device whenever the net device is brought up and down. The ethtool get_settings, set_settings and nway_reset operations will dereference a null or dangling pointer if called while it is down. I think it would be preferable to keep the PHY connected, but there may be good reasons not to. As an immediate fix for this bug: - Set the phydev pointer to NULL after disconnecting the PHY - Change those three operations to return -ENODEV while the PHY is not connected Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 01dfae4..6576243 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1827,6 +1827,9 @@ static int sh_eth_get_settings(struct net_device *ndev, unsigned long flags; int ret; + if (!mdp->phydev) + return -ENODEV; + spin_lock_irqsave(&mdp->lock, flags); ret = phy_ethtool_gset(mdp->phydev, ecmd); spin_unlock_irqrestore(&mdp->lock, flags); @@ -1841,6 +1844,9 @@ static int sh_eth_set_settings(struct net_device *ndev, unsigned long flags; int ret; + if (!mdp->phydev) + return -ENODEV; + spin_lock_irqsave(&mdp->lock, flags); /* disable tx and rx */ @@ -1875,6 +1881,9 @@ static int sh_eth_nway_reset(struct net_device *ndev) unsigned long flags; int ret; + if (!mdp->phydev) + return -ENODEV; + spin_lock_irqsave(&mdp->lock, flags); ret = phy_start_aneg(mdp->phydev); spin_unlock_irqrestore(&mdp->lock, flags); @@ -2184,6 +2193,7 @@ static int sh_eth_close(struct net_device *ndev) if (mdp->phydev) { phy_stop(mdp->phydev); phy_disconnect(mdp->phydev); + mdp->phydev = NULL; } free_irq(ndev->irq, ndev); -- cgit v0.10.2 From 6216642f200258708e47170ff14ba8ecb486f4f0 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 18 Jan 2015 19:49:58 +0100 Subject: bgmac: register napi before the device napi should get registered before the netdev and not after. Signed-off-by: Hauke Mehrtens Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 05c6af6..aa9f950 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1515,6 +1515,8 @@ static int bgmac_probe(struct bcma_device *core) if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n"); + netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); + err = bgmac_mii_register(bgmac); if (err) { bgmac_err(bgmac, "Cannot register MDIO\n"); @@ -1529,8 +1531,6 @@ static int bgmac_probe(struct bcma_device *core) netif_carrier_off(net_dev); - netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); - return 0; err_mii_unregister: @@ -1549,9 +1549,9 @@ static void bgmac_remove(struct bcma_device *core) { struct bgmac *bgmac = bcma_get_drvdata(core); - netif_napi_del(&bgmac->napi); unregister_netdev(bgmac->net_dev); bgmac_mii_unregister(bgmac); + netif_napi_del(&bgmac->napi); bgmac_dma_free(bgmac); bcma_set_drvdata(core, NULL); free_netdev(bgmac->net_dev); -- cgit v0.10.2 From 43f159c60a99318b1ef7d1d7c16c4dfdd06bfd90 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 18 Jan 2015 19:49:59 +0100 Subject: bgmac: activate irqs only if there is nothing to poll IRQs should only get activated when there is nothing to poll in the queue any more and to after every poll. Signed-off-by: Hauke Mehrtens Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index aa9f950..3007d95 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1167,10 +1167,10 @@ static int bgmac_poll(struct napi_struct *napi, int weight) bgmac->int_status = 0; } - if (handled < weight) + if (handled < weight) { napi_complete(napi); - - bgmac_chip_intrs_on(bgmac); + bgmac_chip_intrs_on(bgmac); + } return handled; } -- cgit v0.10.2 From 98bd5c547ef2300f915fc1adce5b6f25c195d4d4 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Mon, 19 Jan 2015 14:21:02 +0100 Subject: btrfs: sync ioctl, handle errors after transaction start The version merged to 3.19 did not handle errors from start_trancaction and could pass an invalid pointer to commit_transaction. Fixes: 6b5fe46dfa52441f ("btrfs: do commit in sync_fs if there are pending changes") Reported-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Chris Mason diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 60f7cbe..c86fb54 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1001,9 +1001,9 @@ int btrfs_sync_fs(struct super_block *sb, int wait) if (fs_info->pending_changes == 0) return 0; trans = btrfs_start_transaction(root, 0); - } else { - return PTR_ERR(trans); } + if (IS_ERR(trans)) + return PTR_ERR(trans); } return btrfs_commit_transaction(trans, root); } -- cgit v0.10.2 From 379d6854a2092e38b6e56a8067d922e31461b7e2 Mon Sep 17 00:00:00 2001 From: Tsutomu Itoh Date: Fri, 9 Jan 2015 17:37:52 +0900 Subject: Btrfs: fix incorrect freeing in scrub_stripe The address that should be freed is not 'ppath' but 'path'. Signed-off-by: Tsutomu Itoh Reviewed-by: Miao Xie Signed-off-by: Chris Mason diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 9e1569f..2f0fbc3 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -3053,7 +3053,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, ppath = btrfs_alloc_path(); if (!ppath) { - btrfs_free_path(ppath); + btrfs_free_path(path); return -ENOMEM; } -- cgit v0.10.2 From 75c68e9fbbdfc04467c9edcac76be998beaa630b Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Fri, 16 Jan 2015 13:24:40 +0000 Subject: Btrfs: fix race deleting block group from space_info->ro_bgs list When removing a block group we were deleting it from its space_info's ro_bgs list without the correct protection - the space info's spinlock. Fix this by doing the list delete while holding the spinlock of the corresponding space info, which is the correct lock for any operation on that list. This issue was introduced in the 3.19 kernel by the following change: Btrfs: move read only block groups onto their own list V2 commit 633c0aad4c0243a506a3e8590551085ad78af82d I ran into a kernel crash while a task was running statfs, which iterates the space_info->ro_bgs list while holding the space info's spinlock, and another task was deleting it from the same list, without holding that spinlock, as part of the block group remove operation (while running the function btrfs_remove_block_group). This happened often when running the stress test xfstests/generic/038 I recently made. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 7e60741..0b18070 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1171,6 +1171,7 @@ struct btrfs_space_info { struct percpu_counter total_bytes_pinned; struct list_head list; + /* Protected by the spinlock 'lock'. */ struct list_head ro_bgs; struct rw_semaphore groups_sem; diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 1511658..a684086 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -9422,7 +9422,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, * are still on the list after taking the semaphore */ list_del_init(&block_group->list); - list_del_init(&block_group->ro_list); if (list_empty(&block_group->space_info->block_groups[index])) { kobj = block_group->space_info->block_group_kobjs[index]; block_group->space_info->block_group_kobjs[index] = NULL; @@ -9464,6 +9463,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, btrfs_remove_free_space_cache(block_group); spin_lock(&block_group->space_info->lock); + list_del_init(&block_group->ro_list); block_group->space_info->total_bytes -= block_group->key.offset; block_group->space_info->bytes_readonly -= block_group->key.offset; block_group->space_info->disk_total -= block_group->key.offset * factor; -- cgit v0.10.2 From 6e1103a6e9b19dbdc348077d04a546b626911fc5 Mon Sep 17 00:00:00 2001 From: Satoru Takeuchi Date: Thu, 25 Dec 2014 18:21:41 +0900 Subject: btrfs: fix state->private cast on 32 bit machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suppress the following warning displayed on building 32bit (i686) kernel. =============================================================================== ... CC [M] fs/btrfs/extent_io.o fs/btrfs/extent_io.c: In function ‘btrfs_free_io_failure_record’: fs/btrfs/extent_io.c:2193:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] failrec = (struct io_failure_record *)state->private; ... =============================================================================== Signed-off-by: Satoru Takeuchi Reported-by: Chris Murphy Signed-off-by: Chris Mason diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 4ebabd2..790dbae 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2190,7 +2190,7 @@ void btrfs_free_io_failure_record(struct inode *inode, u64 start, u64 end) next = next_state(state); - failrec = (struct io_failure_record *)state->private; + failrec = (struct io_failure_record *)(unsigned long)state->private; free_extent_state(state); kfree(failrec); -- cgit v0.10.2 From 8cb3db24c80958647f8a1b65e4968f9f043ffc3d Mon Sep 17 00:00:00 2001 From: hayeswang Date: Mon, 19 Jan 2015 17:02:45 +0800 Subject: r8152: remove generic_ocp_read before writing For ocp_write_word() and ocp_write_byte(), there is a generic_ocp_read() which is used to read the whole 4 byte data, keep the unchanged bytes, and modify the expected bytes. However, the "byen" could be used to determine which bytes of the 4 bytes to write, so the action could be removed. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 57ec23e..0aa83fb 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -833,9 +833,6 @@ static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - - data |= __le32_to_cpu(tmp) & ~mask; tmp = __cpu_to_le32(data); generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); @@ -874,9 +871,6 @@ static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - - data |= __le32_to_cpu(tmp) & ~mask; tmp = __cpu_to_le32(data); generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); -- cgit v0.10.2 From b4d99def09389ab696a5c85db58124fe0f16d590 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Mon, 19 Jan 2015 17:02:46 +0800 Subject: r8152: remove sram_read Read OCP register 0xa43a~0xa43b would clear some flags which the hw would use, and it may let the device lost. However, the unit of reading is 4 bytes. That is, it would read 0xa438~0xa43b when calling sram_read() to read OCP_SRAM_DATA. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 0aa83fb..bf405f1 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -920,12 +920,6 @@ static void sram_write(struct r8152 *tp, u16 addr, u16 data) ocp_reg_write(tp, OCP_SRAM_DATA, data); } -static u16 sram_read(struct r8152 *tp, u16 addr) -{ - ocp_reg_write(tp, OCP_SRAM_ADDR, addr); - return ocp_reg_read(tp, OCP_SRAM_DATA); -} - static int read_mii_word(struct net_device *netdev, int phy_id, int reg) { struct r8152 *tp = netdev_priv(netdev); @@ -2512,24 +2506,18 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) data = ocp_reg_read(tp, OCP_POWER_CFG); data |= EN_10M_PLLOFF; ocp_reg_write(tp, OCP_POWER_CFG, data); - data = sram_read(tp, SRAM_IMPEDANCE); - data &= ~RX_DRIVING_MASK; - sram_write(tp, SRAM_IMPEDANCE, data); + sram_write(tp, SRAM_IMPEDANCE, 0x0b13); ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); ocp_data |= PFM_PWM_SWITCH; ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); - data = sram_read(tp, SRAM_LPF_CFG); - data |= LPF_AUTO_TUNE; - sram_write(tp, SRAM_LPF_CFG, data); + /* Enable LPF corner auto tune */ + sram_write(tp, SRAM_LPF_CFG, 0xf70f); - data = sram_read(tp, SRAM_10M_AMP1); - data |= GDAC_IB_UPALL; - sram_write(tp, SRAM_10M_AMP1, data); - data = sram_read(tp, SRAM_10M_AMP2); - data |= AMP_DN; - sram_write(tp, SRAM_10M_AMP2, data); + /* Adjust 10M Amplitude */ + sram_write(tp, SRAM_10M_AMP1, 0x00af); + sram_write(tp, SRAM_10M_AMP2, 0x0208); set_bit(PHY_RESET, &tp->flags); } -- cgit v0.10.2 From 38bdf45f4aa5cb6186d50a29e6cbbd9d486a1519 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 18 Jan 2015 09:46:10 -0600 Subject: bus: mvebu-mbus: fix support of MBus window 13 On Armada XP, 375 and 38x the MBus window 13 has the remap capability, like windows 0 to 7. However, the mvebu-mbus driver isn't currently taking into account this special case, which means that when window 13 is actually used, the remap registers are left to 0, making the device using this MBus window unavailable. As a minimal fix for stable, don't use window 13. A full fix will follow later. Fixes: fddddb52a6c ("bus: introduce an Marvell EBU MBus driver") Cc: # v3.10+ Reviewed-by: Thomas Petazzoni Signed-off-by: Andrew Lunn diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index eb7682d..81bf297 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -210,12 +210,25 @@ static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus, } /* Checks whether the given window number is available */ + +/* On Armada XP, 375 and 38x the MBus window 13 has the remap + * capability, like windows 0 to 7. However, the mvebu-mbus driver + * isn't currently taking into account this special case, which means + * that when window 13 is actually used, the remap registers are left + * to 0, making the device using this MBus window unavailable. The + * quick fix for stable is to not use window 13. A follow up patch + * will correctly handle this window. +*/ static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus, const int win) { void __iomem *addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset(win); u32 ctrl = readl(addr + WIN_CTRL_OFF); + + if (win == 13) + return false; + return !(ctrl & WIN_CTRL_ENABLE); } -- cgit v0.10.2 From a8c1d28ac3925b99b5a939617d3fef1644298ee8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 19 Jan 2015 22:34:51 +0300 Subject: s2io: use snprintf() as a safety feature "sp->desc[i]" has 25 characters. "dev->name" has 15 characters. If we used all 15 characters then the sprintf() would overflow. I changed the "sprintf(sp->name, "%s Neterion %s"" to snprintf(), as well, even though it can't overflow just to be consistent. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index f5e4b82..db0c7a9 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -6987,7 +6987,9 @@ static int s2io_add_isr(struct s2io_nic *sp) if (sp->s2io_entries[i].in_use == MSIX_FLG) { if (sp->s2io_entries[i].type == MSIX_RING_TYPE) { - sprintf(sp->desc[i], "%s:MSI-X-%d-RX", + snprintf(sp->desc[i], + sizeof(sp->desc[i]), + "%s:MSI-X-%d-RX", dev->name, i); err = request_irq(sp->entries[i].vector, s2io_msix_ring_handle, @@ -6996,7 +6998,9 @@ static int s2io_add_isr(struct s2io_nic *sp) sp->s2io_entries[i].arg); } else if (sp->s2io_entries[i].type == MSIX_ALARM_TYPE) { - sprintf(sp->desc[i], "%s:MSI-X-%d-TX", + snprintf(sp->desc[i], + sizeof(sp->desc[i]), + "%s:MSI-X-%d-TX", dev->name, i); err = request_irq(sp->entries[i].vector, s2io_msix_fifo_handle, @@ -8154,7 +8158,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) "%s: UDP Fragmentation Offload(UFO) enabled\n", dev->name); /* Initialize device name */ - sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name); + snprintf(sp->name, sizeof(sp->name), "%s Neterion %s", dev->name, + sp->product_name); if (vlan_tag_strip) sp->vlan_strip_flag = 1; -- cgit v0.10.2 From c772be52319de9756fd82f36d37a6d3e003441e3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 20 Jan 2015 09:07:04 +1030 Subject: param: fix uninitialized read with CONFIG_DEBUG_LOCK_ALLOC ignore_lockdep is uninitialized, and sysfs_attr_init() doesn't initialize it, so memset to 0. Reported-by: Huang Ying Cc: Eric W. Biederman Signed-off-by: Rusty Russell diff --git a/kernel/params.c b/kernel/params.c index bd65d136..728e05b 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -642,6 +642,7 @@ static __modinit int add_sysfs_param(struct module_kobject *mk, mk->mp->grp.attrs = new_attrs; /* Tack new one on the end. */ + memset(&mk->mp->attrs[mk->mp->num], 0, sizeof(mk->mp->attrs[0])); sysfs_attr_init(&mk->mp->attrs[mk->mp->num].mattr.attr); mk->mp->attrs[mk->mp->num].param = kp; mk->mp->attrs[mk->mp->num].mattr.show = param_attr_show; -- cgit v0.10.2 From d453cded05ee219b77815ea194dc36efa5398bca Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 20 Jan 2015 09:07:04 +1030 Subject: module_arch_freeing_init(): new hook for archs before module->module_init freed. Archs have been abusing module_free() to clean up their arch-specific allocations. Since module_free() is also (ab)used by BPF and trace code, let's keep it to simple allocations, and provide a hook called before that. This means that avr32, ia64, parisc and s390 no longer need to implement their own module_free() at all. avr32 doesn't need module_finalize() either. Signed-off-by: Rusty Russell Cc: Chris Metcalf Cc: Haavard Skinnemoen Cc: Hans-Christian Egtvedt Cc: Tony Luck Cc: Fenghua Yu Cc: "James E.J. Bottomley" Cc: Helge Deller Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: linux-kernel@vger.kernel.org Cc: linux-ia64@vger.kernel.org Cc: linux-parisc@vger.kernel.org Cc: linux-s390@vger.kernel.org diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c index 2c94129..164efa0 100644 --- a/arch/avr32/kernel/module.c +++ b/arch/avr32/kernel/module.c @@ -19,12 +19,10 @@ #include #include -void module_free(struct module *mod, void *module_region) +void module_arch_freeing_init(struct module *mod) { vfree(mod->arch.syminfo); mod->arch.syminfo = NULL; - - vfree(module_region); } static inline int check_rela(Elf32_Rela *rela, struct module *module, @@ -291,12 +289,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, return ret; } - -int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, - struct module *module) -{ - vfree(module->arch.syminfo); - module->arch.syminfo = NULL; - - return 0; -} diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index 24603be..29754aa 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c @@ -305,14 +305,12 @@ plt_target (struct plt_entry *plt) #endif /* !USE_BRL */ void -module_free (struct module *mod, void *module_region) +module_arch_freeing_init (struct module *mod) { - if (mod && mod->arch.init_unw_table && - module_region == mod->module_init) { + if (mod->arch.init_unw_table) { unw_remove_unwind_table(mod->arch.init_unw_table); mod->arch.init_unw_table = NULL; } - vfree(module_region); } /* Have we already seen one of these relocations? */ diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 50dfafc..5822e8e 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -298,14 +298,10 @@ static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n) } #endif - -/* Free memory returned from module_alloc */ -void module_free(struct module *mod, void *module_region) +void module_arch_freeing_init(struct module *mod) { kfree(mod->arch.section); mod->arch.section = NULL; - - vfree(module_region); } /* Additional bytes needed in front of individual sections */ diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index b89b591..409d152 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -55,14 +55,10 @@ void *module_alloc(unsigned long size) } #endif -/* Free memory returned from module_alloc */ -void module_free(struct module *mod, void *module_region) +void module_arch_freeing_init(struct module *mod) { - if (mod) { - vfree(mod->arch.syminfo); - mod->arch.syminfo = NULL; - } - vfree(module_region); + vfree(mod->arch.syminfo); + mod->arch.syminfo = NULL; } static void check_rela(Elf_Rela *rela, struct module *me) diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c index 96447c9..62a597e 100644 --- a/arch/tile/kernel/module.c +++ b/arch/tile/kernel/module.c @@ -83,7 +83,7 @@ void module_free(struct module *mod, void *module_region) 0, 0, 0, NULL, NULL, 0); /* - * FIXME: If module_region == mod->module_init, trim exception + * FIXME: Add module_arch_freeing_init to trim exception * table entries. */ } diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index 7eeb9bb..054eac8 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -82,4 +82,6 @@ int module_finalize(const Elf_Ehdr *hdr, /* Any cleanup needed when module leaves. */ void module_arch_cleanup(struct module *mod); +/* Any cleanup before freeing mod->module_init */ +void module_arch_freeing_init(struct module *mod); #endif diff --git a/kernel/module.c b/kernel/module.c index 3965511..68be0b1f 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1804,6 +1804,10 @@ void __weak module_arch_cleanup(struct module *mod) { } +void __weak module_arch_freeing_init(struct module *mod) +{ +} + /* Free a module, remove from lists, etc. */ static void free_module(struct module *mod) { @@ -1841,6 +1845,7 @@ static void free_module(struct module *mod) /* This may be NULL, but that's OK */ unset_module_init_ro_nx(mod); + module_arch_freeing_init(mod); module_free(mod, mod->module_init); kfree(mod->args); percpu_modfree(mod); @@ -2930,6 +2935,7 @@ static struct module *layout_and_allocate(struct load_info *info, int flags) static void module_deallocate(struct module *mod, struct load_info *info) { percpu_modfree(mod); + module_arch_freeing_init(mod); module_free(mod, mod->module_init); module_free(mod, mod->module_core); } @@ -3055,6 +3061,7 @@ static int do_init_module(struct module *mod) mod->strtab = mod->core_strtab; #endif unset_module_init_ro_nx(mod); + module_arch_freeing_init(mod); module_free(mod, mod->module_init); mod->module_init = NULL; mod->init_size = 0; -- cgit v0.10.2 From be1f221c0445a4157d177197c236f888d3581914 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 20 Jan 2015 09:07:05 +1030 Subject: module: remove mod arg from module_free, rename module_memfree(). Nothing needs the module pointer any more, and the next patch will call it from RCU, where the module itself might no longer exist. Removing the arg is the safest approach. This just codifies the use of the module_alloc/module_free pattern which ftrace and bpf use. Signed-off-by: Rusty Russell Acked-by: Alexei Starovoitov Cc: Mikael Starvik Cc: Jesper Nilsson Cc: Ralf Baechle Cc: Ley Foon Tan Cc: Benjamin Herrenschmidt Cc: Chris Metcalf Cc: Steven Rostedt Cc: x86@kernel.org Cc: Ananth N Mavinakayanahalli Cc: Anil S Keshavamurthy Cc: Masami Hiramatsu Cc: linux-cris-kernel@axis.com Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: nios2-dev@lists.rocketboards.org Cc: linuxppc-dev@lists.ozlabs.org Cc: sparclinux@vger.kernel.org Cc: netdev@vger.kernel.org diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c index 51123f9..af04cb6 100644 --- a/arch/cris/kernel/module.c +++ b/arch/cris/kernel/module.c @@ -36,7 +36,7 @@ void *module_alloc(unsigned long size) } /* Free memory returned from module_alloc */ -void module_free(struct module *mod, void *module_region) +void module_memfree(void *module_region) { kfree(module_region); } diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c index 9fd6834..5d61393 100644 --- a/arch/mips/net/bpf_jit.c +++ b/arch/mips/net/bpf_jit.c @@ -1388,7 +1388,7 @@ out: void bpf_jit_free(struct bpf_prog *fp) { if (fp->jited) - module_free(NULL, fp->bpf_func); + module_memfree(fp->bpf_func); bpf_prog_unlock_free(fp); } diff --git a/arch/nios2/kernel/module.c b/arch/nios2/kernel/module.c index cc924a3..e2e3f13 100644 --- a/arch/nios2/kernel/module.c +++ b/arch/nios2/kernel/module.c @@ -36,7 +36,7 @@ void *module_alloc(unsigned long size) } /* Free memory returned from module_alloc */ -void module_free(struct module *mod, void *module_region) +void module_memfree(void *module_region) { kfree(module_region); } diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 1ca125b..d1916b5 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -699,7 +699,7 @@ out: void bpf_jit_free(struct bpf_prog *fp) { if (fp->jited) - module_free(NULL, fp->bpf_func); + module_memfree(fp->bpf_func); bpf_prog_unlock_free(fp); } diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index f33e7c7..7931eee 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c @@ -776,7 +776,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; if (unlikely(proglen + ilen > oldproglen)) { pr_err("bpb_jit_compile fatal error\n"); kfree(addrs); - module_free(NULL, image); + module_memfree(image); return; } memcpy(image + proglen, temp, ilen); @@ -822,7 +822,7 @@ out: void bpf_jit_free(struct bpf_prog *fp) { if (fp->jited) - module_free(NULL, fp->bpf_func); + module_memfree(fp->bpf_func); bpf_prog_unlock_free(fp); } diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c index 62a597e..2305084 100644 --- a/arch/tile/kernel/module.c +++ b/arch/tile/kernel/module.c @@ -74,7 +74,7 @@ error: /* Free memory returned from module_alloc */ -void module_free(struct module *mod, void *module_region) +void module_memfree(void *module_region) { vfree(module_region); diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 2142376..8b7b0a5 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -674,7 +674,7 @@ static inline void *alloc_tramp(unsigned long size) } static inline void tramp_free(void *tramp) { - module_free(NULL, tramp); + module_memfree(tramp); } #else /* Trampolines can only be created if modules are supported */ diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index 054eac8..f755626 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -26,7 +26,7 @@ unsigned int arch_mod_section_prepend(struct module *mod, unsigned int section); void *module_alloc(unsigned long size); /* Free memory returned from module_alloc. */ -void module_free(struct module *mod, void *module_region); +void module_memfree(void *module_region); /* * Apply the given relocation to the (simplified) ELF. Return -error diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index d6594e4..a64e7a2 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -163,7 +163,7 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, void bpf_jit_binary_free(struct bpf_binary_header *hdr) { - module_free(NULL, hdr); + module_memfree(hdr); } #endif /* CONFIG_BPF_JIT */ diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 06f5830..ee61992 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -127,7 +127,7 @@ static void *alloc_insn_page(void) static void free_insn_page(void *page) { - module_free(NULL, page); + module_memfree(page); } struct kprobe_insn_cache kprobe_insn_slots = { diff --git a/kernel/module.c b/kernel/module.c index 68be0b1f..1f85fd5 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1795,7 +1795,7 @@ static void unset_module_core_ro_nx(struct module *mod) { } static void unset_module_init_ro_nx(struct module *mod) { } #endif -void __weak module_free(struct module *mod, void *module_region) +void __weak module_memfree(void *module_region) { vfree(module_region); } @@ -1846,7 +1846,7 @@ static void free_module(struct module *mod) /* This may be NULL, but that's OK */ unset_module_init_ro_nx(mod); module_arch_freeing_init(mod); - module_free(mod, mod->module_init); + module_memfree(mod->module_init); kfree(mod->args); percpu_modfree(mod); @@ -1855,7 +1855,7 @@ static void free_module(struct module *mod) /* Finally, free the core (containing the module structure) */ unset_module_core_ro_nx(mod); - module_free(mod, mod->module_core); + module_memfree(mod->module_core); #ifdef CONFIG_MPU update_protections(current->mm); @@ -2790,7 +2790,7 @@ static int move_module(struct module *mod, struct load_info *info) */ kmemleak_ignore(ptr); if (!ptr) { - module_free(mod, mod->module_core); + module_memfree(mod->module_core); return -ENOMEM; } memset(ptr, 0, mod->init_size); @@ -2936,8 +2936,8 @@ static void module_deallocate(struct module *mod, struct load_info *info) { percpu_modfree(mod); module_arch_freeing_init(mod); - module_free(mod, mod->module_init); - module_free(mod, mod->module_core); + module_memfree(mod->module_init); + module_memfree(mod->module_core); } int __weak module_finalize(const Elf_Ehdr *hdr, @@ -3062,7 +3062,7 @@ static int do_init_module(struct module *mod) #endif unset_module_init_ro_nx(mod); module_arch_freeing_init(mod); - module_free(mod, mod->module_init); + module_memfree(mod->module_init); mod->module_init = NULL; mod->init_size = 0; mod->init_ro_size = 0; -- cgit v0.10.2 From c749637909eea5d4090c6f50b89c2c20b534a280 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 20 Jan 2015 09:07:05 +1030 Subject: module: fix race in kallsyms resolution during module load success. The kallsyms routines (module_symbol_name, lookup_module_* etc) disable preemption to walk the modules rather than taking the module_mutex: this is because they are used for symbol resolution during oopses. This works because there are synchronize_sched() and synchronize_rcu() in the unload and failure paths. However, there's one case which doesn't have that: the normal case where module loading succeeds, and we free the init section. We don't want a synchronize_rcu() there, because it would slow down module loading: this bug was introduced in 2009 to speed module loading in the first place. Thus, we want to do the free in an RCU callback. We do this in the simplest possible way by allocating a new rcu_head: if we put it in the module structure we'd have to worry about that getting freed. Reported-by: Rui Xiang Signed-off-by: Rusty Russell diff --git a/kernel/module.c b/kernel/module.c index 1f85fd5..ed4ec9c 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2989,10 +2989,31 @@ static void do_mod_ctors(struct module *mod) #endif } +/* For freeing module_init on success, in case kallsyms traversing */ +struct mod_initfree { + struct rcu_head rcu; + void *module_init; +}; + +static void do_free_init(struct rcu_head *head) +{ + struct mod_initfree *m = container_of(head, struct mod_initfree, rcu); + module_memfree(m->module_init); + kfree(m); +} + /* This is where the real work happens */ static int do_init_module(struct module *mod) { int ret = 0; + struct mod_initfree *freeinit; + + freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL); + if (!freeinit) { + ret = -ENOMEM; + goto fail; + } + freeinit->module_init = mod->module_init; /* * We want to find out whether @mod uses async during init. Clear @@ -3005,18 +3026,7 @@ static int do_init_module(struct module *mod) if (mod->init != NULL) ret = do_one_initcall(mod->init); if (ret < 0) { - /* - * Init routine failed: abort. Try to protect us from - * buggy refcounters. - */ - mod->state = MODULE_STATE_GOING; - synchronize_sched(); - module_put(mod); - blocking_notifier_call_chain(&module_notify_list, - MODULE_STATE_GOING, mod); - free_module(mod); - wake_up_all(&module_wq); - return ret; + goto fail_free_freeinit; } if (ret > 0) { pr_warn("%s: '%s'->init suspiciously returned %d, it should " @@ -3062,15 +3072,34 @@ static int do_init_module(struct module *mod) #endif unset_module_init_ro_nx(mod); module_arch_freeing_init(mod); - module_memfree(mod->module_init); mod->module_init = NULL; mod->init_size = 0; mod->init_ro_size = 0; mod->init_text_size = 0; + /* + * We want to free module_init, but be aware that kallsyms may be + * walking this with preempt disabled. In all the failure paths, + * we call synchronize_rcu/synchronize_sched, but we don't want + * to slow down the success path, so use actual RCU here. + */ + call_rcu(&freeinit->rcu, do_free_init); mutex_unlock(&module_mutex); wake_up_all(&module_wq); return 0; + +fail_free_freeinit: + kfree(freeinit); +fail: + /* Try to protect us from buggy refcounters. */ + mod->state = MODULE_STATE_GOING; + synchronize_sched(); + module_put(mod); + blocking_notifier_call_chain(&module_notify_list, + MODULE_STATE_GOING, mod); + free_module(mod); + wake_up_all(&module_wq); + return ret; } static int may_init_module(void) -- cgit v0.10.2 From 7ecd0bde5bfea524a843ad8fa8cb66ccbce68779 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 14 Jan 2015 11:11:03 -0200 Subject: ARM: dts: imx25: Fix PWM "per" clocks Currently PWM functionality is broken on mx25 due to the wrong assignment of the PWM "per" clock. According to Documentation/devicetree/bindings/clock/imx25-clock.txt: pwm_ipg_per 52 ,so update the pwm "per" to use 'pwm_ipg_per' instead of 'per10' clock. With this change PWM can work fine on mx25. Cc: Reported-by: Carlos Soto Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index d238676..e4d3aec 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -369,7 +369,7 @@ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; #pwm-cells = <2>; reg = <0x53fa0000 0x4000>; - clocks = <&clks 106>, <&clks 36>; + clocks = <&clks 106>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <36>; }; @@ -388,7 +388,7 @@ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; #pwm-cells = <2>; reg = <0x53fa8000 0x4000>; - clocks = <&clks 107>, <&clks 36>; + clocks = <&clks 107>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <41>; }; @@ -429,7 +429,7 @@ pwm4: pwm@53fc8000 { compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; reg = <0x53fc8000 0x4000>; - clocks = <&clks 108>, <&clks 36>; + clocks = <&clks 108>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <42>; }; @@ -476,7 +476,7 @@ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; #pwm-cells = <2>; reg = <0x53fe0000 0x4000>; - clocks = <&clks 105>, <&clks 36>; + clocks = <&clks 105>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <26>; }; -- cgit v0.10.2 From 99531e6063283da4468741185fe48b8eb037d919 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 17 Jan 2015 17:47:37 -0500 Subject: scsi_debug: use atomic allocation in resp_rsup_opcodes resp_rsup_opcodes() may get called from atomic context and would need to use GFP_ATOMIC for allocations: [ 1237.913419] BUG: sleeping function called from invalid context at mm/slub.c:1262 [ 1237.914865] in_atomic(): 1, irqs_disabled(): 0, pid: 7556, name: trinity-c311 [ 1237.916142] 3 locks held by trinity-c311/7556: [ 1237.916981] #0: (sb_writers#5){.+.+.+}, at: do_readv_writev (include/linux/fs.h:2346 fs/read_write.c:844) [ 1237.919713] #1: (&of->mutex){+.+.+.}, at: kernfs_fop_write (fs/kernfs/file.c:297) [ 1237.922626] Mutex: counter: -1 owner: trinity-c311 [ 1237.924044] #2: (s_active#51){.+.+.+}, at: kernfs_fop_write (fs/kernfs/file.c:297) [ 1237.925960] Preemption disabled blk_execute_rq_nowait (block/blk-exec.c:95) [ 1237.927416] [ 1237.927680] CPU: 24 PID: 7556 Comm: trinity-c311 Not tainted 3.19.0-rc4-next-20150116-sasha-00054-g4ad498c-dirty #1744 [ 1237.929603] ffff8804fc9d8000 ffff8804d9bc3548 ffffffff9d439fb2 0000000000000000 [ 1237.931097] 0000000000000000 ffff8804d9bc3588 ffffffff9a18389a ffff8804d9bc3598 [ 1237.932466] ffffffff9a1b1715 ffffffffa15935d8 ffffffff9e6f8cb1 00000000000004ee [ 1237.933984] Call Trace: [ 1237.934434] dump_stack (lib/dump_stack.c:52) [ 1237.935323] ___might_sleep (kernel/sched/core.c:7339) [ 1237.936259] ? mark_held_locks (kernel/locking/lockdep.c:2549) [ 1237.937293] __might_sleep (kernel/sched/core.c:7305) [ 1237.938272] __kmalloc (mm/slub.c:1262 mm/slub.c:2419 mm/slub.c:2491 mm/slub.c:3291) [ 1237.939137] ? resp_rsup_opcodes (include/linux/slab.h:435 drivers/scsi/scsi_debug.c:1689) [ 1237.940173] resp_rsup_opcodes (include/linux/slab.h:435 drivers/scsi/scsi_debug.c:1689) [ 1237.941211] ? add_host_store (drivers/scsi/scsi_debug.c:1584) [ 1237.942261] scsi_debug_queuecommand (drivers/scsi/scsi_debug.c:5276) [ 1237.943404] ? blk_rq_map_sg (block/blk-merge.c:254) [ 1237.944398] ? scsi_init_sgtable (drivers/scsi/scsi_lib.c:1095) [ 1237.945402] sdebug_queuecommand_lock_or_not (drivers/scsi/scsi_debug.c:5300) [ 1237.946735] scsi_dispatch_cmd (drivers/scsi/scsi_lib.c:1706) [ 1237.947720] scsi_queue_rq (drivers/scsi/scsi_lib.c:1996) [ 1237.948687] __blk_mq_run_hw_queue (block/blk-mq.c:816) [ 1237.949796] blk_mq_run_hw_queue (block/blk-mq.c:896) [ 1237.950903] ? _raw_spin_unlock (./arch/x86/include/asm/preempt.h:95 include/linux/spinlock_api_smp.h:154 kernel/locking/spinlock.c:183) [ 1237.951862] blk_mq_insert_request (block/blk-mq.c:1037) [ 1237.952876] blk_execute_rq_nowait (block/blk-exec.c:95) [ 1237.953981] ? lockdep_init_map (kernel/locking/lockdep.c:3034) [ 1237.954967] blk_execute_rq (block/blk-exec.c:131) [ 1237.955929] ? blk_rq_bio_prep (block/blk-core.c:2835) [ 1237.956913] scsi_execute (drivers/scsi/scsi_lib.c:252) [ 1237.957821] scsi_execute_req_flags (drivers/scsi/scsi_lib.c:281) [ 1237.958968] scsi_report_opcode (drivers/scsi/scsi.c:956) [ 1237.960009] sd_revalidate_disk (drivers/scsi/sd.c:2707 drivers/scsi/sd.c:2792) [ 1237.961139] revalidate_disk (fs/block_dev.c:1081) [ 1237.962223] sd_rescan (drivers/scsi/sd.c:1532) [ 1237.963142] scsi_rescan_device (drivers/scsi/scsi_scan.c:1579) [ 1237.964165] store_rescan_field (drivers/scsi/scsi_sysfs.c:672) [ 1237.965254] dev_attr_store (drivers/base/core.c:138) [ 1237.966319] sysfs_kf_write (fs/sysfs/file.c:131) [ 1237.967289] kernfs_fop_write (fs/kernfs/file.c:311) [ 1237.968274] do_readv_writev (fs/read_write.c:722 fs/read_write.c:854) [ 1237.969295] ? __acct_update_integrals (kernel/tsacct.c:145) [ 1237.970452] ? kernfs_fop_open (fs/kernfs/file.c:271) [ 1237.971505] ? _raw_spin_unlock (./arch/x86/include/asm/preempt.h:95 include/linux/spinlock_api_smp.h:154 kernel/locking/spinlock.c:183) [ 1237.972512] ? context_tracking_user_exit (include/linux/vtime.h:89 include/linux/jump_label.h:114 include/trace/events/context_tracking.h:47 kernel/context_tracking.c:140) [ 1237.973668] ? trace_hardirqs_on_caller (kernel/locking/lockdep.c:2578 kernel/locking/lockdep.c:2625) [ 1237.974882] ? trace_hardirqs_on (kernel/locking/lockdep.c:2633) [ 1237.975850] vfs_writev (fs/read_write.c:893) [ 1237.976691] SyS_writev (fs/read_write.c:926 fs/read_write.c:917) [ 1237.977538] system_call_fastpath (arch/x86/kernel/entry_64.S:423) Signed-off-by: Sasha Levin Acked-by: Douglas Gilbert Signed-off-by: Christoph Hellwig diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 7b8b51b..9a74f42 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1631,7 +1631,7 @@ resp_rsup_opcodes(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) a_len = 8192; else a_len = alloc_len; - arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_KERNEL); + arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_ATOMIC); if (NULL == arr) { mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, INSUFF_RES_ASCQ); -- cgit v0.10.2 From 91724c20613484555ba7e7b3d8549dac1e24f7a8 Mon Sep 17 00:00:00 2001 From: "Ewan D. Milne" Date: Thu, 15 Jan 2015 10:02:12 -0500 Subject: scsi: Avoid crashing if device uses DIX but adapter does not support it This can happen if a multipathed device uses DIX and another path is added via an adapter that does not support it. Multipath should not allow this path to be added, but we should not depend upon that to avoid crashing. Signed-off-by: Ewan D. Milne Reviewed-by: Martin K. Petersen Signed-off-by: Christoph Hellwig diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 6d5c0b8..17bb541 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1143,7 +1143,17 @@ int scsi_init_io(struct scsi_cmnd *cmd) struct scsi_data_buffer *prot_sdb = cmd->prot_sdb; int ivecs, count; - BUG_ON(prot_sdb == NULL); + if (prot_sdb == NULL) { + /* + * This can happen if someone (e.g. multipath) + * queues a command to a device on an adapter + * that does not support DIX. + */ + WARN_ON_ONCE(1); + error = BLKPREP_KILL; + goto err_exit; + } + ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio); if (scsi_alloc_sgtable(prot_sdb, ivecs, is_mq)) { -- cgit v0.10.2 From fb32c76d16aa40f3057f53273ac483a8e2468004 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 13 Jan 2015 17:57:53 +0000 Subject: VFS: Convert file->f_dentry->d_inode to file_inode() Convert file->f_dentry->d_inode to file_inode() so as to get layered filesystems right. Found with: git grep '[.>]f_dentry' Signed-off-by: David Howells Signed-off-by: Al Viro diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c index 08a313f..f772068 100644 --- a/arch/cris/arch-v32/drivers/sync_serial.c +++ b/arch/cris/arch-v32/drivers/sync_serial.c @@ -604,7 +604,7 @@ static ssize_t __sync_serial_read(struct file *file, struct timespec *ts) { unsigned long flags; - int dev = MINOR(file->f_dentry->d_inode->i_rdev); + int dev = MINOR(file_inode(file)->i_rdev); int avail; struct sync_port *port; unsigned char *start; -- cgit v0.10.2 From b568b8601f05a591a7ff09d8ee1cedb5b2e815fe Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Tue, 20 Jan 2015 10:21:05 +0800 Subject: x86/xen: Treat SCI interrupt as normal GSI interrupt Currently Xen Domain0 has special treatment for ACPI SCI interrupt, that is initialize irq for ACPI SCI at early stage in a special way as: xen_init_IRQ() ->pci_xen_initial_domain() ->xen_setup_acpi_sci() Allocate and initialize irq for ACPI SCI Function xen_setup_acpi_sci() calls acpi_gsi_to_irq() to get an irq number for ACPI SCI. But unfortunately acpi_gsi_to_irq() depends on IOAPIC irqdomains through following path acpi_gsi_to_irq() ->mp_map_gsi_to_irq() ->mp_map_pin_to_irq() ->check IOAPIC irqdomain For PV domains, it uses Xen event based interrupt manangement and doesn't make uses of native IOAPIC, so no irqdomains created for IOAPIC. This causes Xen domain0 fail to install interrupt handler for ACPI SCI and all ACPI events will be lost. Please refer to: https://lkml.org/lkml/2014/12/19/178 So the fix is to get rid of special treatment for ACPI SCI, just treat ACPI SCI as normal GSI interrupt as: acpi_gsi_to_irq() ->acpi_register_gsi() ->acpi_register_gsi_xen() ->xen_register_gsi() With above change, there's no need for xen_setup_acpi_sci() anymore. The above change also works with bare metal kernel too. Signed-off-by: Jiang Liu Tested-by: Sander Eikelenboom Cc: Tony Luck Cc: xen-devel@lists.xenproject.org Cc: Konrad Rzeszutek Wilk Cc: David Vrabel Cc: Rafael J. Wysocki Cc: Len Brown Cc: Pavel Machek Cc: Bjorn Helgaas Link: http://lkml.kernel.org/r/1421720467-7709-2-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index d162636..b9e30da 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -611,20 +611,20 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) { - int irq; - - if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { - *irqp = gsi; - } else { - mutex_lock(&acpi_ioapic_lock); - irq = mp_map_gsi_to_irq(gsi, - IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); - mutex_unlock(&acpi_ioapic_lock); - if (irq < 0) - return -1; - *irqp = irq; + int rc, irq, trigger, polarity; + + rc = acpi_get_override_irq(gsi, &trigger, &polarity); + if (rc == 0) { + trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; + polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; + irq = acpi_register_gsi(NULL, gsi, trigger, polarity); + if (irq >= 0) { + *irqp = irq; + return 0; + } } - return 0; + + return -1; } EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index c489ef2..6e5e89c 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -471,52 +471,6 @@ int __init pci_xen_hvm_init(void) } #ifdef CONFIG_XEN_DOM0 -static __init void xen_setup_acpi_sci(void) -{ - int rc; - int trigger, polarity; - int gsi = acpi_sci_override_gsi; - int irq = -1; - int gsi_override = -1; - - if (!gsi) - return; - - rc = acpi_get_override_irq(gsi, &trigger, &polarity); - if (rc) { - printk(KERN_WARNING "xen: acpi_get_override_irq failed for acpi" - " sci, rc=%d\n", rc); - return; - } - trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; - polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; - - printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " - "polarity=%d\n", gsi, trigger, polarity); - - /* Before we bind the GSI to a Linux IRQ, check whether - * we need to override it with bus_irq (IRQ) value. Usually for - * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: - * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) - * but there are oddballs where the IRQ != GSI: - * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) - * which ends up being: gsi_to_irq[9] == 20 - * (which is what acpi_gsi_to_irq ends up calling when starting the - * the ACPI interpreter and keels over since IRQ 9 has not been - * setup as we had setup IRQ 20 for it). - */ - if (acpi_gsi_to_irq(gsi, &irq) == 0) { - /* Use the provided value if it's valid. */ - if (irq >= 0) - gsi_override = irq; - } - - gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity); - printk(KERN_INFO "xen: acpi sci %d\n", gsi); - - return; -} - int __init pci_xen_initial_domain(void) { int irq; @@ -527,7 +481,6 @@ int __init pci_xen_initial_domain(void) x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs; pci_msi_ignore_mask = 1; #endif - xen_setup_acpi_sci(); __acpi_register_gsi = acpi_register_gsi_xen; /* Pre-allocate legacy irqs */ for (irq = 0; irq < nr_legacy_irqs(); irq++) { -- cgit v0.10.2 From 9889eaeb7c999cae64006bb98c47f40f412ec875 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Tue, 20 Jan 2015 10:21:06 +0800 Subject: ACPI: pci: Do not clear pci_dev->irq in acpi_pci_irq_disable() Xen pciback driver assumes that pci_dev->irq won't change after calling pci_disable_device(). But commit cffe0a2b5a34c95a4dadc9ec7132690a5b0f6687 ("x86, irq: Keep balance of IOAPIC pin reference count") frees irq resources and resets pci_dev->irq to zero when pci_disable_device() is called. So this is a hotfix for 3.19 to avoid resetting pci_dev->irq, and another proper fix will be prepared for next merging window. Signed-off-by: Jiang Liu Tested-by: Sander Eikelenboom Cc: Tony Luck Cc: Konrad Rzeszutek Wilk Cc: David Vrabel Cc: Rafael J. Wysocki Cc: Len Brown Link: http://lkml.kernel.org/r/1421720467-7709-3-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 5277a0e..b1def41 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -512,7 +512,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); if (gsi >= 0) { acpi_unregister_gsi(gsi); - dev->irq = 0; dev->irq_managed = 0; } } -- cgit v0.10.2 From 8abb850a03a3a8b11a0e92949e5b99d9cc178e35 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Tue, 20 Jan 2015 10:21:07 +0800 Subject: x86/xen: Override ACPI IRQ management callback __acpi_unregister_gsi Xen overrides __acpi_register_gsi and leaves __acpi_unregister_gsi as is. That means, an IRQ allocated by acpi_register_gsi_xen_hvm() or acpi_register_gsi_xen() will be freed by acpi_unregister_gsi_ioapic(), which may cause undesired effects. So override __acpi_unregister_gsi to NULL for safety. Signed-off-by: Jiang Liu Tested-by: Sander Eikelenboom Cc: Tony Luck Cc: xen-devel@lists.xenproject.org Cc: Konrad Rzeszutek Wilk Cc: David Vrabel Cc: Bjorn Helgaas Cc: Graeme Gregory Cc: Lv Zheng Link: http://lkml.kernel.org/r/1421720467-7709-4-git-send-email-jiang.liu@linux.intel.com Signed-off-by: Thomas Gleixner diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 0ab4f9f..3a45668 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -50,6 +50,7 @@ void acpi_pic_sci_set_trigger(unsigned int, u16); extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity); +extern void (*__acpi_unregister_gsi)(u32 gsi); static inline void disable_acpi(void) { diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 6e5e89c..9098d88 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -458,6 +458,7 @@ int __init pci_xen_hvm_init(void) * just how GSIs get registered. */ __acpi_register_gsi = acpi_register_gsi_xen_hvm; + __acpi_unregister_gsi = NULL; #endif #ifdef CONFIG_PCI_MSI @@ -482,6 +483,7 @@ int __init pci_xen_initial_domain(void) pci_msi_ignore_mask = 1; #endif __acpi_register_gsi = acpi_register_gsi_xen; + __acpi_unregister_gsi = NULL; /* Pre-allocate legacy irqs */ for (irq = 0; irq < nr_legacy_irqs(); irq++) { int trigger, polarity; -- cgit v0.10.2 From c7c52e482975cb9c390471df35ab85e86dbc5916 Mon Sep 17 00:00:00 2001 From: Jungseok Lee Date: Mon, 19 Jan 2015 14:57:00 +0000 Subject: arm64: Add dtb files to archclean rule As dts files have been reorganised under vendor subdirs, dtb files cannot be removed with "make distclean" now. Thus, this patch moves dtb files under archclean rule and removes unnecessary entries. Cc: Robert Richter Cc: Catalin Marinas Cc: Will Deacon Signed-off-by: Jungseok Lee Signed-off-by: Will Deacon diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 1c43cec..0666888 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -85,6 +85,7 @@ vdso_install: # We use MRPROPER_FILES and CLEAN_FILES now archclean: $(Q)$(MAKE) $(clean)=$(boot) + $(Q)$(MAKE) $(clean)=$(boot)/dts define archhelp echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)' diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index 3b8d427..c62b0f4 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -3,6 +3,4 @@ dts-dirs += apm dts-dirs += arm dts-dirs += cavium -always := $(dtb-y) subdir-y := $(dts-dirs) -clean-files := *.dtb -- cgit v0.10.2 From f285f4a21c3253887caceed493089ece17579d59 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 15 Jan 2015 16:51:46 -0800 Subject: x86, boot: Skip relocs when load address unchanged On 64-bit, relocation is not required unless the load address gets changed. Without this, relocations do unexpected things when the kernel is above 4G. Reported-by: Baoquan He Signed-off-by: Kees Cook Tested-by: Thomas D. Cc: Vivek Goyal Cc: Jan Beulich Cc: Junjie Mao Cc: Andi Kleen Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20150116005146.GA4212@www.outflux.net Signed-off-by: Thomas Gleixner diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index dcc1c53..a950864 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -373,6 +373,8 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, unsigned long output_len, unsigned long run_size) { + unsigned char *output_orig = output; + real_mode = rmode; sanitize_boot_params(real_mode); @@ -421,7 +423,12 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, debug_putstr("\nDecompressing Linux... "); decompress(input_data, input_len, NULL, NULL, output, NULL, error); parse_elf(output); - handle_relocations(output, output_len); + /* + * 32-bit always performs relocations. 64-bit relocations are only + * needed if kASLR has chosen a different load address. + */ + if (!IS_ENABLED(CONFIG_X86_64) || output != output_orig) + handle_relocations(output, output_len); debug_putstr("done.\nBooting the kernel.\n"); return output; } -- cgit v0.10.2 From 4a0d3107d6b19125f21172c2b7d95f9c30ecaf6f Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 16 Jan 2015 15:47:07 +0000 Subject: x86, irq: Properly tag virtualization entry in /proc/interrupts The mis-naming likely was a copy-and-paste effect. Signed-off-by: Jan Beulich Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/54B9408B0200007800055E8B@mail.emea.novell.com Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 6307a0f..705ef8d 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -127,7 +127,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_puts(p, " Machine check polls\n"); #endif #if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) - seq_printf(p, "%*s: ", prec, "THR"); + seq_printf(p, "%*s: ", prec, "HYP"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); seq_puts(p, " Hypervisor callback interrupts\n"); -- cgit v0.10.2 From b3f6c73db732704945408cec19f2391d3eb7483e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 9 Dec 2014 23:39:53 -0200 Subject: mfd: da9052-core: Fix platform-device id collision Allow multiple DA9052 regulators be registered by registering with PLATFORM_DEVID_AUTO instead of PLATFORM_DEVID_NONE. The subdevices are currently registered with PLATFORM_DEVID_NONE, which will cause a name collision on the platform bus when multiple regulators are registered: [ 0.128855] da9052-regulator da9052-regulator: invalid regulator ID specified [ 0.128973] da9052-regulator: probe of da9052-regulator failed with error -22 [ 0.129148] ------------[ cut here ]------------ [ 0.129200] WARNING: CPU: 0 PID: 1 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x5c/0x7c() [ 0.129233] sysfs: cannot create duplicate filename '/devices/platform/soc/60000000.aips/63fc8000.i2c/i2c-0/0-0048/da9052-regulator ... [ 0.132891] ------------[ cut here ]------------ [ 0.132924] WARNING: CPU: 0 PID: 1 at lib/kobject.c:240 kobject_add_internal+0x24c/0x2cc() [ 0.132957] kobject_add_internal failed for da9052-regulator with -EEXIST, don't try to register things with the same name in the same directory. ... [ 0.137000] da9052 0-0048: mfd_add_devices failed: -17 [ 0.138486] da9052: probe of 0-0048 failed with error -17 Based on the fix done by Johan Hovold at commit b6684228726cc255 ("mfd: viperboard: Fix platform-device id collision"). Tested on a imx53-qsb board, where multiple DA9053 regulators can be successfully probed. Signed-off-by: Fabio Estevam Signed-off-by: Lee Jones diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 52a0c2f..ae498b5 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c @@ -554,7 +554,8 @@ int da9052_device_init(struct da9052 *da9052, u8 chip_id) return ret; } - ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, + ret = mfd_add_devices(da9052->dev, PLATFORM_DEVID_AUTO, + da9052_subdev_info, ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL); if (ret) { dev_err(da9052->dev, "mfd_add_devices failed: %d\n", ret); -- cgit v0.10.2 From 773328da243978bebac82bf4c45604281edb6975 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 26 Dec 2014 13:28:20 -0600 Subject: mfd: tps65218: Make INT[12] and STATUS registers volatile STATUS register can be modified by the HW, so we should bypass cache because of that. In the case of INT[12] registers, they are the ones that actually clear the IRQ source at the time they are read. If we rely on the cache for them, we will never be able to clear the interrupt, which will cause our IRQ line to be disabled due to IRQ throttling. Fixes: 44b4dc6 mfd: tps65218: Add driver for the TPS65218 PMIC Cc: # v3.15+ Signed-off-by: Felipe Balbi Signed-off-by: Lee Jones diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c index 0d256cb..2243f75 100644 --- a/drivers/mfd/tps65218.c +++ b/drivers/mfd/tps65218.c @@ -125,10 +125,21 @@ int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg, } EXPORT_SYMBOL_GPL(tps65218_clear_bits); +static const struct regmap_range tps65218_yes_ranges[] = { + regmap_reg_range(TPS65218_REG_INT1, TPS65218_REG_INT2), + regmap_reg_range(TPS65218_REG_STATUS, TPS65218_REG_STATUS), +}; + +static const struct regmap_access_table tps65218_volatile_table = { + .yes_ranges = tps65218_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(tps65218_yes_ranges), +}; + static struct regmap_config tps65218_regmap_config = { .reg_bits = 8, .val_bits = 8, .cache_type = REGCACHE_RBTREE, + .volatile_table = &tps65218_volatile_table, }; static const struct regmap_irq tps65218_irqs[] = { -- cgit v0.10.2 From f29ae369a412942e81035984fa3d7a22ddf91fcb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 26 Dec 2014 13:28:21 -0600 Subject: mfd: tps65218: Make INT1 our status_base register If we don't tell regmap-irq that our first status register is at offset 1, it will try to read offset zero, which is the chipid register. Fixes: 44b4dc6 mfd: tps65218: Add driver for the TPS65218 PMIC Cc: # v3.15+ Signed-off-by: Felipe Balbi Signed-off-by: Lee Jones diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c index 2243f75..d6b7643 100644 --- a/drivers/mfd/tps65218.c +++ b/drivers/mfd/tps65218.c @@ -204,6 +204,7 @@ static struct regmap_irq_chip tps65218_irq_chip = { .num_regs = 2, .mask_base = TPS65218_REG_INT_MASK1, + .status_base = TPS65218_REG_INT1, }; static const struct of_device_id of_tps65218_match_table[] = { -- cgit v0.10.2 From b166010f6afbadb896efa37ff85eb681a8f89392 Mon Sep 17 00:00:00 2001 From: Roger Tseng Date: Thu, 15 Jan 2015 15:14:44 +0800 Subject: mfd: rtsx_usb: Fix runtime PM deadlock sd_set_power_mode() in derived module drivers/mmc/host/rtsx_usb_sdmmc.c acquires dev_mutex and then calls pm_runtime_get_sync() to make sure the device is awake while initializing a newly inserted card. Once it is called during suspending state and explicitly before rtsx_usb_suspend() acquires the same dev_mutex, both routine deadlock and further hang the driver because pm_runtime_get_sync() waits the pending PM operations. Fix this by using an empty suspend method. mmc_core always turns the LED off after a request is done and thus it is ok to remove the only rtsx_usb_turn_off_led() here. Cc: # v3.16+ Fixes: 730876be2566 ("mfd: Add realtek USB card reader driver") Signed-off-by: Roger Tseng [Lee: Removed newly unused variable] Signed-off-by: Lee Jones diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c index dbdd0fa..210d1f8 100644 --- a/drivers/mfd/rtsx_usb.c +++ b/drivers/mfd/rtsx_usb.c @@ -681,21 +681,9 @@ static void rtsx_usb_disconnect(struct usb_interface *intf) #ifdef CONFIG_PM static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message) { - struct rtsx_ucr *ucr = - (struct rtsx_ucr *)usb_get_intfdata(intf); - dev_dbg(&intf->dev, "%s called with pm message 0x%04x\n", __func__, message.event); - /* - * Call to make sure LED is off during suspend to save more power. - * It is NOT a permanent state and could be turned on anytime later. - * Thus no need to call turn_on when resunming. - */ - mutex_lock(&ucr->dev_mutex); - rtsx_usb_turn_off_led(ucr); - mutex_unlock(&ucr->dev_mutex); - return 0; } -- cgit v0.10.2 From 9d34cfdf47963905d792ae9c000efa522739abe4 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Mon, 12 Jan 2015 06:15:45 +0100 Subject: x86: Don't rely on VMWare emulating PAT MSR correctly VMWare seems not to emulate the PAT MSR correctly: reaeding MSR_IA32_CR_PAT returns 0 even after writing another value to it. Commit bd809af16e3ab triggers this VMWare bug when the kernel is booted as a VMWare guest. Detect this bug and don't use the read value if it is 0. Fixes: bd809af16e3ab "x86: Enable PAT to use cache mode translation tables" Reported-and-tested-by: Jongman Heo Acked-by: Alok N Kataria Signed-off-by: Juergen Gross Link: http://lkml.kernel.org/r/1421039745-14335-1-git-send-email-jgross@suse.com Signed-off-by: Thomas Gleixner diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index edf299c..7ac6869 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -234,8 +234,13 @@ void pat_init(void) PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC); /* Boot CPU check */ - if (!boot_pat_state) + if (!boot_pat_state) { rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); + if (!boot_pat_state) { + pat_disable("PAT read returns always zero, disabled."); + return; + } + } wrmsrl(MSR_IA32_CR_PAT, pat); -- cgit v0.10.2 From 32c6590d126836a062b3140ed52d898507987017 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 12 Jan 2015 16:26:02 -0800 Subject: x86, hyperv: Mark the Hyper-V clocksource as being continuous The Hyper-V clocksource is continuous; mark it accordingly. Signed-off-by: K. Y. Srinivasan Acked-by: jasowang@redhat.com Cc: gregkh@linuxfoundation.org Cc: devel@linuxdriverproject.org Cc: olaf@aepfle.de Cc: apw@canonical.com Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1421108762-3331-1-git-send-email-kys@microsoft.com Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index a450373..939155f 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -107,6 +107,7 @@ static struct clocksource hyperv_cs = { .rating = 400, /* use this when running on Hyperv*/ .read = read_hv_clock, .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static void __init ms_hyperv_init_platform(void) -- cgit v0.10.2 From 76d697d10769048e5721510100bf3a9413a56385 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 20 Jan 2015 11:00:56 +0800 Subject: blk-mq: fix hctx/ctx kobject use-after-free The kobject memory shouldn't have been freed before the kobject is released because driver core can access it freely before its release. This patch frees hctx in its release callback. For ctx, they share one single per-cpu variable which is associated with the request queue, so free ctx in q->mq_kobj's release handler. Signed-off-by: Sasha Levin (fix ctx kobjects) Signed-off-by: Ming Lei Signed-off-by: Jens Axboe diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c index 1630a20..6774a0e 100644 --- a/block/blk-mq-sysfs.c +++ b/block/blk-mq-sysfs.c @@ -15,6 +15,26 @@ static void blk_mq_sysfs_release(struct kobject *kobj) { + struct request_queue *q; + + q = container_of(kobj, struct request_queue, mq_kobj); + free_percpu(q->queue_ctx); +} + +static void blk_mq_ctx_release(struct kobject *kobj) +{ + struct blk_mq_ctx *ctx; + + ctx = container_of(kobj, struct blk_mq_ctx, kobj); + kobject_put(&ctx->queue->mq_kobj); +} + +static void blk_mq_hctx_release(struct kobject *kobj) +{ + struct blk_mq_hw_ctx *hctx; + + hctx = container_of(kobj, struct blk_mq_hw_ctx, kobj); + kfree(hctx); } struct blk_mq_ctx_sysfs_entry { @@ -318,13 +338,13 @@ static struct kobj_type blk_mq_ktype = { static struct kobj_type blk_mq_ctx_ktype = { .sysfs_ops = &blk_mq_sysfs_ops, .default_attrs = default_ctx_attrs, - .release = blk_mq_sysfs_release, + .release = blk_mq_ctx_release, }; static struct kobj_type blk_mq_hw_ktype = { .sysfs_ops = &blk_mq_hw_sysfs_ops, .default_attrs = default_hw_ctx_attrs, - .release = blk_mq_sysfs_release, + .release = blk_mq_hctx_release, }; static void blk_mq_unregister_hctx(struct blk_mq_hw_ctx *hctx) @@ -355,6 +375,7 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx) return ret; hctx_for_each_ctx(hctx, ctx, i) { + kobject_get(&q->mq_kobj); ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu); if (ret) break; diff --git a/block/blk-mq.c b/block/blk-mq.c index 2f95747..9ee3b87 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1641,10 +1641,8 @@ static void blk_mq_free_hw_queues(struct request_queue *q, struct blk_mq_hw_ctx *hctx; unsigned int i; - queue_for_each_hw_ctx(q, hctx, i) { + queue_for_each_hw_ctx(q, hctx, i) free_cpumask_var(hctx->cpumask); - kfree(hctx); - } } static int blk_mq_init_hctx(struct request_queue *q, @@ -2002,11 +2000,9 @@ void blk_mq_free_queue(struct request_queue *q) percpu_ref_exit(&q->mq_usage_counter); - free_percpu(q->queue_ctx); kfree(q->queue_hw_ctx); kfree(q->mq_map); - q->queue_ctx = NULL; q->queue_hw_ctx = NULL; q->mq_map = NULL; -- cgit v0.10.2 From 9aa609e1a3846d3c17087b62579867bab0f488de Mon Sep 17 00:00:00 2001 From: Rui Wang Date: Mon, 15 Dec 2014 11:28:26 -0800 Subject: drm: fb helper should avoid sleeping in panic context There are still some places in the fb helper that need to avoid sleeping in panic context. Here's an example: [ 65.615496] bad: scheduling from the idle thread! [ 65.620747] CPU: 92 PID: 0 Comm: swapper/92 Tainted: G M E 3.18.0-rc4-7-default+ #20 [ 65.630364] Hardware name: Intel Corporation BRICKLAND/BRICKLAND, BIOS BRHSXSD1.86B.0056.R01.1409242327 09/24/2014 [ 65.641923] ffff88087f693d80 ffff88087f689878 ffffffff81566db9 0000000000000000 [ 65.650226] ffff88087f693d80 ffff88087f689898 ffffffff810871ff ffff88046eb3e0d0 [ 65.658527] ffff88087f693d80 ffff88087f6898c8 ffffffff8107c1fa 000000017f6898b8 [ 65.666830] Call Trace: [ 65.669557] <#MC> [] dump_stack+0x46/0x58 [ 65.675994] [] dequeue_task_idle+0x2f/0x40 [ 65.682412] [] dequeue_task+0x5a/0x80 [ 65.688345] [] deactivate_task+0x23/0x30 [ 65.694569] [] __schedule+0x580/0x7f0 [ 65.700502] [] schedule_preempt_disabled+0x29/0x70 [ 65.707696] [] __ww_mutex_lock_slowpath+0xb8/0x162 [ 65.714891] [] __ww_mutex_lock+0x53/0x85 [ 65.721125] [] drm_modeset_lock+0x3d/0x110 [drm] [ 65.728132] [] __drm_modeset_lock_all+0x8a/0x120 [drm] [ 65.735721] [] drm_modeset_lock_all+0x10/0x30 [drm] [ 65.743015] [] drm_fb_helper_pan_display+0x2f/0xf0 [drm_kms_helper] [ 65.751857] [] fb_pan_display+0xd1/0x1a0 [ 65.758081] [] bit_update_start+0x20/0x50 [ 65.764400] [] fbcon_switch+0x3a2/0x550 [ 65.770528] [] redraw_screen+0x189/0x240 [ 65.776750] [] fbcon_blank+0x20a/0x2d0 [ 65.782778] [] ? erst_writer+0x209/0x330 [ 65.789002] [] ? internal_add_timer+0x63/0x80 [ 65.795710] [] ? mod_timer+0x127/0x1e0 [ 65.801740] [] do_unblank_screen+0xa8/0x1d0 [ 65.808255] [] unblank_screen+0x10/0x20 [ 65.814381] [] bust_spinlocks+0x19/0x40 [ 65.820508] [] panic+0x106/0x1f5 [ 65.825955] [] mce_panic+0x2ac/0x2e0 [ 65.831789] [] ? delay_tsc+0x4a/0x80 [ 65.837625] [] do_machine_check+0xbaf/0xbf0 [ 65.844138] [] ? intel_idle+0xc7/0x150 [ 65.850166] [] machine_check+0x1f/0x30 [ 65.856195] [] ? intel_idle+0xc7/0x150 [ 65.862222] <> [] cpuidle_enter_state+0x55/0x170 [ 65.869823] [] cpuidle_enter+0x17/0x20 [ 65.875852] [] cpu_startup_entry+0x2d8/0x370 [ 65.882467] [] start_secondary+0x159/0x180 There's __drm_modeset_lock_all() which Daniel Vetter introduced for this purpose. We can leverage that without reinventing anything. This patch works with the latest kernel. Reviewed-by: Rob Clark Tested-by: Tony Luck Signed-off-by: Rui Wang Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 52ce26d..cf775a4 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -741,7 +741,9 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) int i, j, rc = 0; int start; - drm_modeset_lock_all(dev); + if (__drm_modeset_lock_all(dev, !!oops_in_progress)) { + return -EBUSY; + } if (!drm_fb_helper_is_bound(fb_helper)) { drm_modeset_unlock_all(dev); return -EBUSY; @@ -915,7 +917,9 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, int ret = 0; int i; - drm_modeset_lock_all(dev); + if (__drm_modeset_lock_all(dev, !!oops_in_progress)) { + return -EBUSY; + } if (!drm_fb_helper_is_bound(fb_helper)) { drm_modeset_unlock_all(dev); return -EBUSY; -- cgit v0.10.2 From 6c9fe14f9d64cc12401a825a60ec5c5723496ca4 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 20 Jan 2015 17:05:33 +0800 Subject: btrfs: Fix the bug that fs_info->pending_changes is never cleared. Fs_info->pending_changes is never cleared since the original code uses cmpxchg(&fs_info->pending_changes, 0, 0), which will only clear it if pending_changes is already 0. This will cause a lot of problem when mount it with inode_cache mount option. If the btrfs is mounted as inode_cache, pending_changes will always be 1, even when the fs is frozen. Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Chris Mason diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index a605d4e..e88b59d 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -2118,7 +2118,7 @@ void btrfs_apply_pending_changes(struct btrfs_fs_info *fs_info) unsigned long prev; unsigned long bit; - prev = cmpxchg(&fs_info->pending_changes, 0, 0); + prev = xchg(&fs_info->pending_changes, 0); if (!prev) return; -- cgit v0.10.2 From a53f4f8e9c8ebe6c9ee3b34c368913aae9876e22 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Mon, 19 Jan 2015 15:42:41 +0800 Subject: btrfs: Don't call btrfs_start_transaction() on frozen fs to avoid deadlock. Commit 6b5fe46dfa52 (btrfs: do commit in sync_fs if there are pending changes) will call btrfs_start_transaction() in sync_fs(), to handle some operations needed to be done in next transaction. However this can cause deadlock if the filesystem is frozen, with the following sys_r+w output: [ 143.255932] Call Trace: [ 143.255936] [] schedule+0x29/0x70 [ 143.255939] [] __sb_start_write+0xb3/0x100 [ 143.255971] [] start_transaction+0x2e6/0x5a0 [btrfs] [ 143.255992] [] btrfs_start_transaction+0x1b/0x20 [btrfs] [ 143.256003] [] btrfs_sync_fs+0xca/0xd0 [btrfs] [ 143.256007] [] sync_fs_one_sb+0x20/0x30 [ 143.256011] [] iterate_supers+0xe1/0xf0 [ 143.256014] [] sys_sync+0x55/0x90 [ 143.256017] [] system_call_fastpath+0x12/0x17 [ 143.256111] Call Trace: [ 143.256114] [] schedule+0x29/0x70 [ 143.256119] [] rwsem_down_write_failed+0x1c5/0x2d0 [ 143.256123] [] call_rwsem_down_write_failed+0x13/0x20 [ 143.256131] [] thaw_super+0x28/0xc0 [ 143.256135] [] do_vfs_ioctl+0x3f5/0x540 [ 143.256187] [] SyS_ioctl+0x91/0xb0 [ 143.256213] [] system_call_fastpath+0x12/0x17 The reason is like the following: (Holding s_umount) VFS sync_fs staff: |- btrfs_sync_fs() |- btrfs_start_transaction() |- sb_start_intwrite() (Waiting thaw_fs to unfreeze) VFS thaw_fs staff: thaw_fs() (Waiting sync_fs to release s_umount) So deadlock happens. This can be easily triggered by fstest/generic/068 with inode_cache mount option. The fix is to check if the fs is frozen, if the fs is frozen, just return and waiting for the next transaction. Cc: David Sterba Reported-by: Gui Hecheng Signed-off-by: Qu Wenruo [enhanced comment, changed to SB_FREEZE_WRITE] Signed-off-by: David Sterba Signed-off-by: Chris Mason diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index c86fb54..6f49b28 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1000,6 +1000,16 @@ int btrfs_sync_fs(struct super_block *sb, int wait) */ if (fs_info->pending_changes == 0) return 0; + /* + * A non-blocking test if the fs is frozen. We must not + * start a new transaction here otherwise a deadlock + * happens. The pending operations are delayed to the + * next commit after thawing. + */ + if (__sb_start_write(sb, SB_FREEZE_WRITE, false)) + __sb_end_write(sb, SB_FREEZE_WRITE); + else + return 0; trans = btrfs_start_transaction(root, 0); } if (IS_ERR(trans)) -- cgit v0.10.2 From bbd5900935be8755b6344386373174b20cd474a2 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 16 Oct 2014 11:44:15 +0800 Subject: watchdog: imx2_wdt: Improve power management support. Improve power management operations(suspend and resume) as part of dev_pm_ops for IMX2 watchdog driver. If PM will be supported, please make sure that the wdev->clk could disable the watchdog's counter input clock source or can mask watchdog's reset request to the core. If watchdog is still used by consumers and resumes from deep sleep state, we need to restart the watchdog again without enabling the timer. If watchdog been has started --> stopped by the consumers and resumes from non-deep sleep state, then start the timer again. If watchdog has been started --> stopped by the consumers and resumes from deep sleep state, will do nothing. The watchdog will be restarted by consumers next time to be used. Signed-off-by: Xiubo Li Reviewed-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index d6add51..c50c7d8 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -327,18 +327,21 @@ static void imx2_wdt_shutdown(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP -/* Disable watchdog if it is active during suspend */ +/* Disable watchdog if it is active or non-active but still running */ static int imx2_wdt_suspend(struct device *dev) { struct watchdog_device *wdog = dev_get_drvdata(dev); struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); - imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); - imx2_wdt_ping(wdog); + /* The watchdog IP block is running */ + if (imx2_wdt_is_running(wdev)) { + imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); + imx2_wdt_ping(wdog); - /* Watchdog has been stopped but IP block is still running */ - if (!watchdog_active(wdog) && imx2_wdt_is_running(wdev)) - del_timer_sync(&wdev->timer); + /* The watchdog is not active */ + if (!watchdog_active(wdog)) + del_timer_sync(&wdev->timer); + } clk_disable_unprepare(wdev->clk); @@ -354,15 +357,25 @@ static int imx2_wdt_resume(struct device *dev) clk_prepare_enable(wdev->clk); if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) { - /* Resumes from deep sleep we need restart - * the watchdog again. + /* + * If the watchdog is still active and resumes + * from deep sleep state, need to restart the + * watchdog again. */ imx2_wdt_setup(wdog); imx2_wdt_set_timeout(wdog, wdog->timeout); imx2_wdt_ping(wdog); } else if (imx2_wdt_is_running(wdev)) { + /* Resuming from non-deep sleep state. */ + imx2_wdt_set_timeout(wdog, wdog->timeout); imx2_wdt_ping(wdog); - mod_timer(&wdev->timer, jiffies + wdog->timeout * HZ / 2); + /* + * But the watchdog is not active, then start + * the timer again. + */ + if (!watchdog_active(wdog)) + mod_timer(&wdev->timer, + jiffies + wdog->timeout * HZ / 2); } return 0; -- cgit v0.10.2 From 5fe65ce7ccbb47b16e17a88bcdac73cffadb80fa Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Mon, 8 Sep 2014 09:14:07 +0200 Subject: watchdog: imx2_wdt: Disable power down counter on boot Disable power down counter of the watchdog to avoid system resets. The watchdog power down counter is set automatically by the chip. If it is not set to 0 in the driver, the system resets. Signed-off-by: Markus Pargmann Acked-by: Shawn Guo Signed-off-by: Wim Van Sebroeck diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index c50c7d8..5142bba 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -52,6 +52,8 @@ #define IMX2_WDT_WRSR 0x04 /* Reset Status Register */ #define IMX2_WDT_WRSR_TOUT (1 << 1) /* -> Reset due to Timeout */ +#define IMX2_WDT_WMCR 0x08 /* Misc Register */ + #define IMX2_WDT_MAX_TIME 128 #define IMX2_WDT_DEFAULT_TIME 60 /* in seconds */ @@ -274,6 +276,13 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) imx2_wdt_ping_if_active(wdog); + /* + * Disable the watchdog power down counter at boot. Otherwise the power + * down counter will pull down the #WDOG interrupt line for one clock + * cycle. + */ + regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0); + ret = watchdog_register_device(wdog); if (ret) { dev_err(&pdev->dev, "cannot register watchdog device\n"); -- cgit v0.10.2 From 7a32757eda68a53626f003018733d09f94138334 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 21 Dec 2014 22:14:43 +0100 Subject: watchdog: drop owner assignment from platform_drivers This platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang Signed-off-by: Wim Van Sebroeck diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c index 5927c0a..bcfd2a2 100644 --- a/drivers/watchdog/cadence_wdt.c +++ b/drivers/watchdog/cadence_wdt.c @@ -503,7 +503,6 @@ static struct platform_driver cdns_wdt_driver = { .shutdown = cdns_wdt_shutdown, .driver = { .name = "cdns-wdt", - .owner = THIS_MODULE, .of_match_table = cdns_wdt_of_match, .pm = &cdns_wdt_pm_ops, }, diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c index ef6a298..1f4155e 100644 --- a/drivers/watchdog/meson_wdt.c +++ b/drivers/watchdog/meson_wdt.c @@ -215,7 +215,6 @@ static struct platform_driver meson_wdt_driver = { .remove = meson_wdt_remove, .shutdown = meson_wdt_shutdown, .driver = { - .owner = THIS_MODULE, .name = DRV_NAME, .of_match_table = meson_wdt_dt_ids, }, -- cgit v0.10.2 From 909ba297beb50981a9d12364688d3c5f3084c6eb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 20 Jan 2015 04:38:25 +0100 Subject: ARM: 8292/1: mm: fix size rounding-down of arm_add_memory() function The current rounding of "size" is wrong: - If "start" is sufficiently near the next page boundary, "size" is decremented by more than enough and the last page is lost. - If "size" is sufficiently small, it is wrapped around and gets a bogus value. Signed-off-by: Masahiro Yamada Acked-by: Geert Uytterhoeven Acked-by: Ard Biesheuvel Signed-off-by: Russell King diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index f9c8639..d13f185 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -657,10 +657,13 @@ int __init arm_add_memory(u64 start, u64 size) /* * Ensure that start/size are aligned to a page boundary. - * Size is appropriately rounded down, start is rounded up. + * Size is rounded down, start is rounded up. */ - size -= start & ~PAGE_MASK; aligned_start = PAGE_ALIGN(start); + if (aligned_start > start + size) + size = 0; + else + size -= aligned_start - start; #ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT if (aligned_start > ULONG_MAX) { -- cgit v0.10.2 From 7ffd7b4e169d619e66928fe5d997723f2c6f1056 Mon Sep 17 00:00:00 2001 From: Viktor Babrian Date: Sun, 18 Jan 2015 20:01:40 +0100 Subject: can: c_can: end pending transmission on network stop (ifdown) Put controller into init mode in network stop to end pending transmissions. The issue is observed in cases when transmitted frame is not acked. Signed-off-by: Viktor Babrian Cc: linux-stable Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index f94a9fa..c672c4d 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -615,6 +615,9 @@ static void c_can_stop(struct net_device *dev) c_can_irq_control(priv, false); + /* put ctrl to init on stop to end ongoing transmission */ + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_INIT); + /* deactivate pins */ pinctrl_pm_select_sleep_state(dev->dev.parent); priv->can.state = CAN_STATE_STOPPED; -- cgit v0.10.2 From 3cb99af5ea00da4ef3db31b45c4efaff1664c181 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 23 Dec 2014 14:02:57 -0300 Subject: [media] tlg2300: Fix media dependencies X-Patchwork-Delegate: m.chehab@samsung.com Changeset ea2e813e8cc3 moved the driver to staging, but it forgot to preserve the existing dependency. Fixes: ea2e813e8cc3 ("[media] tlg2300: move to staging in preparation for removal") Reported-by: Jim Davis Signed-off-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/tlg2300/Kconfig b/drivers/staging/media/tlg2300/Kconfig index 81784c6..77d8753 100644 --- a/drivers/staging/media/tlg2300/Kconfig +++ b/drivers/staging/media/tlg2300/Kconfig @@ -1,6 +1,7 @@ config VIDEO_TLG2300 tristate "Telegent TLG2300 USB video capture support (Deprecated)" depends on VIDEO_DEV && I2C && SND && DVB_CORE + depends on MEDIA_USB_SUPPORT select VIDEO_TUNER select VIDEO_TVEEPROM depends on RC_CORE -- cgit v0.10.2 From 721f3223f26bbe81c7e55f84188e74d99df50a16 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Mon, 22 Dec 2014 19:51:39 -0300 Subject: [media] cx23885: Split Hauppauge WinTV Starburst from HVR4400 card entry Unconditionally attaching Si2161/Si2165 demod driver breaks Hauppauge WinTV Starburst. So create own card entry for this. Add card name comments to the subsystem ids. This fixes a regression introduced in 3.17 by 36efec48e2e6016e05364906720a0ec350a5d768 ([media] cx23885: Add si2165 support for HVR-5500) Signed-off-by: Matthias Schwarzott Tested-by: Antti Palosaari Signed-off-by: Hans Verkuil CC: stable@vger.kernel.org # for 3.17 and upper Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index db99ca2..06931f6 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -614,7 +614,7 @@ struct cx23885_board cx23885_boards[] = { .portb = CX23885_MPEG_DVB, }, [CX23885_BOARD_HAUPPAUGE_HVR4400] = { - .name = "Hauppauge WinTV-HVR4400", + .name = "Hauppauge WinTV-HVR4400/HVR5500", .porta = CX23885_ANALOG_VIDEO, .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, @@ -622,6 +622,10 @@ struct cx23885_board cx23885_boards[] = { .tuner_addr = 0x60, /* 0xc0 >> 1 */ .tuner_bus = 1, }, + [CX23885_BOARD_HAUPPAUGE_STARBURST] = { + .name = "Hauppauge WinTV Starburst", + .portb = CX23885_MPEG_DVB, + }, [CX23885_BOARD_AVERMEDIA_HC81R] = { .name = "AVerTV Hybrid Express Slim HC81R", .tuner_type = TUNER_XC2028, @@ -936,19 +940,19 @@ struct cx23885_subid cx23885_subids[] = { }, { .subvendor = 0x0070, .subdevice = 0xc108, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-4400 (Model 121xxx, Hybrid DVB-T/S2, IR) */ }, { .subvendor = 0x0070, .subdevice = 0xc138, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-5500 (Model 121xxx, Hybrid DVB-T/C/S2, IR) */ }, { .subvendor = 0x0070, .subdevice = 0xc12a, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_STARBURST, /* Hauppauge WinTV Starburst (Model 121x00, DVB-S2, IR) */ }, { .subvendor = 0x0070, .subdevice = 0xc1f8, - .card = CX23885_BOARD_HAUPPAUGE_HVR4400, + .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-5500 (Model 121xxx, Hybrid DVB-T/C/S2, IR) */ }, { .subvendor = 0x1461, .subdevice = 0xd939, @@ -1545,8 +1549,9 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ break; case CX23885_BOARD_HAUPPAUGE_HVR4400: + case CX23885_BOARD_HAUPPAUGE_STARBURST: /* GPIO-8 tda10071 demod reset */ - /* GPIO-9 si2165 demod reset */ + /* GPIO-9 si2165 demod reset (only HVR4400/HVR5500)*/ /* Put the parts into reset and back */ cx23885_gpio_enable(dev, GPIO_8 | GPIO_9, 1); @@ -1872,6 +1877,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: case CX23885_BOARD_HAUPPAUGE_HVR4400: + case CX23885_BOARD_HAUPPAUGE_STARBURST: case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE: if (dev->i2c_bus[0].i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0xc0); @@ -1980,6 +1986,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; + case CX23885_BOARD_HAUPPAUGE_STARBURST: + ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_T982: ts1->gen_ctrl_val = 0x5; /* Parallel */ diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index c47d182..a9c450d 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1710,6 +1710,17 @@ static int dvb_register(struct cx23885_tsport *port) break; } break; + case CX23885_BOARD_HAUPPAUGE_STARBURST: + i2c_bus = &dev->i2c_bus[0]; + fe0->dvb.frontend = dvb_attach(tda10071_attach, + &hauppauge_tda10071_config, + &i2c_bus->i2c_adap); + if (fe0->dvb.frontend != NULL) { + dvb_attach(a8293_attach, fe0->dvb.frontend, + &i2c_bus->i2c_adap, + &hauppauge_a8293_config); + } + break; case CX23885_BOARD_DVBSKY_T9580: case CX23885_BOARD_DVBSKY_S950: i2c_bus = &dev->i2c_bus[0]; diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index f55cd12..36f2f96 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -99,6 +99,7 @@ #define CX23885_BOARD_DVBSKY_S950 49 #define CX23885_BOARD_DVBSKY_S952 50 #define CX23885_BOARD_DVBSKY_T982 51 +#define CX23885_BOARD_HAUPPAUGE_STARBURST 52 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 -- cgit v0.10.2 From d0bb12c9f4811b8a8c0a87ac1b5fbab19861e7e0 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Fri, 2 Jan 2015 14:55:17 -0300 Subject: [media] Fix Mygica T230 support Commit 2adb177e57417cf8409e86bda2c516e5f99a2099 removed 2 devices from the cxusb device table but failed to fix up the T230 properties that follow, meaning that this device no longer gets detected properly. Adjust the cxusb_table index appropriate so detection works. Signed-off-by: Jonathan McDowell Reviewed-by: Olli Salonen Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 0f345b1..f327c49 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -2232,7 +2232,7 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { { "Mygica T230 DVB-T/T2/C", { NULL }, - { &cxusb_table[22], NULL }, + { &cxusb_table[20], NULL }, }, } }; -- cgit v0.10.2 From 7d96c3e446b4a786a6a4a7733deb9d1634a9ad4d Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sun, 18 Jan 2015 16:30:11 -0300 Subject: [media] soc-camera: fix device capabilities in multiple camera host drivers The V4L2 API requires both .capabilities and .device_caps fields of struct v4l2_capability to be set. Otherwise the compliance checker complains and since commit "v4l2-ioctl: WARN_ON if querycap didn't fill device_caps" a compile-time warning is issued. Fix this non-compliance in several soc-camera camera host drivers. Reported-by: Geert Uytterhoeven Signed-off-by: Guennadi Liakhovetski Tested-by: Geert Uytterhoeven Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index ee5650f..494447f 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -760,8 +760,9 @@ static int isi_camera_querycap(struct soc_camera_host *ici, { strcpy(cap->driver, "atmel-isi"); strcpy(cap->card, "Atmel Image Sensor Interface"); - cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING); + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index ce72bd2..192377f 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c @@ -1256,7 +1256,8 @@ static int mx2_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the friendly caller:-> */ strlcpy(cap->card, MX2_CAM_DRIVER_DESCRIPTION, sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 8e52ccc..000d023 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -967,7 +967,8 @@ static int mx3_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the firendly caller:-> */ strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index e6b9328..16f65ec 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c @@ -1427,7 +1427,8 @@ static int omap1_cam_querycap(struct soc_camera_host *ici, { /* cap->name is set by the friendly caller:-> */ strlcpy(cap->card, "OMAP1 Camera", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 951226a..8d6e343 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -1576,7 +1576,8 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, { /* cap->name is set by the firendly caller:-> */ strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 5f58ed9..ca62839 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1652,7 +1652,9 @@ static int sh_mobile_ceu_querycap(struct soc_camera_host *ici, struct v4l2_capability *cap) { strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } -- cgit v0.10.2 From 42d74e4fe6508308abc1baac95ba36ad0cc5143e Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 13 Jan 2015 21:55:02 -0300 Subject: [media] rcar_vin: Update device_caps and capabilities in querycap The V4L2 API requires both .capabilities and .device_caps fields of struct v4l2_capability to be set. Otherwise the compliance checker complains and since commit "v4l2-ioctl: WARN_ON if querycap didn't fill device_caps" a compile-time warning is issued. Fix this non-compliance in the rcar_vin driver. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 44461c5..9c28278a3 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -1799,7 +1799,9 @@ static int rcar_vin_querycap(struct soc_camera_host *ici, struct v4l2_capability *cap) { strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; } -- cgit v0.10.2 From 6cf11ee6300f38b7cfc43af9b7be2afaa5e05869 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Jan 2015 06:16:18 -0300 Subject: [media] vb2: fix vb2_thread_stop race conditions The locking scheme inside the vb2 thread is unsafe when stopping the thread. In particular kthread_stop was called *after* internal data structures were cleaned up instead of doing that before. In addition, internal vb2 functions were called after threadio->stop was set to true and vb2_internal_streamoff was called. This is also not allowed. All this led to a variety of race conditions and kernel warnings and/or oopses. Fixed by moving the kthread_stop call up before the cleanup takes place, and by checking threadio->stop before calling internal vb2 queuing operations. Signed-off-by: Hans Verkuil Cc: # for v3.16 and up Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index d09a891..bc08a82 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -3146,27 +3146,26 @@ static int vb2_thread(void *data) prequeue--; } else { call_void_qop(q, wait_finish, q); - ret = vb2_internal_dqbuf(q, &fileio->b, 0); + if (!threadio->stop) + ret = vb2_internal_dqbuf(q, &fileio->b, 0); call_void_qop(q, wait_prepare, q); dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); } - if (threadio->stop) - break; - if (ret) + if (ret || threadio->stop) break; try_to_freeze(); vb = q->bufs[fileio->b.index]; if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR)) - ret = threadio->fnc(vb, threadio->priv); - if (ret) - break; + if (threadio->fnc(vb, threadio->priv)) + break; call_void_qop(q, wait_finish, q); if (set_timestamp) v4l2_get_timestamp(&fileio->b.timestamp); - ret = vb2_internal_qbuf(q, &fileio->b); + if (!threadio->stop) + ret = vb2_internal_qbuf(q, &fileio->b); call_void_qop(q, wait_prepare, q); - if (ret) + if (ret || threadio->stop) break; } @@ -3235,11 +3234,11 @@ int vb2_thread_stop(struct vb2_queue *q) threadio->stop = true; vb2_internal_streamoff(q, q->type); call_void_qop(q, wait_prepare, q); + err = kthread_stop(threadio->thread); q->fileio = NULL; fileio->req.count = 0; vb2_reqbufs(q, &fileio->req); kfree(fileio); - err = kthread_stop(threadio->thread); threadio->thread = NULL; kfree(threadio); q->fileio = NULL; -- cgit v0.10.2 From 42639f6de69433cd531c79390fd8eccf311ed44e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Jan 2015 06:23:26 -0300 Subject: [media] pvrusb2: fix missing device_caps in querycap The VIDIOC_QUERYCAP function should set device_caps, but this was missing. In addition, it set the version field as well, but that should be done by the core, not by the driver. If a driver doesn't set device_caps the v4l2 core will issue a WARN_ON, so it's important that this is set correctly. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c index 1b158f1..536210b 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c @@ -89,16 +89,6 @@ static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; module_param_array(vbi_nr, int, NULL, 0444); MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor"); -static struct v4l2_capability pvr_capability ={ - .driver = "pvrusb2", - .card = "Hauppauge WinTV pvr-usb2", - .bus_info = "usb", - .version = LINUX_VERSION_CODE, - .capabilities = (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | - V4L2_CAP_READWRITE), -}; - static struct v4l2_fmtdesc pvr_fmtdesc [] = { { .index = 0, @@ -160,10 +150,22 @@ static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability * struct pvr2_v4l2_fh *fh = file->private_data; struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); + strlcpy(cap->driver, "pvrusb2", sizeof(cap->driver)); strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw), sizeof(cap->bus_info)); strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card)); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | + V4L2_CAP_AUDIO | V4L2_CAP_RADIO | + V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS; + switch (fh->pdi->devbase.vfl_type) { + case VFL_TYPE_GRABBER: + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO; + break; + case VFL_TYPE_RADIO: + cap->device_caps = V4L2_CAP_RADIO; + break; + } + cap->device_caps |= V4L2_CAP_TUNER | V4L2_CAP_READWRITE; return 0; } -- cgit v0.10.2 From 8d4d9329cde6ff5369656d7d50630d8aac907bfa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 19 Jan 2015 07:14:14 -0300 Subject: [media] cx23885: fix free interrupt bug First free the interrupt, then disable the PCI device. The other way around will lead to this warning: Jan 19 11:42:02 telek kernel: [ 1440.161234] WARNING: CPU: 0 PID: 2191 at kernel/irq/manage.c:1311 __free_irq+0x97/0x1f0() Jan 19 11:42:02 telek kernel: [ 1440.161236] Trying to free already-free IRQ 0 Jan 19 11:42:02 telek kernel: [ 1440.161237] Modules linked in: tda8290 tda10048 cx25840 cx23885(-) altera_ci tda18271 altera_stapl videobuf2_dvb tveeprom cx2341x videobuf2_dma_sg dvb_core rc_core videobuf2_memops videobuf2_core v4l2_common videodev media nouveau x86_pkg_temp_thermal cfbfillrect cfbimgblt cfbcopyarea ttm drm_kms_helper processor button isci Jan 19 11:42:02 telek kernel: [ 1440.161266] CPU: 0 PID: 2191 Comm: rmmod Tainted: G W 3.19.0-rc1-telek #345 Jan 19 11:42:02 telek kernel: [ 1440.161268] Hardware name: ASUSTeK COMPUTER INC. Z9PE-D8 WS/Z9PE-D8 WS, BIOS 5404 02/10/2014 Jan 19 11:42:02 telek kernel: [ 1440.161270] ffffffff81bf1fce ffff8808958b7cc8 ffffffff8194a97f 0000000000000000 Jan 19 11:42:02 telek kernel: [ 1440.161274] ffff8808958b7d18 ffff8808958b7d08 ffffffff810c56b0 0000000000000286 Jan 19 11:42:02 telek kernel: [ 1440.161279] 0000000000000000 0000000000000000 ffff88089f808890 ffff88089f808800 Jan 19 11:42:02 telek kernel: [ 1440.161284] Call Trace: Jan 19 11:42:02 telek kernel: [ 1440.161290] [] dump_stack+0x4f/0x7b Jan 19 11:42:02 telek kernel: [ 1440.161295] [] warn_slowpath_common+0x80/0xc0 Jan 19 11:42:02 telek kernel: [ 1440.161299] [] warn_slowpath_fmt+0x41/0x50 Jan 19 11:42:02 telek kernel: [ 1440.161303] [] ? _raw_spin_lock_irqsave+0x56/0x70 Jan 19 11:42:02 telek kernel: [ 1440.161307] [] ? __free_irq+0x49/0x1f0 Jan 19 11:42:02 telek kernel: [ 1440.161311] [] __free_irq+0x97/0x1f0 Jan 19 11:42:02 telek kernel: [ 1440.161316] [] free_irq+0x48/0xd0 Jan 19 11:42:02 telek kernel: [ 1440.161323] [] cx23885_finidev+0x4b/0x90 [cx23885] Jan 19 11:42:02 telek kernel: [ 1440.161329] [] pci_device_remove+0x3a/0xc0 Jan 19 11:42:02 telek kernel: [ 1440.161334] [] __device_release_driver+0x7a/0xf0 Jan 19 11:42:02 telek kernel: [ 1440.161338] [] driver_detach+0xc8/0xd0 Jan 19 11:42:02 telek kernel: [ 1440.161341] [] bus_remove_driver+0x4e/0xb0 Jan 19 11:42:02 telek kernel: [ 1440.161345] [] driver_unregister+0x2b/0x60 Jan 19 11:42:02 telek kernel: [ 1440.161349] [] pci_unregister_driver+0x25/0x70 Jan 19 11:42:02 telek kernel: [ 1440.161355] [] cx23885_fini+0x10/0x12 [cx23885] Jan 19 11:42:02 telek kernel: [ 1440.161360] [] SyS_delete_module+0x1a8/0x1f0 Jan 19 11:42:02 telek kernel: [ 1440.161364] [] system_call_fastpath+0x12/0x17 Jan 19 11:42:02 telek kernel: [ 1440.161367] ---[ end trace a9c07cb5f3357020 ]--- Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index d07b04a..eadb65e 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -2049,11 +2049,11 @@ static void cx23885_finidev(struct pci_dev *pci_dev) cx23885_shutdown(dev); - pci_disable_device(pci_dev); - /* unregister stuff */ free_irq(pci_dev->irq, dev); + pci_disable_device(pci_dev); + cx23885_dev_unregister(dev); vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); v4l2_ctrl_handler_free(&dev->ctrl_handler); -- cgit v0.10.2 From 2c0108e1c02f9fc95f465adc4d2ce1ad8688290a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 1 Jan 2015 18:13:54 -0300 Subject: [media] omap3isp: Correctly set QUERYCAP capabilities device_caps in struct v4l2_capability were inadequately set in VIDIOC_QUERYCAP. Fix this. Without this a WARN_ON in the v4l2 core is triggered. This WARN_ON was added for kernel 3.19 exactly to detect these situations. Signed-off-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index b463fe1..3fe9047 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -602,10 +602,13 @@ isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap) strlcpy(cap->card, video->video.name, sizeof(cap->card)); strlcpy(cap->bus_info, "media", sizeof(cap->bus_info)); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT + | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; else - cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; + cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; return 0; } -- cgit v0.10.2 From d5db139ab3764640e0882a1746e7b9fdee33fd87 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 22 Jan 2015 11:13:14 +1030 Subject: module: make module_refcount() a signed integer. James Bottomley points out that it will be -1 during unload. It's only used for diagnostics, so let's not hide that as it could be a clue as to what's gone wrong. Cc: Jason Wessel Acked-and-documention-added-by: James Bottomley Reviewed-by: Masami Hiramatsu Signed-off-by: Rusty Russell diff --git a/include/linux/module.h b/include/linux/module.h index ebfb0e1..b653d7c 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -444,7 +444,7 @@ extern void __module_put_and_exit(struct module *mod, long code) #define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code) #ifdef CONFIG_MODULE_UNLOAD -unsigned long module_refcount(struct module *mod); +int module_refcount(struct module *mod); void __symbol_put(const char *symbol); #define symbol_put(x) __symbol_put(VMLINUX_SYMBOL_STR(x)) void symbol_put_addr(void *addr); diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 379650b..2934889 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -1979,7 +1979,7 @@ static int kdb_lsmod(int argc, const char **argv) kdb_printf("%-20s%8u 0x%p ", mod->name, mod->core_size, (void *)mod); #ifdef CONFIG_MODULE_UNLOAD - kdb_printf("%4ld ", module_refcount(mod)); + kdb_printf("%4d ", module_refcount(mod)); #endif if (mod->state == MODULE_STATE_GOING) kdb_printf(" (Unloading)"); diff --git a/kernel/module.c b/kernel/module.c index ed4ec9c..d856e96 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -772,9 +772,18 @@ static int try_stop_module(struct module *mod, int flags, int *forced) return 0; } -unsigned long module_refcount(struct module *mod) +/** + * module_refcount - return the refcount or -1 if unloading + * + * @mod: the module we're checking + * + * Returns: + * -1 if the module is in the process of unloading + * otherwise the number of references in the kernel to the module + */ +int module_refcount(struct module *mod) { - return (unsigned long)atomic_read(&mod->refcnt) - MODULE_REF_BASE; + return atomic_read(&mod->refcnt) - MODULE_REF_BASE; } EXPORT_SYMBOL(module_refcount); @@ -856,7 +865,7 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod) struct module_use *use; int printed_something = 0; - seq_printf(m, " %lu ", module_refcount(mod)); + seq_printf(m, " %i ", module_refcount(mod)); /* * Always include a trailing , so userspace can differentiate @@ -908,7 +917,7 @@ EXPORT_SYMBOL_GPL(symbol_put_addr); static ssize_t show_refcnt(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { - return sprintf(buffer, "%lu\n", module_refcount(mk->mod)); + return sprintf(buffer, "%i\n", module_refcount(mk->mod)); } static struct module_attribute modinfo_refcnt = -- cgit v0.10.2 From 0eb13208aa16ca5517835ea8f3feef091a13b984 Mon Sep 17 00:00:00 2001 From: "Shreyas B. Prabhu" Date: Wed, 14 Jan 2015 16:43:21 +0530 Subject: powerpc/powernv: Restore LPCR with LPCR_PECE1 cleared LPCR_PECE1 bit controls whether decrementer interrupts are allowed to cause exit from power-saving mode. While waking up from winkle, restoring LPCR with LPCR_PECE1 set (i.e Decrementer interrupts allowed) can cause issue in the following scenario: - All the threads in a core are offlined. The core enters deep winkle. - Spurious interrupt wakes up a thread in the core. Here LPCR is restored with LPCR_PECE1 bit set. - Since it was a spurious interrupt on a offline thread, the thread clears the interrupt and goes back to winkle. - Here before the thread executes winkle and puts the core into deep winkle, if a decrementer interrupt occurs on any of the sibling threads in the core that thread wakes up. - Since in offline loop we are flushing interrupt only in case of external interrupt, the decrementer interrupt does not get flushed. So at this stage the thread is stuck in this is loop of waking up at 0x100 due to decrementer interrupt, not flushing the interrupt as only external interrupts get flushed, entering winkle, waking up at 0x100 again. Fix this by programming PORE to restore LPCR with LPCR_PECE1 bit cleared when waking up from winkle. Signed-off-by: Shreyas B. Prabhu Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Signed-off-by: Michael Ellerman diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index b700a32..d2de7d5 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -304,7 +304,7 @@ int pnv_save_sprs_for_winkle(void) * all cpus at boot. Get these reg values of current cpu and use the * same accross all cpus. */ - uint64_t lpcr_val = mfspr(SPRN_LPCR); + uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1; uint64_t hid0_val = mfspr(SPRN_HID0); uint64_t hid1_val = mfspr(SPRN_HID1); uint64_t hid4_val = mfspr(SPRN_HID4); -- cgit v0.10.2 From d24c8163b755be4a47482ab8240090d56ca8ef9b Mon Sep 17 00:00:00 2001 From: Ley Foon Tan Date: Thu, 22 Jan 2015 17:05:16 +0800 Subject: nios2: fix kuser trampoline address __kuser_sigtramp address should be 0x1044 instead of 0x1040. Signed-off-by: Ley Foon Tan diff --git a/arch/nios2/kernel/signal.c b/arch/nios2/kernel/signal.c index f9d2788..2d0ea25 100644 --- a/arch/nios2/kernel/signal.c +++ b/arch/nios2/kernel/signal.c @@ -200,7 +200,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, /* Set up to return from userspace; jump to fixed address sigreturn trampoline on kuser page. */ - regs->ra = (unsigned long) (0x1040); + regs->ra = (unsigned long) (0x1044); /* Set up registers for signal handler */ regs->sp = (unsigned long) frame; -- cgit v0.10.2 From 3c606d35fe9766ede86a45273a628b320be13b45 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 22 Jan 2015 10:19:43 -0500 Subject: cgroup: prevent mount hang due to memory controller lifetime Since b2052564e66d ("mm: memcontrol: continue cache reclaim from offlined groups"), re-mounting the memory controller after using it is very likely to hang. The cgroup core assumes that any remaining references after deleting a cgroup are temporary in nature, and synchroneously waits for them, but the above-mentioned commit has left-over page cache pin its css until it is reclaimed naturally. That being said, swap entries and charged kernel memory have been doing the same indefinite pinning forever, the bug is just more likely to trigger with left-over page cache. Reparenting kernel memory is highly impractical, which leaves changing the cgroup assumptions to reflect this: once a controller has been mounted and used, it has internal state that is independent from mount and cgroup lifetime. It can be unmounted and remounted, but it can't be reconfigured during subsequent mounts. Don't offline the controller root as long as there are any children, dead or alive. A remount will no longer wait for these old references to drain, it will simply mount the persistent controller state again. Reported-by: "Suzuki K. Poulose" Reported-by: Will Deacon Signed-off-by: Johannes Weiner Signed-off-by: Tejun Heo diff --git a/kernel/cgroup.c b/kernel/cgroup.c index bb263d0..04cfe8a 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1909,7 +1909,7 @@ static void cgroup_kill_sb(struct super_block *sb) * * And don't kill the default root. */ - if (css_has_online_children(&root->cgrp.self) || + if (!list_empty(&root->cgrp.self.children) || root == &cgrp_dfl_root) cgroup_put(&root->cgrp); else -- cgit v0.10.2 From 3e7f7626fd49a9ffba8520a1a073f62929acad63 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 16 Dec 2014 19:45:25 +0200 Subject: of/overlay: Do not generate duplicate nodes During the course of the rewrites a bug sneaked in when dealing with children nodes of overlays, which ends up duplicating sub nodes. Simply remove the duplicate traversal of child nodes to fix. Signed-off-by: Pantelis Antoniou Signed-off-by: Grant Likely diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index ea63fbd2..352b4f2 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -114,17 +114,6 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, ret = of_overlay_apply_one(ov, tchild, child); if (ret) return ret; - - /* The properties are already copied, now do the child nodes */ - for_each_child_of_node(child, grandchild) { - ret = of_overlay_apply_single_device_node(ov, tchild, grandchild); - if (ret) { - pr_err("%s: Failed to apply single node @%s/%s\n", - __func__, tchild->full_name, - grandchild->name); - return ret; - } - } } return ret; -- cgit v0.10.2 From 15204ab1ebc5aba608cd19c83c37b98438b938b0 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Tue, 16 Dec 2014 19:45:26 +0200 Subject: of/platform: Handle of_populate drivers in notifier When using overlays with drivers calling of_populate the notifier will try to create the device twice. Using the populated bit before proceeding protects against this. Signed-off-by: Pantelis Antoniou Signed-off-by: Grant Likely diff --git a/drivers/of/platform.c b/drivers/of/platform.c index a54ec10..b0d50d7 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -566,6 +566,10 @@ static int of_platform_notify(struct notifier_block *nb, if (!of_node_check_flag(rd->dn->parent, OF_POPULATED_BUS)) return NOTIFY_OK; /* not for us */ + /* already populated? (driver using of_populate manually) */ + if (of_node_check_flag(rd->dn, OF_POPULATED)) + return NOTIFY_OK; + /* pdev_parent may be NULL when no bus platform device */ pdev_parent = of_find_device_by_node(rd->dn->parent); pdev = of_platform_device_create(rd->dn, NULL, @@ -581,6 +585,11 @@ static int of_platform_notify(struct notifier_block *nb, break; case OF_RECONFIG_CHANGE_REMOVE: + + /* already depopulated? */ + if (!of_node_check_flag(rd->dn, OF_POPULATED)) + return NOTIFY_OK; + /* find our device by node */ pdev = of_find_device_by_node(rd->dn); if (pdev == NULL) -- cgit v0.10.2 From 6d310dfb382a303cbaf838e1b680f55cef18ae03 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 22 Jan 2015 11:20:40 +0000 Subject: scsi_debug: test always evaluates to false, || should be used instead cppcheck found the following issue: (warning) Logical conjunction always evaluates to false: alloc_len < 4 && alloc_len > 65535. ..the test should be instead: if (alloc_len < 4 || alloc_len > 65536) This error was introduced by recent commit 38d5c8336e60bf6e53a1da9 ("scsi_debug: add Report supported opcodes+tmfs; Compare and write") Signed-off-by: Colin Ian King Acked-by: Douglas Gilbert Signed-off-by: Christoph Hellwig diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 9a74f42..4aca1b0 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1623,7 +1623,7 @@ resp_rsup_opcodes(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) req_opcode = cmd[3]; req_sa = get_unaligned_be16(cmd + 4); alloc_len = get_unaligned_be32(cmd + 6); - if (alloc_len < 4 && alloc_len > 0xffff) { + if (alloc_len < 4 || alloc_len > 0xffff) { mk_sense_invalid_fld(scp, SDEB_IN_CDB, 6, -1); return check_condition_result; } -- cgit v0.10.2 From 2a5a69d8f79bfe1c98ee59cc91e9e743290c5d4e Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Wed, 21 Jan 2015 09:13:41 -0700 Subject: MAINTAINERS: Remove self as isci maintainer Removing myself as a maintainer. Signed-off-by: Dave Jiang Signed-off-by: Christoph Hellwig diff --git a/MAINTAINERS b/MAINTAINERS index f6dee56..5daac16 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4951,7 +4951,6 @@ K: \b(ABS|SYN)_MT_ INTEL C600 SERIES SAS CONTROLLER DRIVER M: Intel SCU Linux support M: Artur Paszkiewicz -M: Dave Jiang L: linux-scsi@vger.kernel.org T: git git://git.code.sf.net/p/intel-sas/isci S: Supported -- cgit v0.10.2 From 44b4dad9b5719f28ce1635d4c2dc08c398a1815b Mon Sep 17 00:00:00 2001 From: Tyrel Datwyler Date: Mon, 12 Jan 2015 16:31:35 -0800 Subject: MAINTAINERS: ibmvfc driver maintainer change Change maintainer of ibmvfc driver to Tyrel Datwyler. Signed-off-by: Tyrel Datwyler Cc: Nathan Fontenot Cc: Brian King Signed-off-by: Christoph Hellwig diff --git a/MAINTAINERS b/MAINTAINERS index 5daac16..047582f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4761,7 +4761,7 @@ F: drivers/scsi/ibmvscsi/ibmvscsi* F: drivers/scsi/ibmvscsi/viosrp.h IBM Power Virtual FC Device Drivers -M: Brian King +M: Tyrel Datwyler L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/ibmvscsi/ibmvfc* -- cgit v0.10.2 From bcbde52b14b70c6b3d500e8d18c261d7b1c6fed3 Mon Sep 17 00:00:00 2001 From: Tyrel Datwyler Date: Mon, 12 Jan 2015 16:31:34 -0800 Subject: MAINTAINERS: ibmvscsi driver maintainer change Change maintainer of ibmvscsi driver to Tyrel Datwyler. Signed-off-by: Tyrel Datwyler Acked-by: Nathan Fontenot Cc: Brian King Signed-off-by: Christoph Hellwig diff --git a/MAINTAINERS b/MAINTAINERS index 047582f..2a97e05 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4754,7 +4754,7 @@ S: Supported F: drivers/net/ethernet/ibm/ibmveth.* IBM Power Virtual SCSI Device Drivers -M: Nathan Fontenot +M: Tyrel Datwyler L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/ibmvscsi/ibmvscsi* -- cgit v0.10.2 From f175aa2c9f6cc08f043e85ea37f44ef3676cbac1 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 19 Jan 2015 11:17:31 +0100 Subject: MAINTAINERS: Update Richard Zhu's email address The old cryptic address bounces, fix it by using a properly working one. Signed-off-by: Lucas Stach Signed-off-by: Bjorn Helgaas Acked-by: Richard Zhu diff --git a/MAINTAINERS b/MAINTAINERS index ddb9ac8..c78f2d1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7229,7 +7229,7 @@ S: Maintained F: drivers/pci/host/*layerscape* PCI DRIVER FOR IMX6 -M: Richard Zhu +M: Richard Zhu M: Lucas Stach L: linux-pci@vger.kernel.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -- cgit v0.10.2 From 814564a0a1d2faee11ff9de43245d78cb79c85ac Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 8 Jan 2015 14:30:20 -0800 Subject: x86, mpx: Explicitly disable 32-bit MPX support on 64-bit kernels We had originally planned on submitting MPX support in one patch set. We eventually broke it up in to two pieces for easier review. One of the features that didn't make the first round was supporting 32-bit binaries on 64-bit kernels. Once we split the set up, we never added code to restrict 32-bit binaries from _using_ MPX on 64-bit kernels. The 32-bit bounds tables are a different format than the 64-bit ones. Without this patch, the kernel will try to read a 32-bit binary's tables as if they were the 64-bit version. They will likely be noticed as being invalid rather quickly and the app will get killed, but that's kinda mean. This patch adds an explicit check, and will make a 64-bit kernel essentially behave as if it has no MPX support when called from a 32-bit binary. Signed-off-by: Dave Hansen Cc: Andy Lutomirski Cc: Dave Hansen Link: http://lkml.kernel.org/r/20150108223020.9E9AA511@viggo.jf.intel.com Signed-off-by: Thomas Gleixner diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c index 67ebf57..c439ec4 100644 --- a/arch/x86/mm/mpx.c +++ b/arch/x86/mm/mpx.c @@ -349,6 +349,12 @@ static __user void *task_get_bounds_dir(struct task_struct *tsk) return MPX_INVALID_BOUNDS_DIR; /* + * 32-bit binaries on 64-bit kernels are currently + * unsupported. + */ + if (IS_ENABLED(CONFIG_X86_64) && test_thread_flag(TIF_IA32)) + return MPX_INVALID_BOUNDS_DIR; + /* * The bounds directory pointer is stored in a register * only accessible if we first do an xsave. */ -- cgit v0.10.2 From c922228efeeefa32e57f875764bfa6ca8053a68a Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 8 Jan 2015 14:30:21 -0800 Subject: x86, mpx: Fix potential performance issue on unmaps The 3.19 merge window saw some TLB modifications merged which caused a performance regression. They were fixed in commit 045bbb9fa. Once that fix was applied, I also noticed that there was a small but intermittent regression still present. It was not present consistently enough to bisect reliably, but I'm fairly confident that it came from (my own) MPX patches. The source was reading a relatively unused field in the mm_struct via arch_unmap. I also noted that this code was in the main instruction flow of do_munmap() and probably had more icache impact than we want. This patch does two things: 1. Adds a static (via Kconfig) and dynamic (via cpuid) check for MPX with cpu_feature_enabled(). This keeps us from reading that cacheline in the mm and trades it for a check of the global CPUID variables at least on CPUs without MPX. 2. Adds an unlikely() to ensure that the MPX call ends up out of the main instruction flow in do_munmap(). I've added a detailed comment about why this was done and why we want it even on systems where MPX is present. Signed-off-by: Dave Hansen Cc: luto@amacapital.net Cc: Dave Hansen Link: http://lkml.kernel.org/r/20150108223021.AEEAB987@viggo.jf.intel.com Signed-off-by: Thomas Gleixner diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 40269a2..4b75d59 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -130,7 +130,25 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long start, unsigned long end) { - mpx_notify_unmap(mm, vma, start, end); + /* + * mpx_notify_unmap() goes and reads a rarely-hot + * cacheline in the mm_struct. That can be expensive + * enough to be seen in profiles. + * + * The mpx_notify_unmap() call and its contents have been + * observed to affect munmap() performance on hardware + * where MPX is not present. + * + * The unlikely() optimizes for the fast case: no MPX + * in the CPU, or no MPX use in the process. Even if + * we get this wrong (in the unlikely event that MPX + * is widely enabled on some system) the overhead of + * MPX itself (reading bounds tables) is expected to + * overwhelm the overhead of getting this unlikely() + * consistently wrong. + */ + if (unlikely(cpu_feature_enabled(X86_FEATURE_MPX))) + mpx_notify_unmap(mm, vma, start, end); } #endif /* _ASM_X86_MMU_CONTEXT_H */ -- cgit v0.10.2 From e9d1b4f3c60997fe197bf0243cb4a41a44387a88 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 8 Jan 2015 14:30:22 -0800 Subject: x86, mpx: Strictly enforce empty prctl() args Description from Michael Kerrisk. He suggested an identical patch to one I had already coded up and tested. commit fe3d197f8431 "x86, mpx: On-demand kernel allocation of bounds tables" added two new prctl() operations, PR_MPX_ENABLE_MANAGEMENT and PR_MPX_DISABLE_MANAGEMENT. However, no checks were included to ensure that unused arguments are zero, as is done in many existing prctl()s and as should be done for all new prctl()s. This patch adds the required checks. Suggested-by: Andy Lutomirski Suggested-by: Michael Kerrisk Signed-off-by: Dave Hansen Cc: Dave Hansen Link: http://lkml.kernel.org/r/20150108223022.7F56FD13@viggo.jf.intel.com Signed-off-by: Thomas Gleixner diff --git a/kernel/sys.c b/kernel/sys.c index a8c9f5a..ea9c881 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2210,9 +2210,13 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, up_write(&me->mm->mmap_sem); break; case PR_MPX_ENABLE_MANAGEMENT: + if (arg2 || arg3 || arg4 || arg5) + return -EINVAL; error = MPX_ENABLE_MANAGEMENT(me); break; case PR_MPX_DISABLE_MANAGEMENT: + if (arg2 || arg3 || arg4 || arg5) + return -EINVAL; error = MPX_DISABLE_MANAGEMENT(me); break; default: -- cgit v0.10.2 From e30ab185c490e9a9381385529e0fd32f0a399495 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 22 Jan 2015 11:27:58 -0800 Subject: x86, tls, ldt: Stop checking lm in LDT_empty 32-bit programs don't have an lm bit in their ABI, so they can't reliably cause LDT_empty to return true without resorting to memset. They shouldn't need to do this. This should fix a longstanding, if minor, issue in all 64-bit kernels as well as a potential regression in the TLS hardening code. Fixes: 41bdc78544b8 x86/tls: Validate TLS entries to protect espfix Cc: stable@vger.kernel.org Signed-off-by: Andy Lutomirski Cc: torvalds@linux-foundation.org Link: http://lkml.kernel.org/r/72a059de55e86ad5e2935c80aa91880ddf19d07c.1421954363.git.luto@amacapital.net Signed-off-by: Thomas Gleixner diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 50d033a..fc237fd 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -251,7 +251,8 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; } -#define _LDT_empty(info) \ +/* This intentionally ignores lm, since 32-bit apps don't have that field. */ +#define LDT_empty(info) \ ((info)->base_addr == 0 && \ (info)->limit == 0 && \ (info)->contents == 0 && \ @@ -261,12 +262,6 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) (info)->seg_not_present == 1 && \ (info)->useable == 0) -#ifdef CONFIG_X86_64 -#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0)) -#else -#define LDT_empty(info) (_LDT_empty(info)) -#endif - static inline void clear_LDT(void) { set_ldt(NULL, 0); -- cgit v0.10.2 From 3669ef9fa7d35f573ec9c0e0341b29251c2734a7 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 22 Jan 2015 11:27:59 -0800 Subject: x86, tls: Interpret an all-zero struct user_desc as "no segment" The Witcher 2 did something like this to allocate a TLS segment index: struct user_desc u_info; bzero(&u_info, sizeof(u_info)); u_info.entry_number = (uint32_t)-1; syscall(SYS_set_thread_area, &u_info); Strictly speaking, this code was never correct. It should have set read_exec_only and seg_not_present to 1 to indicate that it wanted to find a free slot without putting anything there, or it should have put something sensible in the TLS slot if it wanted to allocate a TLS entry for real. The actual effect of this code was to allocate a bogus segment that could be used to exploit espfix. The set_thread_area hardening patches changed the behavior, causing set_thread_area to return -EINVAL and crashing the game. This changes set_thread_area to interpret this as a request to find a free slot and to leave it empty, which isn't *quite* what the game expects but should be close enough to keep it working. In particular, using the code above to allocate two segments will allocate the same segment both times. According to FrostbittenKing on Github, this fixes The Witcher 2. If this somehow still causes problems, we could instead allocate a limit==0 32-bit data segment, but that seems rather ugly to me. Fixes: 41bdc78544b8 x86/tls: Validate TLS entries to protect espfix Signed-off-by: Andy Lutomirski Cc: stable@vger.kernel.org Cc: torvalds@linux-foundation.org Link: http://lkml.kernel.org/r/0cb251abe1ff0958b8e468a9a9a905b80ae3a746.1421954363.git.luto@amacapital.net Signed-off-by: Thomas Gleixner diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index fc237fd..a94b82e 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -262,6 +262,19 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) (info)->seg_not_present == 1 && \ (info)->useable == 0) +/* Lots of programs expect an all-zero user_desc to mean "no segment at all". */ +static inline bool LDT_zero(const struct user_desc *info) +{ + return (info->base_addr == 0 && + info->limit == 0 && + info->contents == 0 && + info->read_exec_only == 0 && + info->seg_32bit == 0 && + info->limit_in_pages == 0 && + info->seg_not_present == 0 && + info->useable == 0); +} + static inline void clear_LDT(void) { set_ldt(NULL, 0); diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index 4e942f3..7fc5e84 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c @@ -29,7 +29,28 @@ static int get_free_idx(void) static bool tls_desc_okay(const struct user_desc *info) { - if (LDT_empty(info)) + /* + * For historical reasons (i.e. no one ever documented how any + * of the segmentation APIs work), user programs can and do + * assume that a struct user_desc that's all zeros except for + * entry_number means "no segment at all". This never actually + * worked. In fact, up to Linux 3.19, a struct user_desc like + * this would create a 16-bit read-write segment with base and + * limit both equal to zero. + * + * That was close enough to "no segment at all" until we + * hardened this function to disallow 16-bit TLS segments. Fix + * it up by interpreting these zeroed segments the way that they + * were almost certainly intended to be interpreted. + * + * The correct way to ask for "no segment at all" is to specify + * a user_desc that satisfies LDT_empty. To keep everything + * working, we accept both. + * + * Note that there's a similar kludge in modify_ldt -- look at + * the distinction between modes 1 and 0x11. + */ + if (LDT_empty(info) || LDT_zero(info)) return true; /* @@ -71,7 +92,7 @@ static void set_tls_desc(struct task_struct *p, int idx, cpu = get_cpu(); while (n-- > 0) { - if (LDT_empty(info)) + if (LDT_empty(info) || LDT_zero(info)) desc->a = desc->b = 0; else fill_ldt(desc, info); -- cgit v0.10.2 From 31bb7723706ba9660504a6c3903ea46198f98fd1 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 22 Jan 2015 12:43:17 +0100 Subject: x86, mm: Change cachemode exports to non-gpl Commit 281d4078bec3 ("x86: Make page cache mode a real type") introduced the symbols __cachemode2pte_tbl and __pte2cachemode_tbl and exported them via EXPORT_SYMBOL_GPL. The exports are part of a replacement of code which has been EXPORT_SYMBOL before these changes resulting in build breakage of out-of-tree non-gpl modules. Change EXPORT_SYMBOL_GPL to EXPORT-SYMBOL for these two symbols. Fixes: 281d4078bec3 "x86: Make page cache mode a real type" Reported-and-tested-by: Steven Noonan Signed-off-by: Juergen Gross Reviewed-by: Toshi Kani Link: http://lkml.kernel.org/r/1421926997-28615-1-git-send-email-jgross@suse.com Signed-off-by: Thomas Gleixner diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 08a7d31..079c3b6 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -43,7 +43,7 @@ uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = { [_PAGE_CACHE_MODE_WT] = _PAGE_PCD, [_PAGE_CACHE_MODE_WP] = _PAGE_PCD, }; -EXPORT_SYMBOL_GPL(__cachemode2pte_tbl); +EXPORT_SYMBOL(__cachemode2pte_tbl); uint8_t __pte2cachemode_tbl[8] = { [__pte2cm_idx(0)] = _PAGE_CACHE_MODE_WB, [__pte2cm_idx(_PAGE_PWT)] = _PAGE_CACHE_MODE_WC, @@ -54,7 +54,7 @@ uint8_t __pte2cachemode_tbl[8] = { [__pte2cm_idx(_PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx(_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, }; -EXPORT_SYMBOL_GPL(__pte2cachemode_tbl); +EXPORT_SYMBOL(__pte2cachemode_tbl); static unsigned long __initdata pgt_buf_start; static unsigned long __initdata pgt_buf_end; -- cgit v0.10.2 From dc4515ea26d6c7fed3d978cd2bd36adc0d057bc5 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 23 Jan 2015 13:22:47 +1030 Subject: scsi: always increment reference count James reported: > After e513cc1 module: Remove stop_machine from module unloading, > module_refcount() is returning (unsigned long)-1 when called from within > a routine that runs in module_exit. This is confusing the scsi device > put code which is coded to detect a module_refcount() of zero for > running within a module exit routine and not try to do another > module_put. The fix is to restore the original behaviour of > module_refcount() and return zero if we're running inside an exit > routine. The correct fix is to turn try_module_get() into __module_get(), and always do the module_put(). Acked-by: James Bottomley Signed-off-by: Rusty Russell diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index e028854..9b38299 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -986,9 +986,9 @@ int scsi_device_get(struct scsi_device *sdev) return -ENXIO; if (!get_device(&sdev->sdev_gendev)) return -ENXIO; - /* We can fail this if we're doing SCSI operations + /* We can fail try_module_get if we're doing SCSI operations * from module exit (like cache flush) */ - try_module_get(sdev->host->hostt->module); + __module_get(sdev->host->hostt->module); return 0; } @@ -1004,14 +1004,7 @@ EXPORT_SYMBOL(scsi_device_get); */ void scsi_device_put(struct scsi_device *sdev) { -#ifdef CONFIG_MODULE_UNLOAD - struct module *module = sdev->host->hostt->module; - - /* The module refcount will be zero if scsi_device_get() - * was called from a module removal routine */ - if (module && module_refcount(module) != 0) - module_put(module); -#endif + module_put(sdev->host->hostt->module); put_device(&sdev->sdev_gendev); } EXPORT_SYMBOL(scsi_device_put); -- cgit v0.10.2 From 38a1dfda8e77d7ba74c94d06d8bc41ba98a4bc8c Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 22 Jan 2015 22:58:49 +0000 Subject: x86/apic: Re-enable PCI_MSI support for non-SMP X86_32 Commit 0dbc6078c06bc0 ('x86, build, pci: Fix PCI_MSI build on !SMP') introduced the dependency that X86_UP_APIC is only available when PCI_MSI is false. This effectively prevents PCI_MSI support on 32bit UP systems because it disables both APIC and IO-APIC. But APIC support is architecturally required for PCI_MSI. The intention of the patch was to enforce APIC support when PCI_MSI is enabled, but failed to do so. Remove the !PCI_MSI dependency from X86_UP_APIC and enforce X86_UP_APIC when PCI_MSI support is enabled on 32bit UP systems. [ tglx: Massaged changelog ] Fixes 0dbc6078c06bc0 'x86, build, pci: Fix PCI_MSI build on !SMP' Signed-off-by: Bryan O'Donoghue Suggested-by: Thomas Gleixner Reviewed-by: Andy Shevchenko Cc: Thomas Petazzoni Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1421967529-9037-1-git-send-email-pure.logic@nexus-software.ie Signed-off-by: Thomas Gleixner diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ba397bd..0dc9d01 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -857,7 +857,7 @@ source "kernel/Kconfig.preempt" config X86_UP_APIC bool "Local APIC support on uniprocessors" - depends on X86_32 && !SMP && !X86_32_NON_STANDARD && !PCI_MSI + depends on X86_32 && !SMP && !X86_32_NON_STANDARD ---help--- A local APIC (Advanced Programmable Interrupt Controller) is an integrated interrupt controller in the CPU. If you have a single-CPU @@ -868,6 +868,10 @@ config X86_UP_APIC performance counters), and the NMI watchdog which detects hard lockups. +config X86_UP_APIC_MSI + def_bool y + select X86_UP_APIC if X86_32 && !SMP && !X86_32_NON_STANDARD && PCI_MSI + config X86_UP_IOAPIC bool "IO-APIC support on uniprocessors" depends on X86_UP_APIC -- cgit v0.10.2 From 2af81d6718f5ec92b1d787e0fe79b0d3b6f78601 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 21 Jan 2015 22:19:34 +0200 Subject: mac80211: only roll back station states for WDS when suspending In normal cases (i.e. when we are fully associated), cfg80211 takes care of removing all the stations before calling suspend in mac80211. But in the corner case when we suspend during authentication or association, mac80211 needs to roll back the station states. But we shouldn't roll back the station states in the suspend function, because this is taken care of in other parts of the code, except for WDS interfaces. For AP types of interfaces, cfg80211 takes care of disconnecting all stations before calling the driver's suspend code. For station interfaces, this is done in the quiesce code. For WDS interfaces we still need to do it here, so move the code into a new switch case for WDS. Cc: stable@kernel.org [3.15+] Signed-off-by: Luciano Coelho Signed-off-by: Johannes Berg diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 4c5192e..4a95fe3 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -86,20 +86,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) } } - /* tear down aggregation sessions and remove STAs */ - mutex_lock(&local->sta_mtx); - list_for_each_entry(sta, &local->sta_list, list) { - if (sta->uploaded) { - enum ieee80211_sta_state state; - - state = sta->sta_state; - for (; state > IEEE80211_STA_NOTEXIST; state--) - WARN_ON(drv_sta_state(local, sta->sdata, sta, - state, state - 1)); - } - } - mutex_unlock(&local->sta_mtx); - /* remove all interfaces that were created in the driver */ list_for_each_entry(sdata, &local->interfaces, list) { if (!ieee80211_sdata_running(sdata)) @@ -111,6 +97,21 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) case NL80211_IFTYPE_STATION: ieee80211_mgd_quiesce(sdata); break; + case NL80211_IFTYPE_WDS: + /* tear down aggregation sessions and remove STAs */ + mutex_lock(&local->sta_mtx); + sta = sdata->u.wds.sta; + if (sta && sta->uploaded) { + enum ieee80211_sta_state state; + + state = sta->sta_state; + for (; state > IEEE80211_STA_NOTEXIST; state--) + WARN_ON(drv_sta_state(local, sta->sdata, + sta, state, + state - 1)); + } + mutex_unlock(&local->sta_mtx); + break; default: break; } -- cgit v0.10.2 From fb142f4bbb7d718b3d9cc8f27c909b4809545f5c Mon Sep 17 00:00:00 2001 From: Fred Chou Date: Tue, 20 Jan 2015 10:17:27 +0800 Subject: mac80211: correct header length calculation HT Control field may also be present in management frames, as defined in 8.2.4.1.10 of 802.11-2012. Account for this in calculation of header length. Signed-off-by: Fred Chou Signed-off-by: Johannes Berg diff --git a/net/wireless/util.c b/net/wireless/util.c index d0ac795..5488c36 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -308,6 +308,12 @@ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc) goto out; } + if (ieee80211_is_mgmt(fc)) { + if (ieee80211_has_order(fc)) + hdrlen += IEEE80211_HT_CTL_LEN; + goto out; + } + if (ieee80211_is_ctl(fc)) { /* * ACK and CTS are 10 bytes, all others 16. To see how -- cgit v0.10.2 From 520452172e6b318f3a8bd9d4fe1e25066393de25 Mon Sep 17 00:00:00 2001 From: Alexandre Demers Date: Tue, 9 Dec 2014 01:27:50 -0500 Subject: x86/tsc: Change Fast TSC calibration failed from error to info Many users see this message when booting without knowning that it is of no importance and that TSC calibration may have succeeded by another way. As explained by Paul Bolle in http://lkml.kernel.org/r/1348488259.1436.22.camel@x61.thuisdomein "Fast TSC calibration failed" should not be considered as an error since other calibration methods are being tried afterward. At most, those send a warning if they fail (not an error). So let's change the message from error to warning. [ tglx: Make if pr_info. It's really not important at all ] Fixes: c767a54ba065 x86/debug: Add KERN_ to bare printks, convert printks to pr_ Signed-off-by: Alexandre Demers Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1418106470-6906-1-git-send-email-alexandre.f.demers@gmail.com Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index b7e50bb..5054497 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -617,7 +617,7 @@ static unsigned long quick_pit_calibrate(void) goto success; } } - pr_err("Fast TSC calibration failed\n"); + pr_info("Fast TSC calibration failed\n"); return 0; success: -- cgit v0.10.2 From 3a5c5e81d8128a9e43abc52b75dd21d3da7a0cfc Mon Sep 17 00:00:00 2001 From: Mathy Vanhoef Date: Tue, 20 Jan 2015 15:05:08 +0100 Subject: mac80211: properly set CCK flag in radiotap Fix a regression introduced by commit a5e70697d0c4 ("mac80211: add radiotap flag and handling for 5/10 MHz") where the IEEE80211_CHAN_CCK channel type flag was incorrectly replaced by the IEEE80211_CHAN_OFDM flag. This commit fixes that by using the CCK flag again. Cc: stable@vger.kernel.org Fixes: a5e70697d0c4 ("mac80211: add radiotap flag and handling for 5/10 MHz") Signed-off-by: Mathy Vanhoef Signed-off-by: Johannes Berg diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 683b10f..d69ca51 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -272,7 +272,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, else if (rate && rate->flags & IEEE80211_RATE_ERP_G) channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ; else if (rate) - channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ; + channel_flags |= IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ; else channel_flags |= IEEE80211_CHAN_2GHZ; put_unaligned_le16(channel_flags, pos); -- cgit v0.10.2 From 0fa7b39131576dd1baa6ca17fca53c65d7f62249 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 23 Jan 2015 11:10:12 +0100 Subject: nl80211: fix per-station group key get/del and memory leak In case userspace attempts to obtain key information for or delete a unicast key, this is currently erroneously rejected unless the driver sets the WIPHY_FLAG_IBSS_RSN flag. Apparently enough drivers do so it was never noticed. Fix that, and while at it fix a potential memory leak: the error path in the get_key() function was placed after allocating a message but didn't free it - move it to a better place. Luckily admin permissions are needed to call this operation. Cc: stable@vger.kernel.org Fixes: e31b82136d1ad ("cfg80211/mac80211: allow per-station GTKs") Signed-off-by: Johannes Berg diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7ca4b51..8887c6e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2854,6 +2854,9 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->get_key) return -EOPNOTSUPP; + if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) + return -ENOENT; + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; @@ -2873,10 +2876,6 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) goto nla_put_failure; - if (pairwise && mac_addr && - !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) - return -ENOENT; - err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie, get_key_callback); @@ -3047,7 +3046,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) wdev_lock(dev->ieee80211_ptr); err = nl80211_key_allowed(dev->ieee80211_ptr); - if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr && + if (key.type == NL80211_KEYTYPE_GROUP && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) err = -ENOENT; -- cgit v0.10.2 From 284be28565efe262a81972d12e9264d4824a4ced Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 22 Jan 2015 20:52:10 +0000 Subject: arm64: dump: Fix implicit inclusion of definition for PCI_IOBASE Since c9465b4ec37a68425 (arm64: add support to dump the kernel page tables) allmodconfig has failed to build on arm64 as a result of: ../arch/arm64/mm/dump.c:55:20: error: 'PCI_IOBASE' undeclared here (not in a function) Fix this by explicitly including io.h to ensure that a definition is present. Signed-off-by: Mark Brown Signed-off-by: Will Deacon diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c index cf33f33..d54dc9a 100644 --- a/arch/arm64/mm/dump.c +++ b/arch/arm64/mm/dump.c @@ -15,6 +15,7 @@ */ #include #include +#include #include #include #include -- cgit v0.10.2 From 63ea0a49ae0b145b91ff2b070c01b66fc75854b9 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Thu, 8 Jan 2015 11:59:03 +0100 Subject: KVM: x86: Fix of previously incomplete fix for CVE-2014-8480 STR and SLDT with rip-relative operand can cause a host kernel oops. Mark them as DstMem as well. Cc: stable@vger.linux.org Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 169b09d..817c6ca 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -3791,8 +3791,8 @@ static const struct opcode group5[] = { }; static const struct opcode group6[] = { - DI(Prot, sldt), - DI(Prot, str), + DI(Prot | DstMem, sldt), + DI(Prot | DstMem, str), II(Prot | Priv | SrcMem16, em_lldt, lldt), II(Prot | Priv | SrcMem16, em_ltr, ltr), N, N, N, N, -- cgit v0.10.2 From f3747379accba8e95d70cec0eae0582c8c182050 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Thu, 1 Jan 2015 23:11:11 +0200 Subject: KVM: x86: SYSENTER emulation is broken SYSENTER emulation is broken in several ways: 1. It misses the case of 16-bit code segments completely (CVE-2015-0239). 2. MSR_IA32_SYSENTER_CS is checked in 64-bit mode incorrectly (bits 0 and 1 can still be set without causing #GP). 3. MSR_IA32_SYSENTER_EIP and MSR_IA32_SYSENTER_ESP are not masked in legacy-mode. 4. There is some unneeded code. Fix it. Cc: stable@vger.linux.org Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 817c6ca..de12c1d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2348,7 +2348,7 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt) * Not recognized on AMD in compat mode (but is recognized in legacy * mode). */ - if ((ctxt->mode == X86EMUL_MODE_PROT32) && (efer & EFER_LMA) + if ((ctxt->mode != X86EMUL_MODE_PROT64) && (efer & EFER_LMA) && !vendor_intel(ctxt)) return emulate_ud(ctxt); @@ -2359,25 +2359,13 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt) setup_syscalls_segments(ctxt, &cs, &ss); ops->get_msr(ctxt, MSR_IA32_SYSENTER_CS, &msr_data); - switch (ctxt->mode) { - case X86EMUL_MODE_PROT32: - if ((msr_data & 0xfffc) == 0x0) - return emulate_gp(ctxt, 0); - break; - case X86EMUL_MODE_PROT64: - if (msr_data == 0x0) - return emulate_gp(ctxt, 0); - break; - default: - break; - } + if ((msr_data & 0xfffc) == 0x0) + return emulate_gp(ctxt, 0); ctxt->eflags &= ~(EFLG_VM | EFLG_IF); - cs_sel = (u16)msr_data; - cs_sel &= ~SELECTOR_RPL_MASK; + cs_sel = (u16)msr_data & ~SELECTOR_RPL_MASK; ss_sel = cs_sel + 8; - ss_sel &= ~SELECTOR_RPL_MASK; - if (ctxt->mode == X86EMUL_MODE_PROT64 || (efer & EFER_LMA)) { + if (efer & EFER_LMA) { cs.d = 0; cs.l = 1; } @@ -2386,10 +2374,11 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt) ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS); ops->get_msr(ctxt, MSR_IA32_SYSENTER_EIP, &msr_data); - ctxt->_eip = msr_data; + ctxt->_eip = (efer & EFER_LMA) ? msr_data : (u32)msr_data; ops->get_msr(ctxt, MSR_IA32_SYSENTER_ESP, &msr_data); - *reg_write(ctxt, VCPU_REGS_RSP) = msr_data; + *reg_write(ctxt, VCPU_REGS_RSP) = (efer & EFER_LMA) ? msr_data : + (u32)msr_data; return X86EMUL_CONTINUE; } -- cgit v0.10.2 From 6b1271de3723a7957c7cc6a7f36ea114f557e730 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Fri, 19 Dec 2014 14:34:34 +0200 Subject: of/unittest: Overlays with sub-devices tests Introduce selftests for overlays using sub-devices present in children nodes. Signed-off-by: Pantelis Antoniou Signed-off-by: Grant Likely diff --git a/drivers/of/unittest-data/tests-overlay.dtsi b/drivers/of/unittest-data/tests-overlay.dtsi index 75976da..a2b687d 100644 --- a/drivers/of/unittest-data/tests-overlay.dtsi +++ b/drivers/of/unittest-data/tests-overlay.dtsi @@ -176,5 +176,60 @@ }; }; + overlay10 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus"; + __overlay__ { + + /* suppress DTC warning */ + #address-cells = <1>; + #size-cells = <0>; + + test-selftest10 { + compatible = "selftest"; + status = "okay"; + reg = <10>; + + #address-cells = <1>; + #size-cells = <0>; + + test-selftest101 { + compatible = "selftest"; + status = "okay"; + reg = <1>; + }; + + }; + }; + }; + }; + + overlay11 { + fragment@0 { + target-path = "/testcase-data/overlay-node/test-bus"; + __overlay__ { + + /* suppress DTC warning */ + #address-cells = <1>; + #size-cells = <0>; + + test-selftest11 { + compatible = "selftest"; + status = "okay"; + reg = <11>; + + #address-cells = <1>; + #size-cells = <0>; + + test-selftest111 { + compatible = "selftest"; + status = "okay"; + reg = <1>; + }; + + }; + }; + }; + }; }; }; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 844838e..41a4a13 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -978,6 +978,9 @@ static int selftest_probe(struct platform_device *pdev) } dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + + of_platform_populate(np, NULL, NULL, &pdev->dev); + return 0; } @@ -1385,6 +1388,39 @@ static void of_selftest_overlay_8(void) selftest(1, "overlay test %d passed\n", 8); } +/* test insertion of a bus with parent devices */ +static void of_selftest_overlay_10(void) +{ + int ret; + char *child_path; + + /* device should disable */ + ret = of_selftest_apply_overlay_check(10, 10, 0, 1); + if (selftest(ret == 0, "overlay test %d failed; overlay application\n", 10)) + return; + + child_path = kasprintf(GFP_KERNEL, "%s/test-selftest101", + selftest_path(10)); + if (selftest(child_path, "overlay test %d failed; kasprintf\n", 10)) + return; + + ret = of_path_platform_device_exists(child_path); + kfree(child_path); + if (selftest(ret, "overlay test %d failed; no child device\n", 10)) + return; +} + +/* test insertion of a bus with parent devices (and revert) */ +static void of_selftest_overlay_11(void) +{ + int ret; + + /* device should disable */ + ret = of_selftest_apply_revert_overlay_check(11, 11, 0, 1); + if (selftest(ret == 0, "overlay test %d failed; overlay application\n", 11)) + return; +} + static void __init of_selftest_overlay(void) { struct device_node *bus_np = NULL; @@ -1433,6 +1469,9 @@ static void __init of_selftest_overlay(void) of_selftest_overlay_6(); of_selftest_overlay_8(); + of_selftest_overlay_10(); + of_selftest_overlay_11(); + out: of_node_put(bus_np); } -- cgit v0.10.2 From 9b1cc9f251affdd27f29fe46d0989ba76c33faf6 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 23 Jan 2015 10:00:07 +0000 Subject: dm cache: share cache-metadata object across inactive and active DM tables If a DM table is reloaded with an inactive table when the device is not suspended (normal procedure for LVM2), then there will be two dm-bufio objects that can diverge. This can lead to a situation where the inactive table uses bufio to read metadata at the same time the active table writes metadata -- resulting in the inactive table having stale metadata buffers once it is promoted to the active table slot. Fix this by using reference counting and a global list of cache metadata objects to ensure there is only one metadata object per metadata device. Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer Cc: stable@vger.kernel.org diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index 9fc616c..21b1562 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c @@ -94,6 +94,9 @@ struct cache_disk_superblock { } __packed; struct dm_cache_metadata { + atomic_t ref_count; + struct list_head list; + struct block_device *bdev; struct dm_block_manager *bm; struct dm_space_map *metadata_sm; @@ -669,10 +672,10 @@ static void unpack_value(__le64 value_le, dm_oblock_t *block, unsigned *flags) /*----------------------------------------------------------------*/ -struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, - sector_t data_block_size, - bool may_format_device, - size_t policy_hint_size) +static struct dm_cache_metadata *metadata_open(struct block_device *bdev, + sector_t data_block_size, + bool may_format_device, + size_t policy_hint_size) { int r; struct dm_cache_metadata *cmd; @@ -683,6 +686,7 @@ struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, return NULL; } + atomic_set(&cmd->ref_count, 1); init_rwsem(&cmd->root_lock); cmd->bdev = bdev; cmd->data_block_size = data_block_size; @@ -705,10 +709,95 @@ struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, return cmd; } +/* + * We keep a little list of ref counted metadata objects to prevent two + * different target instances creating separate bufio instances. This is + * an issue if a table is reloaded before the suspend. + */ +static DEFINE_MUTEX(table_lock); +static LIST_HEAD(table); + +static struct dm_cache_metadata *lookup(struct block_device *bdev) +{ + struct dm_cache_metadata *cmd; + + list_for_each_entry(cmd, &table, list) + if (cmd->bdev == bdev) { + atomic_inc(&cmd->ref_count); + return cmd; + } + + return NULL; +} + +static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev, + sector_t data_block_size, + bool may_format_device, + size_t policy_hint_size) +{ + struct dm_cache_metadata *cmd, *cmd2; + + mutex_lock(&table_lock); + cmd = lookup(bdev); + mutex_unlock(&table_lock); + + if (cmd) + return cmd; + + cmd = metadata_open(bdev, data_block_size, may_format_device, policy_hint_size); + if (cmd) { + mutex_lock(&table_lock); + cmd2 = lookup(bdev); + if (cmd2) { + mutex_unlock(&table_lock); + __destroy_persistent_data_objects(cmd); + kfree(cmd); + return cmd2; + } + list_add(&cmd->list, &table); + mutex_unlock(&table_lock); + } + + return cmd; +} + +static bool same_params(struct dm_cache_metadata *cmd, sector_t data_block_size) +{ + if (cmd->data_block_size != data_block_size) { + DMERR("data_block_size (%llu) different from that in metadata (%llu)\n", + (unsigned long long) data_block_size, + (unsigned long long) cmd->data_block_size); + return false; + } + + return true; +} + +struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, + sector_t data_block_size, + bool may_format_device, + size_t policy_hint_size) +{ + struct dm_cache_metadata *cmd = lookup_or_open(bdev, data_block_size, + may_format_device, policy_hint_size); + if (cmd && !same_params(cmd, data_block_size)) { + dm_cache_metadata_close(cmd); + return NULL; + } + + return cmd; +} + void dm_cache_metadata_close(struct dm_cache_metadata *cmd) { - __destroy_persistent_data_objects(cmd); - kfree(cmd); + if (atomic_dec_and_test(&cmd->ref_count)) { + mutex_lock(&table_lock); + list_del(&cmd->list); + mutex_unlock(&table_lock); + + __destroy_persistent_data_objects(cmd); + kfree(cmd); + } } /* -- cgit v0.10.2 From a59db67656021fa212e9b95a583f13c34eb67cd9 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 23 Jan 2015 10:16:16 +0000 Subject: dm cache: fix problematic dual use of a single migration count variable Introduce a new variable to count the number of allocated migration structures. The existing variable cache->nr_migrations became overloaded. It was used to: i) track of the number of migrations in flight for the purposes of quiescing during suspend. ii) to estimate the amount of background IO occuring. Recent discard changes meant that REQ_DISCARD bios are processed with a migration. Discards are not background IO so nr_migrations was not incremented. However this could cause quiescing to complete early. (i) is now handled with a new variable cache->nr_allocated_migrations. cache->nr_migrations has been renamed cache->nr_io_migrations. cleanup_migration() is now called free_io_migration(), since it decrements that variable. Also, remove the unused cache->next_migration variable that got replaced with with prealloc_structs a while ago. Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer Cc: stable@vger.kernel.org diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 1e96d78..e165053 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -221,7 +221,13 @@ struct cache { struct list_head need_commit_migrations; sector_t migration_threshold; wait_queue_head_t migration_wait; - atomic_t nr_migrations; + atomic_t nr_allocated_migrations; + + /* + * The number of in flight migrations that are performing + * background io. eg, promotion, writeback. + */ + atomic_t nr_io_migrations; wait_queue_head_t quiescing_wait; atomic_t quiescing; @@ -258,7 +264,6 @@ struct cache { struct dm_deferred_set *all_io_ds; mempool_t *migration_pool; - struct dm_cache_migration *next_migration; struct dm_cache_policy *policy; unsigned policy_nr_args; @@ -350,10 +355,31 @@ static void free_prison_cell(struct cache *cache, struct dm_bio_prison_cell *cel dm_bio_prison_free_cell(cache->prison, cell); } +static struct dm_cache_migration *alloc_migration(struct cache *cache) +{ + struct dm_cache_migration *mg; + + mg = mempool_alloc(cache->migration_pool, GFP_NOWAIT); + if (mg) { + mg->cache = cache; + atomic_inc(&mg->cache->nr_allocated_migrations); + } + + return mg; +} + +static void free_migration(struct dm_cache_migration *mg) +{ + if (atomic_dec_and_test(&mg->cache->nr_allocated_migrations)) + wake_up(&mg->cache->migration_wait); + + mempool_free(mg, mg->cache->migration_pool); +} + static int prealloc_data_structs(struct cache *cache, struct prealloc *p) { if (!p->mg) { - p->mg = mempool_alloc(cache->migration_pool, GFP_NOWAIT); + p->mg = alloc_migration(cache); if (!p->mg) return -ENOMEM; } @@ -382,7 +408,7 @@ static void prealloc_free_structs(struct cache *cache, struct prealloc *p) free_prison_cell(cache, p->cell1); if (p->mg) - mempool_free(p->mg, cache->migration_pool); + free_migration(p->mg); } static struct dm_cache_migration *prealloc_get_migration(struct prealloc *p) @@ -854,24 +880,14 @@ static void remap_to_origin_then_cache(struct cache *cache, struct bio *bio, * Migration covers moving data from the origin device to the cache, or * vice versa. *--------------------------------------------------------------*/ -static void free_migration(struct dm_cache_migration *mg) -{ - mempool_free(mg, mg->cache->migration_pool); -} - -static void inc_nr_migrations(struct cache *cache) +static void inc_io_migrations(struct cache *cache) { - atomic_inc(&cache->nr_migrations); + atomic_inc(&cache->nr_io_migrations); } -static void dec_nr_migrations(struct cache *cache) +static void dec_io_migrations(struct cache *cache) { - atomic_dec(&cache->nr_migrations); - - /* - * Wake the worker in case we're suspending the target. - */ - wake_up(&cache->migration_wait); + atomic_dec(&cache->nr_io_migrations); } static void __cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell, @@ -894,11 +910,10 @@ static void cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell, wake_worker(cache); } -static void cleanup_migration(struct dm_cache_migration *mg) +static void free_io_migration(struct dm_cache_migration *mg) { - struct cache *cache = mg->cache; + dec_io_migrations(mg->cache); free_migration(mg); - dec_nr_migrations(cache); } static void migration_failure(struct dm_cache_migration *mg) @@ -923,7 +938,7 @@ static void migration_failure(struct dm_cache_migration *mg) cell_defer(cache, mg->new_ocell, true); } - cleanup_migration(mg); + free_io_migration(mg); } static void migration_success_pre_commit(struct dm_cache_migration *mg) @@ -934,7 +949,7 @@ static void migration_success_pre_commit(struct dm_cache_migration *mg) if (mg->writeback) { clear_dirty(cache, mg->old_oblock, mg->cblock); cell_defer(cache, mg->old_ocell, false); - cleanup_migration(mg); + free_io_migration(mg); return; } else if (mg->demote) { @@ -944,14 +959,14 @@ static void migration_success_pre_commit(struct dm_cache_migration *mg) mg->old_oblock); if (mg->promote) cell_defer(cache, mg->new_ocell, true); - cleanup_migration(mg); + free_io_migration(mg); return; } } else { if (dm_cache_insert_mapping(cache->cmd, mg->cblock, mg->new_oblock)) { DMWARN_LIMIT("promotion failed; couldn't update on disk metadata"); policy_remove_mapping(cache->policy, mg->new_oblock); - cleanup_migration(mg); + free_io_migration(mg); return; } } @@ -984,7 +999,7 @@ static void migration_success_post_commit(struct dm_cache_migration *mg) } else { if (mg->invalidate) policy_remove_mapping(cache->policy, mg->old_oblock); - cleanup_migration(mg); + free_io_migration(mg); } } else { @@ -999,7 +1014,7 @@ static void migration_success_post_commit(struct dm_cache_migration *mg) bio_endio(mg->new_ocell->holder, 0); cell_defer(cache, mg->new_ocell, false); } - cleanup_migration(mg); + free_io_migration(mg); } } @@ -1251,7 +1266,7 @@ static void promote(struct cache *cache, struct prealloc *structs, mg->new_ocell = cell; mg->start_jiffies = jiffies; - inc_nr_migrations(cache); + inc_io_migrations(cache); quiesce_migration(mg); } @@ -1275,7 +1290,7 @@ static void writeback(struct cache *cache, struct prealloc *structs, mg->new_ocell = NULL; mg->start_jiffies = jiffies; - inc_nr_migrations(cache); + inc_io_migrations(cache); quiesce_migration(mg); } @@ -1302,7 +1317,7 @@ static void demote_then_promote(struct cache *cache, struct prealloc *structs, mg->new_ocell = new_ocell; mg->start_jiffies = jiffies; - inc_nr_migrations(cache); + inc_io_migrations(cache); quiesce_migration(mg); } @@ -1330,7 +1345,7 @@ static void invalidate(struct cache *cache, struct prealloc *structs, mg->new_ocell = NULL; mg->start_jiffies = jiffies; - inc_nr_migrations(cache); + inc_io_migrations(cache); quiesce_migration(mg); } @@ -1412,7 +1427,7 @@ static void process_discard_bio(struct cache *cache, struct prealloc *structs, static bool spare_migration_bandwidth(struct cache *cache) { - sector_t current_volume = (atomic_read(&cache->nr_migrations) + 1) * + sector_t current_volume = (atomic_read(&cache->nr_io_migrations) + 1) * cache->sectors_per_block; return current_volume < cache->migration_threshold; } @@ -1764,7 +1779,7 @@ static void stop_quiescing(struct cache *cache) static void wait_for_migrations(struct cache *cache) { - wait_event(cache->migration_wait, !atomic_read(&cache->nr_migrations)); + wait_event(cache->migration_wait, !atomic_read(&cache->nr_allocated_migrations)); } static void stop_worker(struct cache *cache) @@ -1876,9 +1891,6 @@ static void destroy(struct cache *cache) { unsigned i; - if (cache->next_migration) - mempool_free(cache->next_migration, cache->migration_pool); - if (cache->migration_pool) mempool_destroy(cache->migration_pool); @@ -2424,7 +2436,8 @@ static int cache_create(struct cache_args *ca, struct cache **result) INIT_LIST_HEAD(&cache->quiesced_migrations); INIT_LIST_HEAD(&cache->completed_migrations); INIT_LIST_HEAD(&cache->need_commit_migrations); - atomic_set(&cache->nr_migrations, 0); + atomic_set(&cache->nr_allocated_migrations, 0); + atomic_set(&cache->nr_io_migrations, 0); init_waitqueue_head(&cache->migration_wait); init_waitqueue_head(&cache->quiescing_wait); @@ -2487,8 +2500,6 @@ static int cache_create(struct cache_args *ca, struct cache **result) goto bad; } - cache->next_migration = NULL; - cache->need_tick_bio = true; cache->sized = false; cache->invalidate = false; -- cgit v0.10.2 From dc58376921f153a071e24a6b63684df83905e5f9 Mon Sep 17 00:00:00 2001 From: Darren Hart Date: Wed, 21 Jan 2015 10:34:43 -0800 Subject: Revert "Documentation: Add entry for dell-laptop sysfs interface" This reverts commit 3161293ba6dfceee9c1efe75185677445def05d4. This interface was determined to be flawed and required too invasive a fix for the RC cycle. This will be revisited in 3.20. Signed-off-by: Darren Hart diff --git a/Documentation/ABI/testing/sysfs-platform-dell-laptop b/Documentation/ABI/testing/sysfs-platform-dell-laptop deleted file mode 100644 index 7969443..0000000 --- a/Documentation/ABI/testing/sysfs-platform-dell-laptop +++ /dev/null @@ -1,60 +0,0 @@ -What: /sys/class/leds/dell::kbd_backlight/als_setting -Date: December 2014 -KernelVersion: 3.19 -Contact: Gabriele Mazzotta , - Pali Rohár -Description: - This file allows to control the automatic keyboard - illumination mode on some systems that have an ambient - light sensor. Write 1 to this file to enable the auto - mode, 0 to disable it. - -What: /sys/class/leds/dell::kbd_backlight/start_triggers -Date: December 2014 -KernelVersion: 3.19 -Contact: Gabriele Mazzotta , - Pali Rohár -Description: - This file allows to control the input triggers that - turn on the keyboard backlight illumination that is - disabled because of inactivity. - Read the file to see the triggers available. The ones - enabled are preceded by '+', those disabled by '-'. - - To enable a trigger, write its name preceded by '+' to - this file. To disable a trigger, write its name preceded - by '-' instead. - - For example, to enable the keyboard as trigger run: - echo +keyboard > /sys/class/leds/dell::kbd_backlight/start_triggers - To disable it: - echo -keyboard > /sys/class/leds/dell::kbd_backlight/start_triggers - - Note that not all the available triggers can be configured. - -What: /sys/class/leds/dell::kbd_backlight/stop_timeout -Date: December 2014 -KernelVersion: 3.19 -Contact: Gabriele Mazzotta , - Pali Rohár -Description: - This file allows to specify the interval after which the - keyboard illumination is disabled because of inactivity. - The timeouts are expressed in seconds, minutes, hours and - days, for which the symbols are 's', 'm', 'h' and 'd' - respectively. - - To configure the timeout, write to this file a value along - with any the above units. If no unit is specified, the value - is assumed to be expressed in seconds. - - For example, to set the timeout to 10 minutes run: - echo 10m > /sys/class/leds/dell::kbd_backlight/stop_timeout - - Note that when this file is read, the returned value might be - expressed in a different unit than the one used when the timeout - was set. - - Also note that only some timeouts are supported and that - some systems might fall back to a specific timeout in case - an invalid timeout is written to this file. -- cgit v0.10.2 From b78695a71de994cdbd58f4b3be9085a60bd2203d Mon Sep 17 00:00:00 2001 From: Darren Hart Date: Wed, 21 Jan 2015 10:36:11 -0800 Subject: Revert "platform: x86: dell-laptop: Add support for keyboard backlight" This reverts commit 02b2aaaa57ab41504e8d03a3b2ceeb9440a2c188. This interface was determined to be flawed and required too invasive a fix for the RC cycle. This will be revisited in 3.20. Signed-off-by: Darren Hart diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 9411eae..3d21efe 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -2,11 +2,9 @@ * Driver for Dell laptop extras * * Copyright (c) Red Hat - * Copyright (c) 2014 Gabriele Mazzotta - * Copyright (c) 2014 Pali Rohár * - * Based on documentation in the libsmbios package: - * Copyright (C) 2005-2014 Dell Inc. + * Based on documentation in the libsmbios package, Copyright (C) 2005 Dell + * Inc. * * 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 @@ -34,13 +32,6 @@ #include "../../firmware/dcdbas.h" #define BRIGHTNESS_TOKEN 0x7d -#define KBD_LED_OFF_TOKEN 0x01E1 -#define KBD_LED_ON_TOKEN 0x01E2 -#define KBD_LED_AUTO_TOKEN 0x01E3 -#define KBD_LED_AUTO_25_TOKEN 0x02EA -#define KBD_LED_AUTO_50_TOKEN 0x02EB -#define KBD_LED_AUTO_75_TOKEN 0x02EC -#define KBD_LED_AUTO_100_TOKEN 0x02F6 /* This structure will be modified by the firmware when we enter * system management mode, hence the volatiles */ @@ -71,13 +62,6 @@ struct calling_interface_structure { struct quirk_entry { u8 touchpad_led; - - int needs_kbd_timeouts; - /* - * Ordered list of timeouts expressed in seconds. - * The list must end with -1 - */ - int kbd_timeouts[]; }; static struct quirk_entry *quirks; @@ -92,15 +76,6 @@ static int __init dmi_matched(const struct dmi_system_id *dmi) return 1; } -/* - * These values come from Windows utility provided by Dell. If any other value - * is used then BIOS silently set timeout to 0 without any error message. - */ -static struct quirk_entry quirk_dell_xps13_9333 = { - .needs_kbd_timeouts = 1, - .kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 }, -}; - static int da_command_address; static int da_command_code; static int da_num_tokens; @@ -292,15 +267,6 @@ static const struct dmi_system_id dell_quirks[] __initconst = { }, .driver_data = &quirk_dell_vostro_v130, }, - { - .callback = dmi_matched, - .ident = "Dell XPS13 9333", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "XPS13 9333"), - }, - .driver_data = &quirk_dell_xps13_9333, - }, { } }; @@ -365,29 +331,17 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy) } } -static int find_token_id(int tokenid) +static int find_token_location(int tokenid) { int i; - for (i = 0; i < da_num_tokens; i++) { if (da_tokens[i].tokenID == tokenid) - return i; + return da_tokens[i].location; } return -1; } -static int find_token_location(int tokenid) -{ - int id; - - id = find_token_id(tokenid); - if (id == -1) - return -1; - - return da_tokens[id].location; -} - static struct calling_interface_buffer * dell_send_request(struct calling_interface_buffer *buffer, int class, int select) @@ -408,20 +362,6 @@ dell_send_request(struct calling_interface_buffer *buffer, int class, return buffer; } -static inline int dell_smi_error(int value) -{ - switch (value) { - case 0: /* Completed successfully */ - return 0; - case -1: /* Completed with error */ - return -EIO; - case -2: /* Function not supported */ - return -ENXIO; - default: /* Unknown error */ - return -EINVAL; - } -} - /* Derived from information in DellWirelessCtl.cpp: Class 17, select 11 is radio control. It returns an array of 32-bit values. @@ -776,7 +716,7 @@ static int dell_send_intensity(struct backlight_device *bd) else dell_send_request(buffer, 1, 1); - out: +out: release_buffer(); return ret; } @@ -800,7 +740,7 @@ static int dell_get_intensity(struct backlight_device *bd) ret = buffer->output[1]; - out: +out: release_buffer(); return ret; } @@ -849,984 +789,6 @@ static void touchpad_led_exit(void) led_classdev_unregister(&touchpad_led); } -/* - * Derived from information in smbios-keyboard-ctl: - * - * cbClass 4 - * cbSelect 11 - * Keyboard illumination - * cbArg1 determines the function to be performed - * - * cbArg1 0x0 = Get Feature Information - * cbRES1 Standard return codes (0, -1, -2) - * cbRES2, word0 Bitmap of user-selectable modes - * bit 0 Always off (All systems) - * bit 1 Always on (Travis ATG, Siberia) - * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG) - * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off - * bit 4 Auto: Input-activity-based On; input-activity based Off - * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off - * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off - * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off - * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off - * bits 9-15 Reserved for future use - * cbRES2, byte2 Reserved for future use - * cbRES2, byte3 Keyboard illumination type - * 0 Reserved - * 1 Tasklight - * 2 Backlight - * 3-255 Reserved for future use - * cbRES3, byte0 Supported auto keyboard illumination trigger bitmap. - * bit 0 Any keystroke - * bit 1 Touchpad activity - * bit 2 Pointing stick - * bit 3 Any mouse - * bits 4-7 Reserved for future use - * cbRES3, byte1 Supported timeout unit bitmap - * bit 0 Seconds - * bit 1 Minutes - * bit 2 Hours - * bit 3 Days - * bits 4-7 Reserved for future use - * cbRES3, byte2 Number of keyboard light brightness levels - * cbRES4, byte0 Maximum acceptable seconds value (0 if seconds not supported). - * cbRES4, byte1 Maximum acceptable minutes value (0 if minutes not supported). - * cbRES4, byte2 Maximum acceptable hours value (0 if hours not supported). - * cbRES4, byte3 Maximum acceptable days value (0 if days not supported) - * - * cbArg1 0x1 = Get Current State - * cbRES1 Standard return codes (0, -1, -2) - * cbRES2, word0 Bitmap of current mode state - * bit 0 Always off (All systems) - * bit 1 Always on (Travis ATG, Siberia) - * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG) - * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off - * bit 4 Auto: Input-activity-based On; input-activity based Off - * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off - * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off - * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off - * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off - * bits 9-15 Reserved for future use - * Note: Only One bit can be set - * cbRES2, byte2 Currently active auto keyboard illumination triggers. - * bit 0 Any keystroke - * bit 1 Touchpad activity - * bit 2 Pointing stick - * bit 3 Any mouse - * bits 4-7 Reserved for future use - * cbRES2, byte3 Current Timeout - * bits 7:6 Timeout units indicator: - * 00b Seconds - * 01b Minutes - * 10b Hours - * 11b Days - * bits 5:0 Timeout value (0-63) in sec/min/hr/day - * NOTE: A value of 0 means always on (no timeout) if any bits of RES3 byte - * are set upon return from the [Get feature information] call. - * cbRES3, byte0 Current setting of ALS value that turns the light on or off. - * cbRES3, byte1 Current ALS reading - * cbRES3, byte2 Current keyboard light level. - * - * cbArg1 0x2 = Set New State - * cbRES1 Standard return codes (0, -1, -2) - * cbArg2, word0 Bitmap of current mode state - * bit 0 Always off (All systems) - * bit 1 Always on (Travis ATG, Siberia) - * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG) - * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off - * bit 4 Auto: Input-activity-based On; input-activity based Off - * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off - * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off - * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off - * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off - * bits 9-15 Reserved for future use - * Note: Only One bit can be set - * cbArg2, byte2 Desired auto keyboard illumination triggers. Must remain inactive to allow - * keyboard to turn off automatically. - * bit 0 Any keystroke - * bit 1 Touchpad activity - * bit 2 Pointing stick - * bit 3 Any mouse - * bits 4-7 Reserved for future use - * cbArg2, byte3 Desired Timeout - * bits 7:6 Timeout units indicator: - * 00b Seconds - * 01b Minutes - * 10b Hours - * 11b Days - * bits 5:0 Timeout value (0-63) in sec/min/hr/day - * cbArg3, byte0 Desired setting of ALS value that turns the light on or off. - * cbArg3, byte2 Desired keyboard light level. - */ - - -enum kbd_timeout_unit { - KBD_TIMEOUT_SECONDS = 0, - KBD_TIMEOUT_MINUTES, - KBD_TIMEOUT_HOURS, - KBD_TIMEOUT_DAYS, -}; - -enum kbd_mode_bit { - KBD_MODE_BIT_OFF = 0, - KBD_MODE_BIT_ON, - KBD_MODE_BIT_ALS, - KBD_MODE_BIT_TRIGGER_ALS, - KBD_MODE_BIT_TRIGGER, - KBD_MODE_BIT_TRIGGER_25, - KBD_MODE_BIT_TRIGGER_50, - KBD_MODE_BIT_TRIGGER_75, - KBD_MODE_BIT_TRIGGER_100, -}; - -#define kbd_is_als_mode_bit(bit) \ - ((bit) == KBD_MODE_BIT_ALS || (bit) == KBD_MODE_BIT_TRIGGER_ALS) -#define kbd_is_trigger_mode_bit(bit) \ - ((bit) >= KBD_MODE_BIT_TRIGGER_ALS && (bit) <= KBD_MODE_BIT_TRIGGER_100) -#define kbd_is_level_mode_bit(bit) \ - ((bit) >= KBD_MODE_BIT_TRIGGER_25 && (bit) <= KBD_MODE_BIT_TRIGGER_100) - -struct kbd_info { - u16 modes; - u8 type; - u8 triggers; - u8 levels; - u8 seconds; - u8 minutes; - u8 hours; - u8 days; -}; - -struct kbd_state { - u8 mode_bit; - u8 triggers; - u8 timeout_value; - u8 timeout_unit; - u8 als_setting; - u8 als_value; - u8 level; -}; - -static const int kbd_tokens[] = { - KBD_LED_OFF_TOKEN, - KBD_LED_AUTO_25_TOKEN, - KBD_LED_AUTO_50_TOKEN, - KBD_LED_AUTO_75_TOKEN, - KBD_LED_AUTO_100_TOKEN, - KBD_LED_ON_TOKEN, -}; - -static u16 kbd_token_bits; - -static struct kbd_info kbd_info; -static bool kbd_als_supported; -static bool kbd_triggers_supported; - -static u8 kbd_mode_levels[16]; -static int kbd_mode_levels_count; - -static u8 kbd_previous_level; -static u8 kbd_previous_mode_bit; - -static bool kbd_led_present; - -/* - * NOTE: there are three ways to set the keyboard backlight level. - * First, via kbd_state.mode_bit (assigning KBD_MODE_BIT_TRIGGER_* value). - * Second, via kbd_state.level (assigning numerical value <= kbd_info.levels). - * Third, via SMBIOS tokens (KBD_LED_* in kbd_tokens) - * - * There are laptops which support only one of these methods. If we want to - * support as many machines as possible we need to implement all three methods. - * The first two methods use the kbd_state structure. The third uses SMBIOS - * tokens. If kbd_info.levels == 0, the machine does not support setting the - * keyboard backlight level via kbd_state.level. - */ - -static int kbd_get_info(struct kbd_info *info) -{ - u8 units; - int ret; - - get_buffer(); - - buffer->input[0] = 0x0; - dell_send_request(buffer, 4, 11); - ret = buffer->output[0]; - - if (ret) { - ret = dell_smi_error(ret); - goto out; - } - - info->modes = buffer->output[1] & 0xFFFF; - info->type = (buffer->output[1] >> 24) & 0xFF; - info->triggers = buffer->output[2] & 0xFF; - units = (buffer->output[2] >> 8) & 0xFF; - info->levels = (buffer->output[2] >> 16) & 0xFF; - - if (units & BIT(0)) - info->seconds = (buffer->output[3] >> 0) & 0xFF; - if (units & BIT(1)) - info->minutes = (buffer->output[3] >> 8) & 0xFF; - if (units & BIT(2)) - info->hours = (buffer->output[3] >> 16) & 0xFF; - if (units & BIT(3)) - info->days = (buffer->output[3] >> 24) & 0xFF; - - out: - release_buffer(); - return ret; -} - -static unsigned int kbd_get_max_level(void) -{ - if (kbd_info.levels != 0) - return kbd_info.levels; - if (kbd_mode_levels_count > 0) - return kbd_mode_levels_count - 1; - return 0; -} - -static int kbd_get_level(struct kbd_state *state) -{ - int i; - - if (kbd_info.levels != 0) - return state->level; - - if (kbd_mode_levels_count > 0) { - for (i = 0; i < kbd_mode_levels_count; ++i) - if (kbd_mode_levels[i] == state->mode_bit) - return i; - return 0; - } - - return -EINVAL; -} - -static int kbd_set_level(struct kbd_state *state, u8 level) -{ - if (kbd_info.levels != 0) { - if (level != 0) - kbd_previous_level = level; - if (state->level == level) - return 0; - state->level = level; - if (level != 0 && state->mode_bit == KBD_MODE_BIT_OFF) - state->mode_bit = kbd_previous_mode_bit; - else if (level == 0 && state->mode_bit != KBD_MODE_BIT_OFF) { - kbd_previous_mode_bit = state->mode_bit; - state->mode_bit = KBD_MODE_BIT_OFF; - } - return 0; - } - - if (kbd_mode_levels_count > 0 && level < kbd_mode_levels_count) { - if (level != 0) - kbd_previous_level = level; - state->mode_bit = kbd_mode_levels[level]; - return 0; - } - - return -EINVAL; -} - -static int kbd_get_state(struct kbd_state *state) -{ - int ret; - - get_buffer(); - - buffer->input[0] = 0x1; - dell_send_request(buffer, 4, 11); - ret = buffer->output[0]; - - if (ret) { - ret = dell_smi_error(ret); - goto out; - } - - state->mode_bit = ffs(buffer->output[1] & 0xFFFF); - if (state->mode_bit != 0) - state->mode_bit--; - - state->triggers = (buffer->output[1] >> 16) & 0xFF; - state->timeout_value = (buffer->output[1] >> 24) & 0x3F; - state->timeout_unit = (buffer->output[1] >> 30) & 0x3; - state->als_setting = buffer->output[2] & 0xFF; - state->als_value = (buffer->output[2] >> 8) & 0xFF; - state->level = (buffer->output[2] >> 16) & 0xFF; - - out: - release_buffer(); - return ret; -} - -static int kbd_set_state(struct kbd_state *state) -{ - int ret; - - get_buffer(); - buffer->input[0] = 0x2; - buffer->input[1] = BIT(state->mode_bit) & 0xFFFF; - buffer->input[1] |= (state->triggers & 0xFF) << 16; - buffer->input[1] |= (state->timeout_value & 0x3F) << 24; - buffer->input[1] |= (state->timeout_unit & 0x3) << 30; - buffer->input[2] = state->als_setting & 0xFF; - buffer->input[2] |= (state->level & 0xFF) << 16; - dell_send_request(buffer, 4, 11); - ret = buffer->output[0]; - release_buffer(); - - return dell_smi_error(ret); -} - -static int kbd_set_state_safe(struct kbd_state *state, struct kbd_state *old) -{ - int ret; - - ret = kbd_set_state(state); - if (ret == 0) - return 0; - - /* - * When setting the new state fails,try to restore the previous one. - * This is needed on some machines where BIOS sets a default state when - * setting a new state fails. This default state could be all off. - */ - - if (kbd_set_state(old)) - pr_err("Setting old previous keyboard state failed\n"); - - return ret; -} - -static int kbd_set_token_bit(u8 bit) -{ - int id; - int ret; - - if (bit >= ARRAY_SIZE(kbd_tokens)) - return -EINVAL; - - id = find_token_id(kbd_tokens[bit]); - if (id == -1) - return -EINVAL; - - get_buffer(); - buffer->input[0] = da_tokens[id].location; - buffer->input[1] = da_tokens[id].value; - dell_send_request(buffer, 1, 0); - ret = buffer->output[0]; - release_buffer(); - - return dell_smi_error(ret); -} - -static int kbd_get_token_bit(u8 bit) -{ - int id; - int ret; - int val; - - if (bit >= ARRAY_SIZE(kbd_tokens)) - return -EINVAL; - - id = find_token_id(kbd_tokens[bit]); - if (id == -1) - return -EINVAL; - - get_buffer(); - buffer->input[0] = da_tokens[id].location; - dell_send_request(buffer, 0, 0); - ret = buffer->output[0]; - val = buffer->output[1]; - release_buffer(); - - if (ret) - return dell_smi_error(ret); - - return (val == da_tokens[id].value); -} - -static int kbd_get_first_active_token_bit(void) -{ - int i; - int ret; - - for (i = 0; i < ARRAY_SIZE(kbd_tokens); ++i) { - ret = kbd_get_token_bit(i); - if (ret == 1) - return i; - } - - return ret; -} - -static int kbd_get_valid_token_counts(void) -{ - return hweight16(kbd_token_bits); -} - -static inline int kbd_init_info(void) -{ - struct kbd_state state; - int ret; - int i; - - ret = kbd_get_info(&kbd_info); - if (ret) - return ret; - - kbd_get_state(&state); - - /* NOTE: timeout value is stored in 6 bits so max value is 63 */ - if (kbd_info.seconds > 63) - kbd_info.seconds = 63; - if (kbd_info.minutes > 63) - kbd_info.minutes = 63; - if (kbd_info.hours > 63) - kbd_info.hours = 63; - if (kbd_info.days > 63) - kbd_info.days = 63; - - /* NOTE: On tested machines ON mode did not work and caused - * problems (turned backlight off) so do not use it - */ - kbd_info.modes &= ~BIT(KBD_MODE_BIT_ON); - - kbd_previous_level = kbd_get_level(&state); - kbd_previous_mode_bit = state.mode_bit; - - if (kbd_previous_level == 0 && kbd_get_max_level() != 0) - kbd_previous_level = 1; - - if (kbd_previous_mode_bit == KBD_MODE_BIT_OFF) { - kbd_previous_mode_bit = - ffs(kbd_info.modes & ~BIT(KBD_MODE_BIT_OFF)); - if (kbd_previous_mode_bit != 0) - kbd_previous_mode_bit--; - } - - if (kbd_info.modes & (BIT(KBD_MODE_BIT_ALS) | - BIT(KBD_MODE_BIT_TRIGGER_ALS))) - kbd_als_supported = true; - - if (kbd_info.modes & ( - BIT(KBD_MODE_BIT_TRIGGER_ALS) | BIT(KBD_MODE_BIT_TRIGGER) | - BIT(KBD_MODE_BIT_TRIGGER_25) | BIT(KBD_MODE_BIT_TRIGGER_50) | - BIT(KBD_MODE_BIT_TRIGGER_75) | BIT(KBD_MODE_BIT_TRIGGER_100) - )) - kbd_triggers_supported = true; - - /* kbd_mode_levels[0] is reserved, see below */ - for (i = 0; i < 16; ++i) - if (kbd_is_level_mode_bit(i) && (BIT(i) & kbd_info.modes)) - kbd_mode_levels[1 + kbd_mode_levels_count++] = i; - - /* - * Find the first supported mode and assign to kbd_mode_levels[0]. - * This should be 0 (off), but we cannot depend on the BIOS to - * support 0. - */ - if (kbd_mode_levels_count > 0) { - for (i = 0; i < 16; ++i) { - if (BIT(i) & kbd_info.modes) { - kbd_mode_levels[0] = i; - break; - } - } - kbd_mode_levels_count++; - } - - return 0; - -} - -static inline void kbd_init_tokens(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(kbd_tokens); ++i) - if (find_token_id(kbd_tokens[i]) != -1) - kbd_token_bits |= BIT(i); -} - -static void kbd_init(void) -{ - int ret; - - ret = kbd_init_info(); - kbd_init_tokens(); - - if (kbd_token_bits != 0 || ret == 0) - kbd_led_present = true; -} - -static ssize_t kbd_led_timeout_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct kbd_state new_state; - struct kbd_state state; - bool convert; - int value; - int ret; - char ch; - u8 unit; - int i; - - ret = sscanf(buf, "%d %c", &value, &ch); - if (ret < 1) - return -EINVAL; - else if (ret == 1) - ch = 's'; - - if (value < 0) - return -EINVAL; - - convert = false; - - switch (ch) { - case 's': - if (value > kbd_info.seconds) - convert = true; - unit = KBD_TIMEOUT_SECONDS; - break; - case 'm': - if (value > kbd_info.minutes) - convert = true; - unit = KBD_TIMEOUT_MINUTES; - break; - case 'h': - if (value > kbd_info.hours) - convert = true; - unit = KBD_TIMEOUT_HOURS; - break; - case 'd': - if (value > kbd_info.days) - convert = true; - unit = KBD_TIMEOUT_DAYS; - break; - default: - return -EINVAL; - } - - if (quirks && quirks->needs_kbd_timeouts) - convert = true; - - if (convert) { - /* Convert value from current units to seconds */ - switch (unit) { - case KBD_TIMEOUT_DAYS: - value *= 24; - case KBD_TIMEOUT_HOURS: - value *= 60; - case KBD_TIMEOUT_MINUTES: - value *= 60; - unit = KBD_TIMEOUT_SECONDS; - } - - if (quirks && quirks->needs_kbd_timeouts) { - for (i = 0; quirks->kbd_timeouts[i] != -1; i++) { - if (value <= quirks->kbd_timeouts[i]) { - value = quirks->kbd_timeouts[i]; - break; - } - } - } - - if (value <= kbd_info.seconds && kbd_info.seconds) { - unit = KBD_TIMEOUT_SECONDS; - } else if (value / 60 <= kbd_info.minutes && kbd_info.minutes) { - value /= 60; - unit = KBD_TIMEOUT_MINUTES; - } else if (value / (60 * 60) <= kbd_info.hours && kbd_info.hours) { - value /= (60 * 60); - unit = KBD_TIMEOUT_HOURS; - } else if (value / (60 * 60 * 24) <= kbd_info.days && kbd_info.days) { - value /= (60 * 60 * 24); - unit = KBD_TIMEOUT_DAYS; - } else { - return -EINVAL; - } - } - - ret = kbd_get_state(&state); - if (ret) - return ret; - - new_state = state; - new_state.timeout_value = value; - new_state.timeout_unit = unit; - - ret = kbd_set_state_safe(&new_state, &state); - if (ret) - return ret; - - return count; -} - -static ssize_t kbd_led_timeout_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct kbd_state state; - int ret; - int len; - - ret = kbd_get_state(&state); - if (ret) - return ret; - - len = sprintf(buf, "%d", state.timeout_value); - - switch (state.timeout_unit) { - case KBD_TIMEOUT_SECONDS: - return len + sprintf(buf+len, "s\n"); - case KBD_TIMEOUT_MINUTES: - return len + sprintf(buf+len, "m\n"); - case KBD_TIMEOUT_HOURS: - return len + sprintf(buf+len, "h\n"); - case KBD_TIMEOUT_DAYS: - return len + sprintf(buf+len, "d\n"); - default: - return -EINVAL; - } - - return len; -} - -static DEVICE_ATTR(stop_timeout, S_IRUGO | S_IWUSR, - kbd_led_timeout_show, kbd_led_timeout_store); - -static const char * const kbd_led_triggers[] = { - "keyboard", - "touchpad", - /*"trackstick"*/ NULL, /* NOTE: trackstick is just alias for touchpad */ - "mouse", -}; - -static ssize_t kbd_led_triggers_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct kbd_state new_state; - struct kbd_state state; - bool triggers_enabled = false; - bool als_enabled = false; - bool disable_als = false; - bool enable_als = false; - int trigger_bit = -1; - char trigger[21]; - int i, ret; - - ret = sscanf(buf, "%20s", trigger); - if (ret != 1) - return -EINVAL; - - if (trigger[0] != '+' && trigger[0] != '-') - return -EINVAL; - - ret = kbd_get_state(&state); - if (ret) - return ret; - - if (kbd_als_supported) - als_enabled = kbd_is_als_mode_bit(state.mode_bit); - - if (kbd_triggers_supported) - triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit); - - if (kbd_als_supported) { - if (strcmp(trigger, "+als") == 0) { - if (als_enabled) - return count; - enable_als = true; - } else if (strcmp(trigger, "-als") == 0) { - if (!als_enabled) - return count; - disable_als = true; - } - } - - if (enable_als || disable_als) { - new_state = state; - if (enable_als) { - if (triggers_enabled) - new_state.mode_bit = KBD_MODE_BIT_TRIGGER_ALS; - else - new_state.mode_bit = KBD_MODE_BIT_ALS; - } else { - if (triggers_enabled) { - new_state.mode_bit = KBD_MODE_BIT_TRIGGER; - kbd_set_level(&new_state, kbd_previous_level); - } else { - new_state.mode_bit = KBD_MODE_BIT_ON; - } - } - if (!(kbd_info.modes & BIT(new_state.mode_bit))) - return -EINVAL; - ret = kbd_set_state_safe(&new_state, &state); - if (ret) - return ret; - kbd_previous_mode_bit = new_state.mode_bit; - return count; - } - - if (kbd_triggers_supported) { - for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); ++i) { - if (!(kbd_info.triggers & BIT(i))) - continue; - if (!kbd_led_triggers[i]) - continue; - if (strcmp(trigger+1, kbd_led_triggers[i]) != 0) - continue; - if (trigger[0] == '+' && - triggers_enabled && (state.triggers & BIT(i))) - return count; - if (trigger[0] == '-' && - (!triggers_enabled || !(state.triggers & BIT(i)))) - return count; - trigger_bit = i; - break; - } - } - - if (trigger_bit != -1) { - new_state = state; - if (trigger[0] == '+') - new_state.triggers |= BIT(trigger_bit); - else { - new_state.triggers &= ~BIT(trigger_bit); - /* NOTE: trackstick bit (2) must be disabled when - * disabling touchpad bit (1), otherwise touchpad - * bit (1) will not be disabled */ - if (trigger_bit == 1) - new_state.triggers &= ~BIT(2); - } - if ((kbd_info.triggers & new_state.triggers) != - new_state.triggers) - return -EINVAL; - if (new_state.triggers && !triggers_enabled) { - if (als_enabled) - new_state.mode_bit = KBD_MODE_BIT_TRIGGER_ALS; - else { - new_state.mode_bit = KBD_MODE_BIT_TRIGGER; - kbd_set_level(&new_state, kbd_previous_level); - } - } else if (new_state.triggers == 0) { - if (als_enabled) - new_state.mode_bit = KBD_MODE_BIT_ALS; - else - kbd_set_level(&new_state, 0); - } - if (!(kbd_info.modes & BIT(new_state.mode_bit))) - return -EINVAL; - ret = kbd_set_state_safe(&new_state, &state); - if (ret) - return ret; - if (new_state.mode_bit != KBD_MODE_BIT_OFF) - kbd_previous_mode_bit = new_state.mode_bit; - return count; - } - - return -EINVAL; -} - -static ssize_t kbd_led_triggers_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct kbd_state state; - bool triggers_enabled; - int level, i, ret; - int len = 0; - - ret = kbd_get_state(&state); - if (ret) - return ret; - - len = 0; - - if (kbd_triggers_supported) { - triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit); - level = kbd_get_level(&state); - for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); ++i) { - if (!(kbd_info.triggers & BIT(i))) - continue; - if (!kbd_led_triggers[i]) - continue; - if ((triggers_enabled || level <= 0) && - (state.triggers & BIT(i))) - buf[len++] = '+'; - else - buf[len++] = '-'; - len += sprintf(buf+len, "%s ", kbd_led_triggers[i]); - } - } - - if (kbd_als_supported) { - if (kbd_is_als_mode_bit(state.mode_bit)) - len += sprintf(buf+len, "+als "); - else - len += sprintf(buf+len, "-als "); - } - - if (len) - buf[len - 1] = '\n'; - - return len; -} - -static DEVICE_ATTR(start_triggers, S_IRUGO | S_IWUSR, - kbd_led_triggers_show, kbd_led_triggers_store); - -static ssize_t kbd_led_als_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct kbd_state state; - struct kbd_state new_state; - u8 setting; - int ret; - - ret = kstrtou8(buf, 10, &setting); - if (ret) - return ret; - - ret = kbd_get_state(&state); - if (ret) - return ret; - - new_state = state; - new_state.als_setting = setting; - - ret = kbd_set_state_safe(&new_state, &state); - if (ret) - return ret; - - return count; -} - -static ssize_t kbd_led_als_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct kbd_state state; - int ret; - - ret = kbd_get_state(&state); - if (ret) - return ret; - - return sprintf(buf, "%d\n", state.als_setting); -} - -static DEVICE_ATTR(als_setting, S_IRUGO | S_IWUSR, - kbd_led_als_show, kbd_led_als_store); - -static struct attribute *kbd_led_attrs[] = { - &dev_attr_stop_timeout.attr, - &dev_attr_start_triggers.attr, - &dev_attr_als_setting.attr, - NULL, -}; -ATTRIBUTE_GROUPS(kbd_led); - -static enum led_brightness kbd_led_level_get(struct led_classdev *led_cdev) -{ - int ret; - u16 num; - struct kbd_state state; - - if (kbd_get_max_level()) { - ret = kbd_get_state(&state); - if (ret) - return 0; - ret = kbd_get_level(&state); - if (ret < 0) - return 0; - return ret; - } - - if (kbd_get_valid_token_counts()) { - ret = kbd_get_first_active_token_bit(); - if (ret < 0) - return 0; - for (num = kbd_token_bits; num != 0 && ret > 0; --ret) - num &= num - 1; /* clear the first bit set */ - if (num == 0) - return 0; - return ffs(num) - 1; - } - - pr_warn("Keyboard brightness level control not supported\n"); - return 0; -} - -static void kbd_led_level_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct kbd_state state; - struct kbd_state new_state; - u16 num; - - if (kbd_get_max_level()) { - if (kbd_get_state(&state)) - return; - new_state = state; - if (kbd_set_level(&new_state, value)) - return; - kbd_set_state_safe(&new_state, &state); - return; - } - - if (kbd_get_valid_token_counts()) { - for (num = kbd_token_bits; num != 0 && value > 0; --value) - num &= num - 1; /* clear the first bit set */ - if (num == 0) - return; - kbd_set_token_bit(ffs(num) - 1); - return; - } - - pr_warn("Keyboard brightness level control not supported\n"); -} - -static struct led_classdev kbd_led = { - .name = "dell::kbd_backlight", - .brightness_set = kbd_led_level_set, - .brightness_get = kbd_led_level_get, - .groups = kbd_led_groups, -}; - -static int __init kbd_led_init(struct device *dev) -{ - kbd_init(); - if (!kbd_led_present) - return -ENODEV; - kbd_led.max_brightness = kbd_get_max_level(); - if (!kbd_led.max_brightness) { - kbd_led.max_brightness = kbd_get_valid_token_counts(); - if (kbd_led.max_brightness) - kbd_led.max_brightness--; - } - return led_classdev_register(dev, &kbd_led); -} - -static void brightness_set_exit(struct led_classdev *led_cdev, - enum led_brightness value) -{ - /* Don't change backlight level on exit */ -}; - -static void kbd_led_exit(void) -{ - if (!kbd_led_present) - return; - kbd_led.brightness_set = brightness_set_exit; - led_classdev_unregister(&kbd_led); -} - static int __init dell_init(void) { int max_intensity = 0; @@ -1879,8 +841,6 @@ static int __init dell_init(void) if (quirks && quirks->touchpad_led) touchpad_led_init(&platform_device->dev); - kbd_led_init(&platform_device->dev); - dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); if (dell_laptop_dir != NULL) debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, @@ -1948,7 +908,6 @@ static void __exit dell_exit(void) debugfs_remove_recursive(dell_laptop_dir); if (quirks && quirks->touchpad_led) touchpad_led_exit(); - kbd_led_exit(); i8042_remove_filter(dell_laptop_i8042_filter); cancel_delayed_work_sync(&dell_rfkill_work); backlight_device_unregister(dell_backlight_device); @@ -1965,7 +924,5 @@ module_init(dell_init); module_exit(dell_exit); MODULE_AUTHOR("Matthew Garrett "); -MODULE_AUTHOR("Gabriele Mazzotta "); -MODULE_AUTHOR("Pali Rohár "); MODULE_DESCRIPTION("Dell laptop driver"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From e0b21800107edbf73385a48275c1fd5a9ecaa4db Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Thu, 22 Jan 2015 11:21:32 +0000 Subject: arm64: dts: add baud rate to Juno stdout-path Without explicit command-line parameters, the Juno UART ends up running at 57600 baud in the kernel, which is at odds with the 115200 baud used by the rest of the firmware. Since commit 7914a7c5651a5161 now lets us fix this by specifying default options in stdout-path, do so. Acked-by: Mark Rutland Signed-off-by: Robin Murphy Signed-off-by: Olof Johansson diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts index cb3073e..d429129 100644 --- a/arch/arm64/boot/dts/arm/juno.dts +++ b/arch/arm64/boot/dts/arm/juno.dts @@ -22,7 +22,7 @@ }; chosen { - stdout-path = &soc_uart0; + stdout-path = "serial0:115200n8"; }; psci { -- cgit v0.10.2 From e2a2729a9279eba7366e6a98a1e41ad6baef3caa Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Tue, 20 Jan 2015 12:20:31 -0600 Subject: amd-xgbe: Use proper Rx flow control register Updated hardware documention shows the Rx flow control settings were moved from the Rx queue operation mode register to a new Rx queue flow control register. The old flow control settings are now reserved areas of the Rx queue operation mode register. Update the code to use the new register. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h index 75b08c6..29a0927 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h @@ -767,16 +767,17 @@ #define MTL_Q_RQOMR 0x40 #define MTL_Q_RQMPOCR 0x44 #define MTL_Q_RQDR 0x4c +#define MTL_Q_RQFCR 0x50 #define MTL_Q_IER 0x70 #define MTL_Q_ISR 0x74 /* MTL queue register entry bit positions and sizes */ +#define MTL_Q_RQFCR_RFA_INDEX 1 +#define MTL_Q_RQFCR_RFA_WIDTH 6 +#define MTL_Q_RQFCR_RFD_INDEX 17 +#define MTL_Q_RQFCR_RFD_WIDTH 6 #define MTL_Q_RQOMR_EHFC_INDEX 7 #define MTL_Q_RQOMR_EHFC_WIDTH 1 -#define MTL_Q_RQOMR_RFA_INDEX 8 -#define MTL_Q_RQOMR_RFA_WIDTH 3 -#define MTL_Q_RQOMR_RFD_INDEX 13 -#define MTL_Q_RQOMR_RFD_WIDTH 3 #define MTL_Q_RQOMR_RQS_INDEX 16 #define MTL_Q_RQOMR_RQS_WIDTH 9 #define MTL_Q_RQOMR_RSF_INDEX 5 diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 53f5f66..4c66cd1 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -2079,10 +2079,10 @@ static void xgbe_config_flow_control_threshold(struct xgbe_prv_data *pdata) for (i = 0; i < pdata->rx_q_count; i++) { /* Activate flow control when less than 4k left in fifo */ - XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFA, 2); + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFA, 2); /* De-activate flow control when more than 6k left in fifo */ - XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFD, 4); + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFD, 4); } } -- cgit v0.10.2 From ada072816be1f284cda273f1d980a429b007566a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 24 Jan 2015 14:16:21 +0100 Subject: hwmon: (i5500_temp) New driver for the Intel 5500/5520/X58 chipsets The Intel 5500, 5520 and X58 chipsets embed a digital thermal sensor. This new driver supports it. Note that on many boards the sensor seems to be disabled and reports the minimum value (36.5 degrees Celsius) all the time. Signed-off-by: Jean Delvare Tested-by: Romain Dolbeau Reviewed-by: Guenter Roeck diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6529c09..a7de26d 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -574,6 +574,16 @@ config SENSORS_IIO_HWMON for those channels specified in the map. This map can be provided either via platform data or the device tree bindings. +config SENSORS_I5500 + tristate "Intel 5500/5520/X58 temperature sensor" + depends on X86 && PCI + help + If you say yes here you get support for the temperature + sensor inside the Intel 5500, 5520 and X58 chipsets. + + This driver can also be built as a module. If so, the module + will be called i5500_temp. + config SENSORS_CORETEMP tristate "Intel Core/Core2/Atom temperature sensor" depends on X86 diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 6728064..6c94147 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -68,6 +68,7 @@ obj-$(CONFIG_SENSORS_GPIO_FAN) += gpio-fan.o obj-$(CONFIG_SENSORS_HIH6130) += hih6130.o obj-$(CONFIG_SENSORS_HTU21) += htu21.o obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o +obj-$(CONFIG_SENSORS_I5500) += i5500_temp.o obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c new file mode 100644 index 0000000..cbc822d --- /dev/null +++ b/drivers/hwmon/i5500_temp.c @@ -0,0 +1,201 @@ +/* + * i5500_temp - Driver for Intel 5500/5520/X58 chipset thermal sensor + * + * Copyright (C) 2012, 2014 Jean Delvare + * + * 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, or + * (at your option) any later version. + * + * 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 + +/* Register definitions from datasheet */ +#define REG_TSTHRCATA 0xE2 +#define REG_TSCTRL 0xE8 +#define REG_TSTHRRPEX 0xEB +#define REG_TSTHRLO 0xEC +#define REG_TSTHRHI 0xEE +#define REG_CTHINT 0xF0 +#define REG_TSFSC 0xF3 +#define REG_CTSTS 0xF4 +#define REG_TSTHRRQPI 0xF5 +#define REG_CTCTRL 0xF7 +#define REG_TSTIMER 0xF8 + +struct i5500_temp_data { + struct device *hwmon_dev; + const char *name; +}; + +/* + * Sysfs stuff + */ + +/* Sensor resolution : 0.5 degree C */ +static ssize_t show_temp(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev); + long temp; + u16 tsthrhi; + s8 tsfsc; + + pci_read_config_word(pdev, REG_TSTHRHI, &tsthrhi); + pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); + temp = ((long)tsthrhi - tsfsc) * 500; + + return sprintf(buf, "%ld\n", temp); +} + +static ssize_t show_thresh(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev); + int reg = to_sensor_dev_attr(devattr)->index; + long temp; + u16 tsthr; + + pci_read_config_word(pdev, reg, &tsthr); + temp = tsthr * 500; + + return sprintf(buf, "%ld\n", temp); +} + +static ssize_t show_alarm(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev); + int nr = to_sensor_dev_attr(devattr)->index; + u8 ctsts; + + pci_read_config_byte(pdev, REG_CTSTS, &ctsts); + return sprintf(buf, "%u\n", (unsigned int)ctsts & (1 << nr)); +} + +static ssize_t show_name(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct i5500_temp_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", data->name); +} + +static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); +static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_thresh, NULL, 0xE2); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_thresh, NULL, 0xEC); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_thresh, NULL, 0xEE); +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); + +static struct attribute *i5500_temp_attributes[] = { + &dev_attr_temp1_input.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &dev_attr_name.attr, + NULL +}; + +static const struct attribute_group i5500_temp_group = { + .attrs = i5500_temp_attributes, +}; + +static const struct pci_device_id i5500_temp_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) }, + { 0 }, +}; + +MODULE_DEVICE_TABLE(pci, i5500_temp_ids); + +static int i5500_temp_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int err; + struct i5500_temp_data *data; + + data = kzalloc(sizeof(struct i5500_temp_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + data->name = "intel5500"; + dev_set_drvdata(&pdev->dev, data); + + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Failed to enable device\n"); + goto exit_free; + } + + /* Register sysfs hooks */ + err = sysfs_create_group(&pdev->dev.kobj, &i5500_temp_group); + if (err) + goto exit_free; + + data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + return 0; + + exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &i5500_temp_group); + exit_free: + kfree(data); + exit: + return err; +} + +static void i5500_temp_remove(struct pci_dev *pdev) +{ + struct i5500_temp_data *data = dev_get_drvdata(&pdev->dev); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&pdev->dev.kobj, &i5500_temp_group); + kfree(data); +} + +static struct pci_driver i5500_temp_driver = { + .name = "i5500_temp", + .id_table = i5500_temp_ids, + .probe = i5500_temp_probe, + .remove = i5500_temp_remove, +}; + +static int __init i5500_temp_init(void) +{ + return pci_register_driver(&i5500_temp_driver); +} + +static void __exit i5500_temp_exit(void) +{ + pci_unregister_driver(&i5500_temp_driver); +} + +MODULE_AUTHOR("Jean Delvare "); +MODULE_DESCRIPTION("Intel 5500/5520/X58 chipset thermal sensor driver"); +MODULE_LICENSE("GPL"); + +module_init(i5500_temp_init) +module_exit(i5500_temp_exit) -- cgit v0.10.2 From b8d48ce9519b21021e5875dce1a69f2941b17d1e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 24 Jan 2015 14:16:21 +0100 Subject: hwmon: (i5500_temp) Convert to devm_hwmon_device_register_with_groups Use devm_hwmon_device_register_with_groups() to simplify the code a bit. Signed-off-by: Jean Delvare Cc: Romain Dolbeau Reviewed-by: Guenter Roeck diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c index cbc822d..fdcfa9f 100644 --- a/drivers/hwmon/i5500_temp.c +++ b/drivers/hwmon/i5500_temp.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -37,11 +38,6 @@ #define REG_CTCTRL 0xF7 #define REG_TSTIMER 0xF8 -struct i5500_temp_data { - struct device *hwmon_dev; - const char *name; -}; - /* * Sysfs stuff */ @@ -50,7 +46,7 @@ struct i5500_temp_data { static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, char *buf) { - struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev *pdev = to_pci_dev(dev->parent); long temp; u16 tsthrhi; s8 tsfsc; @@ -65,7 +61,7 @@ static ssize_t show_temp(struct device *dev, static ssize_t show_thresh(struct device *dev, struct device_attribute *devattr, char *buf) { - struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev *pdev = to_pci_dev(dev->parent); int reg = to_sensor_dev_attr(devattr)->index; long temp; u16 tsthr; @@ -79,7 +75,7 @@ static ssize_t show_thresh(struct device *dev, static ssize_t show_alarm(struct device *dev, struct device_attribute *devattr, char *buf) { - struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev *pdev = to_pci_dev(dev->parent); int nr = to_sensor_dev_attr(devattr)->index; u8 ctsts; @@ -87,21 +83,12 @@ static ssize_t show_alarm(struct device *dev, return sprintf(buf, "%u\n", (unsigned int)ctsts & (1 << nr)); } -static ssize_t show_name(struct device *dev, struct device_attribute - *devattr, char *buf) -{ - struct i5500_temp_data *data = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", data->name); -} - static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_thresh, NULL, 0xE2); static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_thresh, NULL, 0xEC); static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_thresh, NULL, 0xEE); static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); static struct attribute *i5500_temp_attributes[] = { &dev_attr_temp1_input.attr, @@ -110,7 +97,6 @@ static struct attribute *i5500_temp_attributes[] = { &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, - &dev_attr_name.attr, NULL }; @@ -118,6 +104,11 @@ static const struct attribute_group i5500_temp_group = { .attrs = i5500_temp_attributes, }; +static const struct attribute_group *i5500_temp_groups[] = { + &i5500_temp_group, + NULL +}; + static const struct pci_device_id i5500_temp_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) }, { 0 }, @@ -129,58 +120,24 @@ static int i5500_temp_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int err; - struct i5500_temp_data *data; - - data = kzalloc(sizeof(struct i5500_temp_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - - data->name = "intel5500"; - dev_set_drvdata(&pdev->dev, data); + struct device *hwmon_dev; err = pci_enable_device(pdev); if (err) { dev_err(&pdev->dev, "Failed to enable device\n"); - goto exit_free; - } - - /* Register sysfs hooks */ - err = sysfs_create_group(&pdev->dev.kobj, &i5500_temp_group); - if (err) - goto exit_free; - - data->hwmon_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove; + return err; } - return 0; - - exit_remove: - sysfs_remove_group(&pdev->dev.kobj, &i5500_temp_group); - exit_free: - kfree(data); - exit: - return err; -} - -static void i5500_temp_remove(struct pci_dev *pdev) -{ - struct i5500_temp_data *data = dev_get_drvdata(&pdev->dev); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&pdev->dev.kobj, &i5500_temp_group); - kfree(data); + hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, + "intel5500", NULL, + i5500_temp_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); } static struct pci_driver i5500_temp_driver = { .name = "i5500_temp", .id_table = i5500_temp_ids, .probe = i5500_temp_probe, - .remove = i5500_temp_remove, }; static int __init i5500_temp_init(void) -- cgit v0.10.2 From e3d982034dd74b32f621fcba7adeb77716fa0fb4 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 24 Jan 2015 14:16:21 +0100 Subject: hwmon: (i5500_temp) Don't bind to disabled sensors On many motherboards, for an unknown reason, the thermal sensor seems to be disabled and will return a constant temperature value of 36.5 degrees Celsius. Don't bind to the device in that case, so that we don't report this bogus value to userspace. Signed-off-by: Jean Delvare Cc: Romain Dolbeau Reviewed-by: Guenter Roeck diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c index fdcfa9f..fb84a0e 100644 --- a/drivers/hwmon/i5500_temp.c +++ b/drivers/hwmon/i5500_temp.c @@ -121,6 +121,8 @@ static int i5500_temp_probe(struct pci_dev *pdev, { int err; struct device *hwmon_dev; + u32 tstimer; + s8 tsfsc; err = pci_enable_device(pdev); if (err) { @@ -128,6 +130,13 @@ static int i5500_temp_probe(struct pci_dev *pdev, return err; } + pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); + pci_read_config_dword(pdev, REG_TSTIMER, &tstimer); + if (tsfsc == 0x7F && tstimer == 0x07D30D40) { + dev_warn(&pdev->dev, "Sensor seems to be disabled\n"); + return -ENODEV; + } + hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, "intel5500", NULL, i5500_temp_groups); -- cgit v0.10.2 From aef64d0d380132c11e27c44b0f73afb9bdb59771 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 24 Jan 2015 14:16:22 +0100 Subject: hwmon: (i5500_temp) Convert to module_pci_driver Use module_pci_driver to simplify the code a bit. Signed-off-by: Axel Lin Reviewed-by: Guenter Roeck Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c index fb84a0e..2922be3 100644 --- a/drivers/hwmon/i5500_temp.c +++ b/drivers/hwmon/i5500_temp.c @@ -149,19 +149,8 @@ static struct pci_driver i5500_temp_driver = { .probe = i5500_temp_probe, }; -static int __init i5500_temp_init(void) -{ - return pci_register_driver(&i5500_temp_driver); -} - -static void __exit i5500_temp_exit(void) -{ - pci_unregister_driver(&i5500_temp_driver); -} +module_pci_driver(i5500_temp_driver); MODULE_AUTHOR("Jean Delvare "); MODULE_DESCRIPTION("Intel 5500/5520/X58 chipset thermal sensor driver"); MODULE_LICENSE("GPL"); - -module_init(i5500_temp_init) -module_exit(i5500_temp_exit) -- cgit v0.10.2 From 86c725e3c5a6baa5316787e0b017d8ac8b0facd8 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 24 Jan 2015 14:16:22 +0100 Subject: hwmon: (i5500_temp) Convert to use ATTRIBUTE_GROUPS macro Use ATTRIBUTE_GROUPS macro to simplify the code a bit. Signed-off-by: Axel Lin Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c index 2922be3..3e3ccbf 100644 --- a/drivers/hwmon/i5500_temp.c +++ b/drivers/hwmon/i5500_temp.c @@ -90,7 +90,7 @@ static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_thresh, NULL, 0xEE); static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); -static struct attribute *i5500_temp_attributes[] = { +static struct attribute *i5500_temp_attrs[] = { &dev_attr_temp1_input.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr, &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, @@ -100,14 +100,7 @@ static struct attribute *i5500_temp_attributes[] = { NULL }; -static const struct attribute_group i5500_temp_group = { - .attrs = i5500_temp_attributes, -}; - -static const struct attribute_group *i5500_temp_groups[] = { - &i5500_temp_group, - NULL -}; +ATTRIBUTE_GROUPS(i5500_temp); static const struct pci_device_id i5500_temp_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) }, @@ -133,7 +126,7 @@ static int i5500_temp_probe(struct pci_dev *pdev, pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); pci_read_config_dword(pdev, REG_TSTIMER, &tstimer); if (tsfsc == 0x7F && tstimer == 0x07D30D40) { - dev_warn(&pdev->dev, "Sensor seems to be disabled\n"); + dev_notice(&pdev->dev, "Sensor seems to be disabled\n"); return -ENODEV; } -- cgit v0.10.2 From 96b26c8c64c7a30488b8b404f7a63346df4c3bff Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 8 Jan 2015 18:52:26 -0500 Subject: dm: fix handling of multiple internal suspends Commit ffcc393641 ("dm: enhance internal suspend and resume interface") attempted to handle multiple internal suspends on the same device, but it did that incorrectly. When these functions are called in this order on the same device the device is no longer suspended, but it should be: dm_internal_suspend_noflush dm_internal_suspend_noflush dm_internal_resume Fix this bug by maintaining an 'internal_suspend_count' and resuming the device when this count drops to zero. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer diff --git a/drivers/md/dm.c b/drivers/md/dm.c index b98cd9d..2caf5b3 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -206,6 +206,9 @@ struct mapped_device { /* zero-length flush that will be cloned and submitted to targets */ struct bio flush_bio; + /* the number of internal suspends */ + unsigned internal_suspend_count; + struct dm_stats stats; }; @@ -2928,7 +2931,7 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla { struct dm_table *map = NULL; - if (dm_suspended_internally_md(md)) + if (md->internal_suspend_count++) return; /* nested internal suspend */ if (dm_suspended_md(md)) { @@ -2953,7 +2956,9 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla static void __dm_internal_resume(struct mapped_device *md) { - if (!dm_suspended_internally_md(md)) + BUG_ON(!md->internal_suspend_count); + + if (--md->internal_suspend_count) return; /* resume from nested internal suspend */ if (dm_suspended_md(md)) -- cgit v0.10.2 From 9143e398a443d104d0c1247a3049ccdeb9b7f192 Mon Sep 17 00:00:00 2001 From: Nimrod Andy Date: Tue, 20 Jan 2015 16:48:17 +0800 Subject: ARM: dts: imx6sx: correct i.MX6sx sdb board enet phy address The commit (3d125f9c91c5) cause i.MX6SX sdb enet cannot work. The cause is the commit add mdio node with un-correct phy address. The patch just correct i.MX6sx sdb board enet phy address. V2: * As Shawn's suggestion that unit-address should match 'reg' property, so update ethernet-phy unit-address. Acked-by: Stefan Agner Signed-off-by: Fugang Duan Acked-by: Shawn Guo Signed-off-by: David S. Miller diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts index 8c1febd..c108bb4 100644 --- a/arch/arm/boot/dts/imx6sx-sdb.dts +++ b/arch/arm/boot/dts/imx6sx-sdb.dts @@ -166,12 +166,12 @@ #address-cells = <1>; #size-cells = <0>; - ethphy1: ethernet-phy@0 { - reg = <0>; + ethphy1: ethernet-phy@1 { + reg = <1>; }; - ethphy2: ethernet-phy@1 { - reg = <1>; + ethphy2: ethernet-phy@2 { + reg = <2>; }; }; }; -- cgit v0.10.2 From f104fedc0da126abe93dd0f4a9fa13e5133bf9df Mon Sep 17 00:00:00 2001 From: Govindarajulu Varadarajan <_govind@gmx.com> Date: Tue, 20 Jan 2015 18:46:15 +0530 Subject: enic: fix rx napi poll return value With the commit d75b1ade567ffab ("net: less interrupt masking in NAPI") napi repoll is done only when work_done == budget. When we are in busy_poll we return 0 in napi_poll. We should return budget. Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com> Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index b29e027..e356afa 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -1335,7 +1335,7 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget) int err; if (!enic_poll_lock_napi(&enic->rq[rq])) - return work_done; + return budget; /* Service RQ */ -- cgit v0.10.2 From 6088beef3f7517717bd21d90b379714dd0837079 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 22 Jan 2015 07:56:18 -0800 Subject: netxen: fix netxen_nic_poll() logic NAPI poll logic now enforces that a poller returns exactly the budget when it wants to be called again. If a driver limits TX completion, it has to return budget as well when the limit is hit, not the number of received packets. Reported-and-tested-by: Mike Galbraith Signed-off-by: Eric Dumazet Fixes: d75b1ade567f ("net: less interrupt masking in NAPI") Cc: Manish Chopra Acked-by: Manish Chopra Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 6130375..c531c8a 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -2388,7 +2388,10 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) work_done = netxen_process_rcv_ring(sds_ring, budget); - if ((work_done < budget) && tx_complete) { + if (!tx_complete) + work_done = budget; + + if (work_done < budget) { napi_complete(&sds_ring->napi); if (test_bit(__NX_DEV_UP, &adapter->state)) netxen_nic_enable_int(sds_ring); -- cgit v0.10.2 From 6b8d9117ccb4f81b1244aafa7bc70ef8fa45fc49 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Fri, 23 Jan 2015 20:47:00 -0500 Subject: net: llc: use correct size for sysctl timeout entries The timeout entries are sizeof(int) rather than sizeof(long), which means that when they were getting read we'd also leak kernel memory to userspace along with the timeout values. Signed-off-by: Sasha Levin Signed-off-by: David S. Miller diff --git a/net/llc/sysctl_net_llc.c b/net/llc/sysctl_net_llc.c index 612a5dd..799bafc 100644 --- a/net/llc/sysctl_net_llc.c +++ b/net/llc/sysctl_net_llc.c @@ -18,28 +18,28 @@ static struct ctl_table llc2_timeout_table[] = { { .procname = "ack", .data = &sysctl_llc2_ack_timeout, - .maxlen = sizeof(long), + .maxlen = sizeof(sysctl_llc2_ack_timeout), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "busy", .data = &sysctl_llc2_busy_timeout, - .maxlen = sizeof(long), + .maxlen = sizeof(sysctl_llc2_busy_timeout), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "p", .data = &sysctl_llc2_p_timeout, - .maxlen = sizeof(long), + .maxlen = sizeof(sysctl_llc2_p_timeout), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, { .procname = "rej", .data = &sysctl_llc2_rej_timeout, - .maxlen = sizeof(long), + .maxlen = sizeof(sysctl_llc2_rej_timeout), .mode = 0644, .proc_handler = proc_dointvec_jiffies, }, -- cgit v0.10.2 From 2aab9525c365048e55b40102c9b69dcb43425d8d Mon Sep 17 00:00:00 2001 From: Mahesh Bandewar Date: Sat, 24 Jan 2015 21:53:43 -0800 Subject: ipvlan: fix incorrect usage of IS_ERR() macro in IPv6 code path. The ip6_route_output() always returns a valid dst pointer unlike in IPv4 case. So the validation has to be different from the IPv4 path. Correcting that error in this patch. This was picked up by a static checker with a following warning - drivers/net/ipvlan/ipvlan_core.c:380 ipvlan_process_v6_outbound() warn: 'dst' isn't an ERR_PTR Signed-off-by: Mahesh Bandewar Reported-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index a14d877..2e19528 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -377,9 +377,11 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) }; dst = ip6_route_output(dev_net(dev), NULL, &fl6); - if (IS_ERR(dst)) + if (dst->error) { + ret = dst->error; + dst_release(dst); goto err; - + } skb_dst_drop(skb); skb_dst_set(skb, dst); err = ip6_local_out(skb); -- cgit v0.10.2 From 24df8986f36b9a5d8ae08236498d92267bac454b Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 20 Jan 2015 19:13:32 -0500 Subject: net: dsa: set slave MII bus PHY mask When registering a mdio bus, Linux assumes than every port has a PHY and tries to scan it. If a switch port has no PHY registered, DSA will fail to register the slave MII bus. To fix this, set the slave MII bus PHY mask to the switch PHYs mask. As an example, if we use a Marvell MV88E6352 (which is a 7-port switch with no registered PHYs for port 5 and port 6), with the following declared names: static struct dsa_chip_data switch_cdata = { [...] .port_names[0] = "sw0", .port_names[1] = "sw1", .port_names[2] = "sw2", .port_names[3] = "sw3", .port_names[4] = "sw4", .port_names[5] = "cpu", }; DSA will fail to create the switch instance. With the PHY mask set for the slave MII bus, only the PHY for ports 0-4 will be scanned and the instance will be successfully created. Signed-off-by: Vivien Didelot Tested-by: Florian Fainelli Acked-by: Florian Fainelli Signed-off-by: David S. Miller diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 515569f..589aafd 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -46,6 +46,7 @@ void dsa_slave_mii_bus_init(struct dsa_switch *ds) snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d:%.2x", ds->index, ds->pd->sw_addr); ds->slave_mii_bus->parent = ds->master_dev; + ds->slave_mii_bus->phy_mask = ~ds->phys_mii_mask; } -- cgit v0.10.2 From 26bc420b59a38e4e6685a73345a0def461136dce Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 25 Jan 2015 20:04:41 -0800 Subject: Linux 3.19-rc6 diff --git a/Makefile b/Makefile index fb93350..95a0e82 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 19 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6 NAME = Diseased Newt # *DOCUMENTATION* -- cgit v0.10.2 From b0a1ba59921eaaa9cb8f97bb35f2e6870fcdfedc Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Tue, 20 Jan 2015 19:16:02 -0800 Subject: ipv6: Fix __ip6_route_redirect In my last commit (a3c00e4: ipv6: Remove BACKTRACK macro), the changes in __ip6_route_redirect is incorrect. The following case is missed: 1. The for loop tries to find a valid gateway rt. If it fails to find one, rt will be NULL. 2. When rt is NULL, it is set to the ip6_null_entry. 3. The newly added 'else if', from a3c00e4, will stop the backtrack from happening. Signed-off-by: Martin KaFai Lau Signed-off-by: David S. Miller diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 166e33b..49596535 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1242,12 +1242,16 @@ restart: rt = net->ipv6.ip6_null_entry; else if (rt->dst.error) { rt = net->ipv6.ip6_null_entry; - } else if (rt == net->ipv6.ip6_null_entry) { + goto out; + } + + if (rt == net->ipv6.ip6_null_entry) { fn = fib6_backtrack(fn, &fl6->saddr); if (fn) goto restart; } +out: dst_hold(&rt->dst); read_unlock_bh(&table->tb6_lock); -- cgit v0.10.2 From efbbc1d56774a18d9518b8500212629fb5809d1b Mon Sep 17 00:00:00 2001 From: Eugene Crosser Date: Wed, 21 Jan 2015 13:39:09 +0100 Subject: qeth: clean up error handling In the functions that are registering and unregistering MAC addresses in the qeth-handled hardware, remove callback functions that are unnesessary, as only the return code is analyzed. Translate hardware response codes to semi-standard 'errno'-like codes for readability. Add kernel-doc description to the internal API function qeth_send_control_data(). Signed-off-by: Eugene Crosser Signed-off-by: Ursula Braun Reviewed-by: Thomas-Mich Richter Signed-off-by: David S. Miller diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index f407e37..e2fbfff 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2021,10 +2021,36 @@ void qeth_prepare_control_data(struct qeth_card *card, int len, } EXPORT_SYMBOL_GPL(qeth_prepare_control_data); +/** + * qeth_send_control_data() - send control command to the card + * @card: qeth_card structure pointer + * @len: size of the command buffer + * @iob: qeth_cmd_buffer pointer + * @reply_cb: callback function pointer + * @cb_card: pointer to the qeth_card structure + * @cb_reply: pointer to the qeth_reply structure + * @cb_cmd: pointer to the original iob for non-IPA + * commands, or to the qeth_ipa_cmd structure + * for the IPA commands. + * @reply_param: private pointer passed to the callback + * + * Returns the value of the `return_code' field of the response + * block returned from the hardware, or other error indication. + * Value of zero indicates successful execution of the command. + * + * Callback function gets called one or more times, with cb_cmd + * pointing to the response returned by the hardware. Callback + * function must return non-zero if more reply blocks are expected, + * and zero if the last or only reply block is received. Callback + * function can get the value of the reply_param pointer from the + * field 'param' of the structure qeth_reply. + */ + int qeth_send_control_data(struct qeth_card *card, int len, struct qeth_cmd_buffer *iob, - int (*reply_cb)(struct qeth_card *, struct qeth_reply *, - unsigned long), + int (*reply_cb)(struct qeth_card *cb_card, + struct qeth_reply *cb_reply, + unsigned long cb_cmd), void *reply_param) { int rc; @@ -2932,6 +2958,12 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, } EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd); +/** + * qeth_send_ipa_cmd() - send an IPA command + * + * See qeth_send_control_data() for explanation of the arguments. + */ + int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, int (*reply_cb)(struct qeth_card *, struct qeth_reply*, unsigned long), diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index d02cd1a..b7b9d5c 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -27,10 +27,7 @@ static int qeth_l2_set_offline(struct ccwgroup_device *); static int qeth_l2_stop(struct net_device *); static int qeth_l2_send_delmac(struct qeth_card *, __u8 *); static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *, - enum qeth_ipa_cmds, - int (*reply_cb) (struct qeth_card *, - struct qeth_reply*, - unsigned long)); + enum qeth_ipa_cmds); static void qeth_l2_set_multicast_list(struct net_device *); static int qeth_l2_recover(void *); static void qeth_bridgeport_query_support(struct qeth_card *card); @@ -130,56 +127,68 @@ static struct net_device *qeth_l2_netdev_by_devno(unsigned char *read_dev_no) return ndev; } -static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card, - struct qeth_reply *reply, - unsigned long data) +static int qeth_setdel_makerc(struct qeth_card *card, int retcode) { - struct qeth_ipa_cmd *cmd; - __u8 *mac; + int rc; - QETH_CARD_TEXT(card, 2, "L2Sgmacb"); - cmd = (struct qeth_ipa_cmd *) data; - mac = &cmd->data.setdelmac.mac[0]; - /* MAC already registered, needed in couple/uncouple case */ - if (cmd->hdr.return_code == IPA_RC_L2_DUP_MAC) { - QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s \n", - mac, QETH_CARD_IFNAME(card)); - cmd->hdr.return_code = 0; + if (retcode) + QETH_CARD_TEXT_(card, 2, "err%d", retcode); + switch (retcode) { + case IPA_RC_SUCCESS: + rc = 0; + break; + case IPA_RC_L2_UNSUPPORTED_CMD: + rc = -ENOSYS; + break; + case IPA_RC_L2_ADDR_TABLE_FULL: + rc = -ENOSPC; + break; + case IPA_RC_L2_DUP_MAC: + case IPA_RC_L2_DUP_LAYER3_MAC: + rc = -EEXIST; + break; + case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: + case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: + rc = -EPERM; + break; + case IPA_RC_L2_MAC_NOT_FOUND: + rc = -ENOENT; + break; + default: + rc = -EIO; + break; } - if (cmd->hdr.return_code) - QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %x\n", - mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code); - return 0; + return rc; } static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac) { - QETH_CARD_TEXT(card, 2, "L2Sgmac"); - return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC, - qeth_l2_send_setgroupmac_cb); -} - -static int qeth_l2_send_delgroupmac_cb(struct qeth_card *card, - struct qeth_reply *reply, - unsigned long data) -{ - struct qeth_ipa_cmd *cmd; - __u8 *mac; + int rc; - QETH_CARD_TEXT(card, 2, "L2Dgmacb"); - cmd = (struct qeth_ipa_cmd *) data; - mac = &cmd->data.setdelmac.mac[0]; - if (cmd->hdr.return_code) - QETH_DBF_MESSAGE(2, "Could not delete group MAC %pM on %s: %x\n", - mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code); - return 0; + QETH_CARD_TEXT(card, 2, "L2Sgmac"); + rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, + IPA_CMD_SETGMAC)); + if (rc == -EEXIST) + QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s\n", + mac, QETH_CARD_IFNAME(card)); + else if (rc) + QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %d\n", + mac, QETH_CARD_IFNAME(card), rc); + return rc; } static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac) { + int rc; + QETH_CARD_TEXT(card, 2, "L2Dgmac"); - return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC, - qeth_l2_send_delgroupmac_cb); + rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, + IPA_CMD_DELGMAC)); + if (rc) + QETH_DBF_MESSAGE(2, + "Could not delete group MAC %pM on %s: %d\n", + mac, QETH_CARD_IFNAME(card), rc); + return rc; } static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) @@ -197,10 +206,11 @@ static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) mc->is_vmac = vmac; if (vmac) { - rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC, - NULL); + rc = qeth_setdel_makerc(card, + qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC)); } else { - rc = qeth_l2_send_setgroupmac(card, mac); + rc = qeth_setdel_makerc(card, + qeth_l2_send_setgroupmac(card, mac)); } if (!rc) @@ -218,7 +228,7 @@ static void qeth_l2_del_all_mc(struct qeth_card *card, int del) if (del) { if (mc->is_vmac) qeth_l2_send_setdelmac(card, mc->mc_addr, - IPA_CMD_DELVMAC, NULL); + IPA_CMD_DELVMAC); else qeth_l2_send_delgroupmac(card, mc->mc_addr); } @@ -539,10 +549,7 @@ out: } static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, - enum qeth_ipa_cmds ipacmd, - int (*reply_cb) (struct qeth_card *, - struct qeth_reply*, - unsigned long)) + enum qeth_ipa_cmds ipacmd) { struct qeth_ipa_cmd *cmd; struct qeth_cmd_buffer *iob; @@ -552,78 +559,50 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.setdelmac.mac_length = OSA_ADDR_LEN; memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN); - return qeth_send_ipa_cmd(card, iob, reply_cb, NULL); + return qeth_send_ipa_cmd(card, iob, NULL, NULL); } -static int qeth_l2_send_setmac_cb(struct qeth_card *card, - struct qeth_reply *reply, - unsigned long data) +static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) { - struct qeth_ipa_cmd *cmd; + int rc; - QETH_CARD_TEXT(card, 2, "L2Smaccb"); - cmd = (struct qeth_ipa_cmd *) data; - if (cmd->hdr.return_code) { - QETH_CARD_TEXT_(card, 2, "L2er%x", cmd->hdr.return_code); + QETH_CARD_TEXT(card, 2, "L2Setmac"); + rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, + IPA_CMD_SETVMAC)); + if (rc == 0) { + card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; + memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN); + dev_info(&card->gdev->dev, + "MAC address %pM successfully registered on device %s\n", + card->dev->dev_addr, card->dev->name); + } else { card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; - switch (cmd->hdr.return_code) { - case IPA_RC_L2_DUP_MAC: - case IPA_RC_L2_DUP_LAYER3_MAC: + switch (rc) { + case -EEXIST: dev_warn(&card->gdev->dev, - "MAC address %pM already exists\n", - cmd->data.setdelmac.mac); + "MAC address %pM already exists\n", mac); break; - case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: - case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: + case -EPERM: dev_warn(&card->gdev->dev, - "MAC address %pM is not authorized\n", - cmd->data.setdelmac.mac); - break; - default: + "MAC address %pM is not authorized\n", mac); break; } - } else { - card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; - memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac, - OSA_ADDR_LEN); - dev_info(&card->gdev->dev, - "MAC address %pM successfully registered on device %s\n", - card->dev->dev_addr, card->dev->name); } - return 0; -} - -static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) -{ - QETH_CARD_TEXT(card, 2, "L2Setmac"); - return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC, - qeth_l2_send_setmac_cb); -} - -static int qeth_l2_send_delmac_cb(struct qeth_card *card, - struct qeth_reply *reply, - unsigned long data) -{ - struct qeth_ipa_cmd *cmd; - - QETH_CARD_TEXT(card, 2, "L2Dmaccb"); - cmd = (struct qeth_ipa_cmd *) data; - if (cmd->hdr.return_code) { - QETH_CARD_TEXT_(card, 2, "err%d", cmd->hdr.return_code); - return 0; - } - card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; - - return 0; + return rc; } static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac) { + int rc; + QETH_CARD_TEXT(card, 2, "L2Delmac"); if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) return 0; - return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC, - qeth_l2_send_delmac_cb); + rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, + IPA_CMD_DELVMAC)); + if (rc == 0) + card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; + return rc; } static int qeth_l2_request_initial_mac(struct qeth_card *card) @@ -687,7 +666,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) return -ERESTARTSYS; } rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); - if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND)) + if (!rc || (rc == -ENOENT)) rc = qeth_l2_send_setmac(card, addr->sa_data); return rc ? -EINVAL : 0; } -- cgit v0.10.2 From 1aec42bcc07ef2b341aa4aa303fe325276db1178 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 21 Jan 2015 13:39:10 +0100 Subject: 390/qeth: Fix locking warning during qeth device setup Do not wait for channel command buffers in IPA commands. The potential wait could be done while holding a spin lock and causes in recent kernels such a bug if kernel lock debugging is enabled: kernel: BUG: sleeping function called from invalid context at drivers/s390/net/qeth_core_main.c: 794 kernel: in_atomic(): 1, irqs_disabled(): 0, pid: 2031, name: NetworkManager kernel: 2 locks held by NetworkManager/2031: kernel: #0: (rtnl_mutex){+.+.+.}, at: [<00000000006e0d7a>] rtnetlink_rcv+0x32/0x50 kernel: #1: (_xmit_ETHER){+.....}, at: [<00000000006cfe90>] dev_set_rx_mode+0x30/0x50 kernel: CPU: 0 PID: 2031 Comm: NetworkManager Not tainted 3.18.0-rc5-next-20141124 #1 kernel: 00000000275fb1f0 00000000275fb280 0000000000000002 0000000000000000 00000000275fb320 00000000275fb298 00000000275fb298 00000000007e326a 0000000000000000 000000000099ce2c 00000000009b4988 000000000000000b 00000000275fb2e0 00000000275fb280 0000000000000000 0000000000000000 0000000000000000 00000000001129c8 00000000275fb280 00000000275fb2e0 kernel: Call Trace: kernel: ([<00000000001128b0>] show_trace+0xf8/0x158) kernel: [<000000000011297a>] show_stack+0x6a/0xe8 kernel: [<00000000007e995a>] dump_stack+0x82/0xb0 kernel: [<000000000017d668>] ___might_sleep+0x170/0x228 kernel: [<000003ff80026f0e>] qeth_wait_for_buffer+0x36/0xd0 [qeth] kernel: [<000003ff80026fe2>] qeth_get_ipacmd_buffer+0x3a/0xc0 [qeth] kernel: [<000003ff80105078>] qeth_l3_send_setdelmc+0x58/0xf8 [qeth_l3] kernel: [<000003ff8010b1fe>] qeth_l3_set_ip_addr_list+0x2c6/0x848 [qeth_l3] kernel: [<000003ff8010bbb4>] qeth_l3_set_multicast_list+0x434/0xc48 [qeth_l3] kernel: [<00000000006cfe9a>] dev_set_rx_mode+0x3a/0x50 kernel: [<00000000006cff90>] __dev_open+0xe0/0x140 kernel: [<00000000006d02a0>] __dev_change_flags+0xa0/0x178 kernel: [<00000000006d03a8>] dev_change_flags+0x30/0x70 kernel: [<00000000006e14ee>] do_setlink+0x346/0x9a0 ... The device driver has plenty of command buffers available per channel for channel command communication. In the extremely rare case when there is no command buffer available, return a NULL pointer and issue a warning in the kernel log. The caller handles the case when a NULL pointer is encountered and returns an error. In the case the wait for command buffer is possible (because no lock is held as in the OSN case), still wait until a channel command buffer is available. Signed-off-by: Thomas Richter Signed-off-by: Ursula Braun Reviewed-by: Eugene Crosser Signed-off-by: David S. Miller diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index e2fbfff..642c77c 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1784,6 +1784,8 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, QETH_DBF_TEXT(SETUP, 2, "idxanswr"); card = CARD_FROM_CDEV(channel->ccwdev); iob = qeth_get_buffer(channel); + if (!iob) + return -ENOMEM; iob->callback = idx_reply_cb; memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1)); channel->ccw.count = QETH_BUFSIZE; @@ -1834,6 +1836,8 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, QETH_DBF_TEXT(SETUP, 2, "idxactch"); iob = qeth_get_buffer(channel); + if (!iob) + return -ENOMEM; iob->callback = idx_reply_cb; memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1)); channel->ccw.count = IDX_ACTIVATE_SIZE; @@ -2940,9 +2944,16 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card, struct qeth_cmd_buffer *iob; struct qeth_ipa_cmd *cmd; - iob = qeth_wait_for_buffer(&card->write); - cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); - qeth_fill_ipacmd_header(card, cmd, ipacmd, prot); + iob = qeth_get_buffer(&card->write); + if (iob) { + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); + qeth_fill_ipacmd_header(card, cmd, ipacmd, prot); + } else { + dev_warn(&card->gdev->dev, + "The qeth driver ran out of channel command buffers\n"); + QETH_DBF_MESSAGE(1, "%s The qeth driver ran out of channel command buffers", + dev_name(&card->gdev->dev)); + } return iob; } @@ -3000,6 +3011,8 @@ int qeth_send_startlan(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "strtlan"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_STARTLAN, 0); + if (!iob) + return -ENOMEM; rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); return rc; } @@ -3045,11 +3058,13 @@ static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card, iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS, QETH_PROT_IPV4); - cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); - cmd->data.setadapterparms.hdr.cmdlength = cmdlen; - cmd->data.setadapterparms.hdr.command_code = command; - cmd->data.setadapterparms.hdr.used_total = 1; - cmd->data.setadapterparms.hdr.seq_no = 1; + if (iob) { + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); + cmd->data.setadapterparms.hdr.cmdlength = cmdlen; + cmd->data.setadapterparms.hdr.command_code = command; + cmd->data.setadapterparms.hdr.used_total = 1; + cmd->data.setadapterparms.hdr.seq_no = 1; + } return iob; } @@ -3062,6 +3077,8 @@ int qeth_query_setadapterparms(struct qeth_card *card) QETH_CARD_TEXT(card, 3, "queryadp"); iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED, sizeof(struct qeth_ipacmd_setadpparms)); + if (!iob) + return -ENOMEM; rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL); return rc; } @@ -3112,6 +3129,8 @@ int qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot) QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot); + if (!iob) + return -ENOMEM; rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL); return rc; } @@ -3151,6 +3170,8 @@ int qeth_query_switch_attributes(struct qeth_card *card, return -ENOMEDIUM; iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES, sizeof(struct qeth_ipacmd_setadpparms_hdr)); + if (!iob) + return -ENOMEM; return qeth_send_ipa_cmd(card, iob, qeth_query_switch_attributes_cb, sw_info); } @@ -3178,6 +3199,8 @@ static int qeth_query_setdiagass(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "qdiagass"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.diagass.subcmd_len = 16; cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY; @@ -3229,6 +3252,8 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action) QETH_DBF_TEXT(SETUP, 2, "diagtrap"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.diagass.subcmd_len = 80; cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP; @@ -4194,6 +4219,8 @@ void qeth_setadp_promisc_mode(struct qeth_card *card) iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE, sizeof(struct qeth_ipacmd_setadpparms)); + if (!iob) + return; cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); cmd->data.setadapterparms.data.mode = mode; qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL); @@ -4264,6 +4291,8 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card) iob = qeth_get_adapter_cmd(card, IPA_SETADP_ALTER_MAC_ADDRESS, sizeof(struct qeth_ipacmd_setadpparms)); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC; cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN; @@ -4377,6 +4406,8 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL, sizeof(struct qeth_ipacmd_setadpparms_hdr) + sizeof(struct qeth_set_access_ctrl)); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl; access_ctrl_req->subcmd_code = isolation; @@ -4620,6 +4651,10 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, QETH_SNMP_SETADP_CMDLENGTH + req_len); + if (!iob) { + rc = -ENOMEM; + goto out; + } cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, @@ -4631,7 +4666,7 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) rc = -EFAULT; } - +out: kfree(ureq); kfree(qinfo.udata); return rc; @@ -4702,6 +4737,10 @@ int qeth_query_oat_command(struct qeth_card *card, char __user *udata) iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT, sizeof(struct qeth_ipacmd_setadpparms_hdr) + sizeof(struct qeth_query_oat)); + if (!iob) { + rc = -ENOMEM; + goto out_free; + } cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); oat_req = &cmd->data.setadapterparms.data.query_oat; oat_req->subcmd_code = oat_data.command; @@ -4767,6 +4806,8 @@ static int qeth_query_card_info(struct qeth_card *card, return -EOPNOTSUPP; iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, sizeof(struct qeth_ipacmd_setadpparms_hdr)); + if (!iob) + return -ENOMEM; return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, (void *)carrier_info); } @@ -5092,11 +5133,23 @@ retriable: card->options.adp.supported_funcs = 0; card->options.sbp.supported_funcs = 0; card->info.diagass_support = 0; - qeth_query_ipassists(card, QETH_PROT_IPV4); - if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) - qeth_query_setadapterparms(card); - if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) - qeth_query_setdiagass(card); + rc = qeth_query_ipassists(card, QETH_PROT_IPV4); + if (rc == -ENOMEM) + goto out; + if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) { + rc = qeth_query_setadapterparms(card); + if (rc < 0) { + QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); + goto out; + } + } + if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) { + rc = qeth_query_setdiagass(card); + if (rc < 0) { + QETH_DBF_TEXT_(SETUP, 2, "7err%d", rc); + goto out; + } + } return 0; out: dev_warn(&card->gdev->dev, "The qeth device driver failed to recover " diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index b7b9d5c..ce87ae7 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -132,7 +132,7 @@ static int qeth_setdel_makerc(struct qeth_card *card, int retcode) int rc; if (retcode) - QETH_CARD_TEXT_(card, 2, "err%d", retcode); + QETH_CARD_TEXT_(card, 2, "err%04x", retcode); switch (retcode) { case IPA_RC_SUCCESS: rc = 0; @@ -154,6 +154,9 @@ static int qeth_setdel_makerc(struct qeth_card *card, int retcode) case IPA_RC_L2_MAC_NOT_FOUND: rc = -ENOENT; break; + case -ENOMEM: + rc = -ENOMEM; + break; default: rc = -EIO; break; @@ -301,6 +304,8 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i, QETH_CARD_TEXT_(card, 4, "L2sdv%x", ipacmd); iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.setdelvlan.vlan_id = i; return qeth_send_ipa_cmd(card, iob, @@ -323,6 +328,7 @@ static int qeth_l2_vlan_rx_add_vid(struct net_device *dev, { struct qeth_card *card = dev->ml_priv; struct qeth_vlan_vid *id; + int rc; QETH_CARD_TEXT_(card, 4, "aid:%d", vid); if (!vid) @@ -338,7 +344,11 @@ static int qeth_l2_vlan_rx_add_vid(struct net_device *dev, id = kmalloc(sizeof(struct qeth_vlan_vid), GFP_ATOMIC); if (id) { id->vid = vid; - qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN); + rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN); + if (rc) { + kfree(id); + return rc; + } spin_lock_bh(&card->vlanlock); list_add_tail(&id->list, &card->vid_list); spin_unlock_bh(&card->vlanlock); @@ -353,6 +363,7 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev, { struct qeth_vlan_vid *id, *tmpid = NULL; struct qeth_card *card = dev->ml_priv; + int rc = 0; QETH_CARD_TEXT_(card, 4, "kid:%d", vid); if (card->info.type == QETH_CARD_TYPE_OSM) { @@ -373,11 +384,11 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev, } spin_unlock_bh(&card->vlanlock); if (tmpid) { - qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN); + rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN); kfree(tmpid); } qeth_l2_set_multicast_list(card->dev); - return 0; + return rc; } static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) @@ -556,6 +567,8 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, QETH_CARD_TEXT(card, 2, "L2sdmac"); iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.setdelmac.mac_length = OSA_ADDR_LEN; memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN); @@ -630,7 +643,7 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) if (rc) { QETH_DBF_MESSAGE(2, "couldn't get MAC address on " "device %s: x%x\n", CARD_BUS_ID(card), rc); - QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); + QETH_DBF_TEXT_(SETUP, 2, "1err%04x", rc); return rc; } QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, OSA_ADDR_LEN); @@ -975,7 +988,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) recover_flag = card->state; rc = qeth_core_hardsetup_card(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); + QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); rc = -ENODEV; goto out_remove; } @@ -1709,6 +1722,8 @@ static void qeth_bridgeport_query_support(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "brqsuppo"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); + if (!iob) + return; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.sbp.hdr.cmdlength = sizeof(struct qeth_ipacmd_sbp_hdr) + @@ -1784,6 +1799,8 @@ int qeth_bridgeport_query_ports(struct qeth_card *card, if (!(card->options.sbp.supported_funcs & IPA_SBP_QUERY_BRIDGE_PORTS)) return -EOPNOTSUPP; iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.sbp.hdr.cmdlength = sizeof(struct qeth_ipacmd_sbp_hdr); @@ -1796,9 +1813,7 @@ int qeth_bridgeport_query_ports(struct qeth_card *card, if (rc) return rc; rc = qeth_bridgeport_makerc(card, &cbctl, IPA_SBP_QUERY_BRIDGE_PORTS); - if (rc) - return rc; - return 0; + return rc; } EXPORT_SYMBOL_GPL(qeth_bridgeport_query_ports); @@ -1852,6 +1867,8 @@ int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role) if (!(card->options.sbp.supported_funcs & setcmd)) return -EOPNOTSUPP; iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.sbp.hdr.cmdlength = cmdlength; cmd->data.sbp.hdr.command_code = setcmd; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 625227ad..e2a0ee8 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -549,6 +549,8 @@ static int qeth_l3_send_setdelmc(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "setdelmc"); iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); memcpy(&cmd->data.setdelipm.mac, addr->mac, OSA_ADDR_LEN); if (addr->proto == QETH_PROT_IPV6) @@ -588,6 +590,8 @@ static int qeth_l3_send_setdelip(struct qeth_card *card, QETH_CARD_TEXT_(card, 4, "flags%02X", flags); iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); if (addr->proto == QETH_PROT_IPV6) { memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr, @@ -616,6 +620,8 @@ static int qeth_l3_send_setrouting(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "setroutg"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.setrtg.type = (type); rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); @@ -1049,12 +1055,14 @@ static struct qeth_cmd_buffer *qeth_l3_get_setassparms_cmd( QETH_CARD_TEXT(card, 4, "getasscm"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot); - cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); - cmd->data.setassparms.hdr.assist_no = ipa_func; - cmd->data.setassparms.hdr.length = 8 + len; - cmd->data.setassparms.hdr.command_code = cmd_code; - cmd->data.setassparms.hdr.return_code = 0; - cmd->data.setassparms.hdr.seq_no = 0; + if (iob) { + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); + cmd->data.setassparms.hdr.assist_no = ipa_func; + cmd->data.setassparms.hdr.length = 8 + len; + cmd->data.setassparms.hdr.command_code = cmd_code; + cmd->data.setassparms.hdr.return_code = 0; + cmd->data.setassparms.hdr.seq_no = 0; + } return iob; } @@ -1090,6 +1098,8 @@ static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "simassp6"); iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, 0, QETH_PROT_IPV6); + if (!iob) + return -ENOMEM; rc = qeth_l3_send_setassparms(card, iob, 0, 0, qeth_l3_default_setassparms_cb, NULL); return rc; @@ -1108,6 +1118,8 @@ static int qeth_l3_send_simple_setassparms(struct qeth_card *card, length = sizeof(__u32); iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, length, QETH_PROT_IPV4); + if (!iob) + return -ENOMEM; rc = qeth_l3_send_setassparms(card, iob, length, data, qeth_l3_default_setassparms_cb, NULL); return rc; @@ -1494,6 +1506,8 @@ static int qeth_l3_iqd_read_initial_mac(struct qeth_card *card) iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, QETH_PROT_IPV6); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = card->info.unique_id; @@ -1537,6 +1551,8 @@ static int qeth_l3_get_unique_id(struct qeth_card *card) iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, QETH_PROT_IPV6); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = card->info.unique_id; @@ -1611,6 +1627,8 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd) QETH_DBF_TEXT(SETUP, 2, "diagtrac"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.diagass.subcmd_len = 16; cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE; @@ -2442,6 +2460,8 @@ static int qeth_l3_query_arp_cache_info(struct qeth_card *card, IPA_CMD_ASS_ARP_QUERY_INFO, sizeof(struct qeth_arp_query_data) - sizeof(char), prot); + if (!iob) + return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd->data.setassparms.data.query_arp.request_bits = 0x000F; cmd->data.setassparms.data.query_arp.reply_bits = 0; @@ -2535,6 +2555,8 @@ static int qeth_l3_arp_add_entry(struct qeth_card *card, IPA_CMD_ASS_ARP_ADD_ENTRY, sizeof(struct qeth_arp_cache_entry), QETH_PROT_IPV4); + if (!iob) + return -ENOMEM; rc = qeth_l3_send_setassparms(card, iob, sizeof(struct qeth_arp_cache_entry), (unsigned long) entry, @@ -2574,6 +2596,8 @@ static int qeth_l3_arp_remove_entry(struct qeth_card *card, IPA_CMD_ASS_ARP_REMOVE_ENTRY, 12, QETH_PROT_IPV4); + if (!iob) + return -ENOMEM; rc = qeth_l3_send_setassparms(card, iob, 12, (unsigned long)buf, qeth_l3_default_setassparms_cb, NULL); @@ -3262,6 +3286,8 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { static int qeth_l3_setup_netdev(struct qeth_card *card) { + int rc; + if (card->info.type == QETH_CARD_TYPE_OSD || card->info.type == QETH_CARD_TYPE_OSX) { if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || @@ -3293,7 +3319,9 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) return -ENODEV; card->dev->flags |= IFF_NOARP; card->dev->netdev_ops = &qeth_l3_netdev_ops; - qeth_l3_iqd_read_initial_mac(card); + rc = qeth_l3_iqd_read_initial_mac(card); + if (rc) + return rc; if (card->options.hsuid[0]) memcpy(card->dev->perm_addr, card->options.hsuid, 9); } else @@ -3360,7 +3388,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) recover_flag = card->state; rc = qeth_core_hardsetup_card(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); + QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); rc = -ENODEV; goto out_remove; } @@ -3401,7 +3429,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) contin: rc = qeth_l3_setadapter_parms(card); if (rc) - QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); + QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); if (!card->options.sniffer) { rc = qeth_l3_start_ipassists(card); if (rc) { @@ -3410,10 +3438,10 @@ contin: } rc = qeth_l3_setrouting_v4(card); if (rc) - QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); + QETH_DBF_TEXT_(SETUP, 2, "4err%04x", rc); rc = qeth_l3_setrouting_v6(card); if (rc) - QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); + QETH_DBF_TEXT_(SETUP, 2, "5err%04x", rc); } netif_tx_disable(card->dev); -- cgit v0.10.2 From 9879de7373fcfb466ec198293b6ccc1ad7a42dd8 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Mon, 26 Jan 2015 12:58:32 -0800 Subject: mm: page_alloc: embed OOM killing naturally into allocation slowpath The OOM killing invocation does a lot of duplicative checks against the task's allocation context. Rework it to take advantage of the existing checks in the allocator slowpath. The OOM killer is invoked when the allocator is unable to reclaim any pages but the allocation has to keep looping. Instead of having a check for __GFP_NORETRY hidden in oom_gfp_allowed(), just move the OOM invocation to the true branch of should_alloc_retry(). The __GFP_FS check from oom_gfp_allowed() can then be moved into the OOM avoidance branch in __alloc_pages_may_oom(), along with the PF_DUMPCORE test. __alloc_pages_may_oom() can then signal to the caller whether the OOM killer was invoked, instead of requiring it to duplicate the order and high_zoneidx checks to guess this when deciding whether to continue. Signed-off-by: Johannes Weiner Acked-by: Michal Hocko Cc: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/oom.h b/include/linux/oom.h index 853698c..7620098 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -85,11 +85,6 @@ static inline void oom_killer_enable(void) oom_killer_disabled = false; } -static inline bool oom_gfp_allowed(gfp_t gfp_mask) -{ - return (gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY); -} - extern struct task_struct *find_lock_task_mm(struct task_struct *p); static inline bool task_will_free_mem(struct task_struct *task) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7633c50..8e20f9c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2332,12 +2332,21 @@ static inline struct page * __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, enum zone_type high_zoneidx, nodemask_t *nodemask, struct zone *preferred_zone, - int classzone_idx, int migratetype) + int classzone_idx, int migratetype, unsigned long *did_some_progress) { struct page *page; - /* Acquire the per-zone oom lock for each zone */ + *did_some_progress = 0; + + if (oom_killer_disabled) + return NULL; + + /* + * Acquire the per-zone oom lock for each zone. If that + * fails, somebody else is making progress for us. + */ if (!oom_zonelist_trylock(zonelist, gfp_mask)) { + *did_some_progress = 1; schedule_timeout_uninterruptible(1); return NULL; } @@ -2363,12 +2372,18 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, goto out; if (!(gfp_mask & __GFP_NOFAIL)) { + /* Coredumps can quickly deplete all memory reserves */ + if (current->flags & PF_DUMPCORE) + goto out; /* The OOM killer will not help higher order allocs */ if (order > PAGE_ALLOC_COSTLY_ORDER) goto out; /* The OOM killer does not needlessly kill tasks for lowmem */ if (high_zoneidx < ZONE_NORMAL) goto out; + /* The OOM killer does not compensate for light reclaim */ + if (!(gfp_mask & __GFP_FS)) + goto out; /* * GFP_THISNODE contains __GFP_NORETRY and we never hit this. * Sanity check for bare calls of __GFP_THISNODE, not real OOM. @@ -2381,7 +2396,7 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, } /* Exhausted what can be done so it's blamo time */ out_of_memory(zonelist, gfp_mask, order, nodemask, false); - + *did_some_progress = 1; out: oom_zonelist_unlock(zonelist, gfp_mask); return page; @@ -2658,7 +2673,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, (gfp_mask & GFP_THISNODE) == GFP_THISNODE) goto nopage; -restart: +retry: if (!(gfp_mask & __GFP_NO_KSWAPD)) wake_all_kswapds(order, zonelist, high_zoneidx, preferred_zone, nodemask); @@ -2681,7 +2696,6 @@ restart: classzone_idx = zonelist_zone_idx(preferred_zoneref); } -rebalance: /* This is the last chance, in general, before the goto nopage. */ page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS, @@ -2788,54 +2802,28 @@ rebalance: if (page) goto got_pg; - /* - * If we failed to make any progress reclaiming, then we are - * running out of options and have to consider going OOM - */ - if (!did_some_progress) { - if (oom_gfp_allowed(gfp_mask)) { - if (oom_killer_disabled) - goto nopage; - /* Coredumps can quickly deplete all memory reserves */ - if ((current->flags & PF_DUMPCORE) && - !(gfp_mask & __GFP_NOFAIL)) - goto nopage; - page = __alloc_pages_may_oom(gfp_mask, order, - zonelist, high_zoneidx, - nodemask, preferred_zone, - classzone_idx, migratetype); - if (page) - goto got_pg; - - if (!(gfp_mask & __GFP_NOFAIL)) { - /* - * The oom killer is not called for high-order - * allocations that may fail, so if no progress - * is being made, there are no other options and - * retrying is unlikely to help. - */ - if (order > PAGE_ALLOC_COSTLY_ORDER) - goto nopage; - /* - * The oom killer is not called for lowmem - * allocations to prevent needlessly killing - * innocent tasks. - */ - if (high_zoneidx < ZONE_NORMAL) - goto nopage; - } - - goto restart; - } - } - /* Check if we should retry the allocation */ pages_reclaimed += did_some_progress; if (should_alloc_retry(gfp_mask, order, did_some_progress, pages_reclaimed)) { + /* + * If we fail to make progress by freeing individual + * pages, but the allocation wants us to keep going, + * start OOM killing tasks. + */ + if (!did_some_progress) { + page = __alloc_pages_may_oom(gfp_mask, order, zonelist, + high_zoneidx, nodemask, + preferred_zone, classzone_idx, + migratetype,&did_some_progress); + if (page) + goto got_pg; + if (!did_some_progress) + goto nopage; + } /* Wait for some write requests to complete then retry */ wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/50); - goto rebalance; + goto retry; } else { /* * High-order allocations do not necessarily loop after -- cgit v0.10.2 From d69911a68c865b152a067feaa45e98e6bb0f655b Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 26 Jan 2015 12:58:35 -0800 Subject: x86, build: replace Perl script with Shell script Commit e6023367d779 ("x86, kaslr: Prevent .bss from overlaping initrd") added Perl to the required build environment. This reimplements in shell the Perl script used to find the size of the kernel with bss and brk added. Signed-off-by: Kees Cook Reported-by: Rob Landley Acked-by: Rob Landley Cc: Anca Emanuel Cc: Fengguang Wu Cc: Junjie Mao Cc: Kees Cook Cc: Thomas Gleixner Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index d999398..ad754b4 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -90,7 +90,7 @@ suffix-$(CONFIG_KERNEL_LZO) := lzo suffix-$(CONFIG_KERNEL_LZ4) := lz4 RUN_SIZE = $(shell $(OBJDUMP) -h vmlinux | \ - perl $(srctree)/arch/x86/tools/calc_run_size.pl) + $(CONFIG_SHELL) $(srctree)/arch/x86/tools/calc_run_size.sh) quiet_cmd_mkpiggy = MKPIGGY $@ cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false ) diff --git a/arch/x86/tools/calc_run_size.pl b/arch/x86/tools/calc_run_size.pl deleted file mode 100644 index 23210ba..0000000 --- a/arch/x86/tools/calc_run_size.pl +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/perl -# -# Calculate the amount of space needed to run the kernel, including room for -# the .bss and .brk sections. -# -# Usage: -# objdump -h a.out | perl calc_run_size.pl -use strict; - -my $mem_size = 0; -my $file_offset = 0; - -my $sections=" *[0-9]+ \.(?:bss|brk) +"; -while (<>) { - if (/^$sections([0-9a-f]+) +(?:[0-9a-f]+ +){2}([0-9a-f]+)/) { - my $size = hex($1); - my $offset = hex($2); - $mem_size += $size; - if ($file_offset == 0) { - $file_offset = $offset; - } elsif ($file_offset != $offset) { - # BFD linker shows the same file offset in ELF. - # Gold linker shows them as consecutive. - next if ($file_offset + $mem_size == $offset + $size); - - printf STDERR "file_offset: 0x%lx\n", $file_offset; - printf STDERR "mem_size: 0x%lx\n", $mem_size; - printf STDERR "offset: 0x%lx\n", $offset; - printf STDERR "size: 0x%lx\n", $size; - - die ".bss and .brk are non-contiguous\n"; - } - } -} - -if ($file_offset == 0) { - die "Never found .bss or .brk file offset\n"; -} -printf("%d\n", $mem_size + $file_offset); diff --git a/arch/x86/tools/calc_run_size.sh b/arch/x86/tools/calc_run_size.sh new file mode 100644 index 0000000..1a4c17b --- /dev/null +++ b/arch/x86/tools/calc_run_size.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Calculate the amount of space needed to run the kernel, including room for +# the .bss and .brk sections. +# +# Usage: +# objdump -h a.out | sh calc_run_size.sh + +NUM='\([0-9a-fA-F]*[ \t]*\)' +OUT=$(sed -n 's/^[ \t0-9]*.b[sr][sk][ \t]*'"$NUM$NUM$NUM$NUM"'.*/\1\4/p') +if [ -z "$OUT" ] ; then + echo "Never found .bss or .brk file offset" >&2 + exit 1 +fi + +OUT=$(echo ${OUT# }) +sizeA=$(printf "%d" 0x${OUT%% *}) +OUT=${OUT#* } +offsetA=$(printf "%d" 0x${OUT%% *}) +OUT=${OUT#* } +sizeB=$(printf "%d" 0x${OUT%% *}) +OUT=${OUT#* } +offsetB=$(printf "%d" 0x${OUT%% *}) + +run_size=$(( $offsetA + $sizeA + $sizeB )) + +# BFD linker shows the same file offset in ELF. +if [ "$offsetA" -ne "$offsetB" ] ; then + # Gold linker shows them as consecutive. + endB=$(( $offsetB + $sizeB )) + if [ "$endB" != "$run_size" ] ; then + printf "sizeA: 0x%x\n" $sizeA >&2 + printf "offsetA: 0x%x\n" $offsetA >&2 + printf "sizeB: 0x%x\n" $sizeB >&2 + printf "offsetB: 0x%x\n" $offsetB >&2 + echo ".bss and .brk are non-contiguous" >&2 + exit 1 + fi +fi + +printf "%d\n" $run_size +exit 0 -- cgit v0.10.2 From 0346dadbf041a2606bcb5bd27828b0d105897f4a Mon Sep 17 00:00:00 2001 From: Greg Thelen Date: Mon, 26 Jan 2015 12:58:38 -0800 Subject: memcg: remove extra newlines from memcg oom kill log Commit e61734c55c24 ("cgroup: remove cgroup->name") added two extra newlines to memcg oom kill log messages. This makes dmesg hard to read and parse. The issue affects 3.15+. Example: Task in /t <<< extra #1 killed as a result of limit of /t <<< extra #2 memory: usage 102400kB, limit 102400kB, failcnt 274712 Remove the extra newlines from memcg oom kill messages, so the messages look like: Task in /t killed as a result of limit of /t memory: usage 102400kB, limit 102400kB, failcnt 240649 Fixes: e61734c55c24 ("cgroup: remove cgroup->name") Signed-off-by: Greg Thelen Acked-by: Michal Hocko Acked-by: Johannes Weiner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 851924f..683b478 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1477,9 +1477,9 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) pr_info("Task in "); pr_cont_cgroup_path(task_cgroup(p, memory_cgrp_id)); - pr_info(" killed as a result of limit of "); + pr_cont(" killed as a result of limit of "); pr_cont_cgroup_path(memcg->css.cgroup); - pr_info("\n"); + pr_cont("\n"); rcu_read_unlock(); -- cgit v0.10.2 From 17636faada9c2f6696feafd633c5857ccf7ed0cd Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 26 Jan 2015 12:58:41 -0800 Subject: mm/vmscan: fix highidx argument type for_each_zone_zonelist_nodemask wants an enum zone_type argument, but is passed gfp_t: mm/vmscan.c:2658:9: expected int enum zone_type [signed] highest_zoneidx mm/vmscan.c:2658:9: got restricted gfp_t [usertype] gfp_mask mm/vmscan.c:2658:9: warning: incorrect type in argument 2 (different base types) mm/vmscan.c:2658:9: expected int enum zone_type [signed] highest_zoneidx mm/vmscan.c:2658:9: got restricted gfp_t [usertype] gfp_mask convert argument to the correct type. Signed-off-by: Michael S. Tsirkin Cc: Johannes Weiner Cc: Vladimir Davydov Cc: Rik van Riel Cc: Michal Hocko Cc: Mel Gorman Cc: Vlastimil Babka Cc: Suleiman Souhlal Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/vmscan.c b/mm/vmscan.c index ab2505c..dcd90c8 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2656,7 +2656,7 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, * should make reasonable progress. */ for_each_zone_zonelist_nodemask(zone, z, zonelist, - gfp_mask, nodemask) { + gfp_zone(gfp_mask), nodemask) { if (zone_idx(zone) > ZONE_NORMAL) continue; -- cgit v0.10.2 From 07261edb971492c6b41b44d7b1b51f76807d30ad Mon Sep 17 00:00:00 2001 From: Pranith Kumar Date: Mon, 26 Jan 2015 12:58:43 -0800 Subject: printk: add dummy routine for when CONFIG_PRINTK=n There are missing dummy routines for log_buf_addr_get() and log_buf_len_get() for when CONFIG_PRINTK is not set causing build failures. This patch adds these dummy routines at the appropriate location. Signed-off-by: Pranith Kumar Cc: Michael Ellerman Reviewed-by: Petr Mladek Acked-by: Steven Rostedt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/printk.h b/include/linux/printk.h index c8f1703..4d5bf57 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -10,9 +10,6 @@ extern const char linux_banner[]; extern const char linux_proc_banner[]; -extern char *log_buf_addr_get(void); -extern u32 log_buf_len_get(void); - static inline int printk_get_level(const char *buffer) { if (buffer[0] == KERN_SOH_ASCII && buffer[1]) { @@ -163,6 +160,8 @@ extern int kptr_restrict; extern void wake_up_klogd(void); +char *log_buf_addr_get(void); +u32 log_buf_len_get(void); void log_buf_kexec_setup(void); void __init setup_log_buf(int early); void dump_stack_set_arch_desc(const char *fmt, ...); @@ -198,6 +197,16 @@ static inline void wake_up_klogd(void) { } +static inline char *log_buf_addr_get(void) +{ + return NULL; +} + +static inline u32 log_buf_len_get(void) +{ + return 0; +} + static inline void log_buf_kexec_setup(void) { } -- cgit v0.10.2 From 45cd15e600ec8006305ce83f62c7208c2cb7a052 Mon Sep 17 00:00:00 2001 From: Andrey Ryabinin Date: Mon, 26 Jan 2015 12:58:46 -0800 Subject: drivers/rtc/rtc-s5m.c: terminate s5m_rtc_id array with empty element Array of platform_device_id elements should be terminated with empty element. Fixes: 5bccae6ec458 ("rtc: s5m-rtc: add real-time clock driver for s5m8767") Signed-off-by: Andrey Ryabinin Reviewed-by: Krzysztof Kozlowski Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index b5e7c46..89ac1d5 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -832,6 +832,7 @@ static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume); static const struct platform_device_id s5m_rtc_id[] = { { "s5m-rtc", S5M8767X }, { "s2mps14-rtc", S2MPS14X }, + { }, }; static struct platform_driver s5m_rtc_driver = { -- cgit v0.10.2 From 7913ecf69e24bd7575e0d0325eda3b43c8cfa749 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Thu, 22 Jan 2015 10:41:01 +0100 Subject: net: cls_bpf: fix size mismatch on filter preparation In cls_bpf_modify_existing(), we read out the number of filter blocks, do some sanity checks, allocate a block on that size, and copy over the BPF instruction blob from user space, then pass everything through the classic BPF checker prior to installation of the classifier. We should reject mismatches here, there are 2 scenarios: the number of filter blocks could be smaller than the provided instruction blob, so we do a partial copy of the BPF program, and thus the instructions will either be rejected from the verifier or a valid BPF program will be run; in the other case, we'll end up copying more than we're supposed to, and most likely the trailing garbage will be rejected by the verifier as well (i.e. we need to fit instruction pattern, ret {A,K} needs to be last instruction, load/stores must be correct, etc); in case not, we would leak memory when dumping back instruction patterns. The code should have only used nla_len() as Dave noted to avoid this from the beginning. Anyway, lets fix it by rejecting such load attempts. Fixes: 7d1d65cb84e1 ("net: sched: cls_bpf: add BPF-based classifier") Signed-off-by: Daniel Borkmann Acked-by: Jiri Pirko Signed-off-by: David S. Miller diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index 84c8219..49e5fa8 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -180,6 +180,11 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp, } bpf_size = bpf_len * sizeof(*bpf_ops); + if (bpf_size != nla_len(tb[TCA_BPF_OPS])) { + ret = -EINVAL; + goto errout; + } + bpf_ops = kzalloc(bpf_size, GFP_KERNEL); if (bpf_ops == NULL) { ret = -ENOMEM; -- cgit v0.10.2 From 3f2ab135946dcd4eb6af92a53d6d4bd35e7526ca Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Thu, 22 Jan 2015 10:41:02 +0100 Subject: net: cls_bpf: fix auto generation of per list handles When creating a bpf classifier in tc with priority collisions and invoking automatic unique handle assignment, cls_bpf_grab_new_handle() will return a wrong handle id which in fact is non-unique. Usually altering of specific filters is being addressed over major id, but in case of collisions we result in a filter chain, where handle ids address individual cls_bpf_progs inside the classifier. Issue is, in cls_bpf_grab_new_handle() we probe for head->hgen handle in cls_bpf_get() and in case we found a free handle, we're supposed to use exactly head->hgen. In case of insufficient numbers of handles, we bail out later as handle id 0 is not allowed. Fixes: 7d1d65cb84e1 ("net: sched: cls_bpf: add BPF-based classifier") Signed-off-by: Daniel Borkmann Acked-by: Jiri Pirko Acked-by: Alexei Starovoitov Signed-off-by: David S. Miller diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index 49e5fa8..f59adf8 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -220,15 +220,21 @@ static u32 cls_bpf_grab_new_handle(struct tcf_proto *tp, struct cls_bpf_head *head) { unsigned int i = 0x80000000; + u32 handle; do { if (++head->hgen == 0x7FFFFFFF) head->hgen = 1; } while (--i > 0 && cls_bpf_get(tp, head->hgen)); - if (i == 0) + + if (unlikely(i == 0)) { pr_err("Insufficient number of handles\n"); + handle = 0; + } else { + handle = head->hgen; + } - return i; + return handle; } static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, -- cgit v0.10.2 From 02a54164c52ed6eca3089a0d402170fbf34d6cf5 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Thu, 22 Jan 2015 15:19:22 +0530 Subject: drivers: net: cpsw: discard dual emac default vlan configuration In Dual EMAC, the default VLANs are used to segregate Rx packets between the ports, so adding the same default VLAN to the switch will affect the normal packet transfers. So returning error on addition of dual EMAC default VLANs. Even if EMAC 0 default port VLAN is added to EMAC 1, it will lead to break dual EMAC port separations. Fixes: d9ba8f9e6298 (driver: net: ethernet: cpsw: dual emac interface implementation) Cc: # v3.9+ Reported-by: Felipe Balbi Signed-off-by: Mugunthan V N Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index e068d48..a39131f 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -1683,6 +1683,19 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, if (vid == priv->data.default_vlan) return 0; + if (priv->data.dual_emac) { + /* In dual EMAC, reserved VLAN id should not be used for + * creating VLAN interfaces as this can break the dual + * EMAC port separation + */ + int i; + + for (i = 0; i < priv->data.slaves; i++) { + if (vid == priv->slaves[i].port_vlan) + return -EINVAL; + } + } + dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid); return cpsw_add_vlan_ale_entry(priv, vid); } @@ -1696,6 +1709,15 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, if (vid == priv->data.default_vlan) return 0; + if (priv->data.dual_emac) { + int i; + + for (i = 0; i < priv->data.slaves; i++) { + if (vid == priv->slaves[i].port_vlan) + return -EINVAL; + } + } + dev_info(priv->dev, "removing vlanid %d from vlan filter\n", vid); ret = cpsw_ale_del_vlan(priv->ale, vid, 0); if (ret != 0) -- cgit v0.10.2 From eebfb643c0799ecb98ba77d4a0dd0e56f6a17553 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 22 Jan 2015 12:40:13 +0000 Subject: sh_eth: Fix padding of short frames on TX If an skb to be transmitted is shorter than the minimum Ethernet frame length, we currently set the DMA descriptor length to the minimum but do not add zero-padding. This could result in leaking sensitive data. We also pass different lengths to dma_map_single() and dma_unmap_single(). Use skb_padto() to pad properly, before calling dma_map_single(). Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 6576243..4ae22fc 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2117,6 +2117,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) } spin_unlock_irqrestore(&mdp->lock, flags); + if (skb_padto(skb, ETH_ZLEN)) + return NETDEV_TX_OK; + entry = mdp->cur_tx % mdp->num_tx_ring; mdp->tx_skbuff[entry] = skb; txdesc = &mdp->tx_ring[entry]; @@ -2126,10 +2129,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) skb->len + 2); txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (skb->len < ETH_ZLEN) - txdesc->buffer_length = ETH_ZLEN; - else - txdesc->buffer_length = skb->len; + txdesc->buffer_length = skb->len; if (entry >= mdp->num_tx_ring - 1) txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE); -- cgit v0.10.2 From bd8889163a7f392f89de5bb01ad00f5772c7ea25 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 22 Jan 2015 12:40:25 +0000 Subject: sh_eth: Detach net device when stopping queue to resize DMA rings We must only ever stop TX queues when they are full or the net device is not 'ready' so far as the net core, and specifically the watchdog, is concerned. Otherwise, the watchdog may fire *immediately* if no packets have been added to the queue in the last 5 seconds. What's more, sh_eth_tx_timeout() will likely crash if called while we're resizing the TX ring. I could easily trigger this by running the loop: while ethtool -G eth0 rx 128 && ethtool -G eth0 rx 64; do echo -n .; done Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 4ae22fc..fa8a7b7 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1968,6 +1968,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev, return -EINVAL; if (netif_running(ndev)) { + netif_device_detach(ndev); netif_tx_disable(ndev); /* Disable interrupts by clearing the interrupt mask. */ sh_eth_write(ndev, 0x0000, EESIPR); @@ -2001,7 +2002,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev, 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_wake_queue(ndev); + netif_device_attach(ndev); } return 0; -- cgit v0.10.2 From 084236d8c53952f14b5cb1741311c80c7fbe8289 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 22 Jan 2015 12:41:34 +0000 Subject: sh_eth: Fix crash or memory leak when resizing rings on device that is down If the device is down then no packet buffers should be allocated. We also must not touch its registers as it may be powered off. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index fa8a7b7..7facda1 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1976,29 +1976,31 @@ static int sh_eth_set_ringparam(struct net_device *ndev, sh_eth_write(ndev, 0, EDTRR); sh_eth_write(ndev, 0, EDRRR); synchronize_irq(ndev->irq); - } - /* Free all the skbuffs in the Rx queue. */ - sh_eth_ring_free(ndev); - /* Free DMA buffer */ - sh_eth_free_dma_buffer(mdp); + /* Free all the skbuffs in the Rx queue. */ + sh_eth_ring_free(ndev); + /* Free DMA buffer */ + sh_eth_free_dma_buffer(mdp); + } /* Set new parameters */ mdp->num_rx_ring = ring->rx_pending; mdp->num_tx_ring = ring->tx_pending; - ret = sh_eth_ring_init(ndev); - if (ret < 0) { - netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", __func__); - return ret; - } - ret = sh_eth_dev_init(ndev, false); - if (ret < 0) { - netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", __func__); - return ret; - } - if (netif_running(ndev)) { + ret = sh_eth_ring_init(ndev); + if (ret < 0) { + netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", + __func__); + return ret; + } + ret = sh_eth_dev_init(ndev, false); + if (ret < 0) { + netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", + __func__); + return ret; + } + 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); -- cgit v0.10.2 From 283e38db65e77be9bbe2d455452584ee7834e4e9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 22 Jan 2015 12:44:08 +0000 Subject: sh_eth: Fix serialisation of interrupt disable with interrupt & NAPI handlers In order to stop the RX path accessing the RX ring while it's being stopped or resized, we clear the interrupt mask (EESIPR) and then call free_irq() or synchronise_irq(). This is insufficient because the interrupt handler or NAPI poller may set EESIPR again after we clear it. Also, in sh_eth_set_ringparam() we currently don't disable NAPI polling at all. I could easily trigger a crash by running the loop: while ethtool -G eth0 rx 128 && ethtool -G eth0 rx 64; do echo -n .; done and 'ping -f' toward the sh_eth port from another machine. To fix this: - Add a software flag (irq_enabled) to signal whether interrupts should be enabled - In the interrupt handler, if the flag is clear then clear EESIPR and return - In the NAPI poller, if the flag is clear then don't set EESIPR - Set the flag before enabling interrupts in sh_eth_dev_init() and sh_eth_set_ringparam() - Clear the flag and serialise with the interrupt and NAPI handlers before clearing EESIPR in sh_eth_close() and sh_eth_set_ringparam() After this, I could run the loop for 100,000 iterations successfully. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 7facda1..99a838d 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1316,8 +1316,10 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) RFLR); sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); - if (start) + if (start) { + mdp->irq_enabled = true; sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); + } /* PAUSE Prohibition */ val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | @@ -1653,7 +1655,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check)) ret = IRQ_HANDLED; else - goto other_irq; + goto out; + + if (!likely(mdp->irq_enabled)) { + sh_eth_write(ndev, 0, EESIPR); + goto out; + } if (intr_status & EESR_RX_CHECK) { if (napi_schedule_prep(&mdp->napi)) { @@ -1684,7 +1691,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) sh_eth_error(ndev, intr_status); } -other_irq: +out: spin_unlock(&mdp->lock); return ret; @@ -1712,7 +1719,8 @@ static int sh_eth_poll(struct napi_struct *napi, int budget) napi_complete(napi); /* Reenable Rx interrupts */ - sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); + if (mdp->irq_enabled) + sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); out: return budget - quota; } @@ -1970,12 +1978,20 @@ static int sh_eth_set_ringparam(struct net_device *ndev, if (netif_running(ndev)) { netif_device_detach(ndev); netif_tx_disable(ndev); - /* Disable interrupts by clearing the interrupt mask. */ + + /* Serialise with the interrupt handler and NAPI, then + * disable interrupts. We have to clear the + * irq_enabled flag first to ensure that interrupts + * won't be re-enabled. + */ + mdp->irq_enabled = false; + synchronize_irq(ndev->irq); + napi_synchronize(&mdp->napi); sh_eth_write(ndev, 0x0000, EESIPR); + /* Stop the chip's Tx and Rx processes. */ sh_eth_write(ndev, 0, EDTRR); sh_eth_write(ndev, 0, EDRRR); - synchronize_irq(ndev->irq); /* Free all the skbuffs in the Rx queue. */ sh_eth_ring_free(ndev); @@ -2001,6 +2017,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev, 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); @@ -2184,7 +2201,13 @@ static int sh_eth_close(struct net_device *ndev) netif_stop_queue(ndev); - /* Disable interrupts by clearing the interrupt mask. */ + /* Serialise with the interrupt handler and NAPI, then disable + * interrupts. We have to clear the irq_enabled flag first to + * ensure that interrupts won't be re-enabled. + */ + mdp->irq_enabled = false; + synchronize_irq(ndev->irq); + napi_disable(&mdp->napi); sh_eth_write(ndev, 0x0000, EESIPR); /* Stop the chip's Tx and Rx processes. */ @@ -2201,8 +2224,6 @@ static int sh_eth_close(struct net_device *ndev) free_irq(ndev->irq, ndev); - napi_disable(&mdp->napi); - /* Free all the skbuffs in the Rx queue. */ sh_eth_ring_free(ndev); diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 71f5de1..332d3c1 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -513,6 +513,7 @@ struct sh_eth_private { u32 rx_buf_sz; /* Based on MTU+slack. */ int edmac_endian; struct napi_struct napi; + bool irq_enabled; /* MII transceiver section. */ u32 phy_id; /* PHY ID */ struct mii_bus *mii_bus; /* MDIO bus control */ -- cgit v0.10.2 From 9e911414af8caf20d064fe97e946f1a54f110e69 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 22 Jan 2015 11:33:02 -0300 Subject: net: mv643xx_eth: Fix highmem support in non-TSO egress path Commit 69ad0dd7af22b61d9e0e68e56b6290121618b0fb Author: Ezequiel Garcia Date: Mon May 19 13:59:59 2014 -0300 net: mv643xx_eth: Use dma_map_single() to map the skb fragments caused a nasty regression by removing the support for highmem skb fragments. By using page_address() to get the address of a fragment's page, we are assuming a lowmem page. However, such assumption is incorrect, as fragments can be in highmem pages, resulting in very nasty issues. This commit fixes this by using the skb_frag_dma_map() helper, which takes care of mapping the skb fragment properly. Additionally, the type of mapping is now tracked, so it can be unmapped using dma_unmap_page or dma_unmap_single when appropriate. This commit also fixes the error path in txq_init() to release the resources properly. Fixes: 69ad0dd7af22 ("net: mv643xx_eth: Use dma_map_single() to map the skb fragments") Reported-by: Russell King Signed-off-by: Ezequiel Garcia Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index a62fc38..1c75829 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -192,6 +192,10 @@ static char mv643xx_eth_driver_version[] = "1.4"; #define IS_TSO_HEADER(txq, addr) \ ((addr >= txq->tso_hdrs_dma) && \ (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE)) + +#define DESC_DMA_MAP_SINGLE 0 +#define DESC_DMA_MAP_PAGE 1 + /* * RX/TX descriptors. */ @@ -362,6 +366,7 @@ struct tx_queue { dma_addr_t tso_hdrs_dma; struct tx_desc *tx_desc_area; + char *tx_desc_mapping; /* array to track the type of the dma mapping */ dma_addr_t tx_desc_dma; int tx_desc_area_size; @@ -750,6 +755,7 @@ txq_put_data_tso(struct net_device *dev, struct tx_queue *txq, if (txq->tx_curr_desc == txq->tx_ring_size) txq->tx_curr_desc = 0; desc = &txq->tx_desc_area[tx_index]; + txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE; desc->l4i_chk = 0; desc->byte_cnt = length; @@ -879,14 +885,13 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) skb_frag_t *this_frag; int tx_index; struct tx_desc *desc; - void *addr; this_frag = &skb_shinfo(skb)->frags[frag]; - addr = page_address(this_frag->page.p) + this_frag->page_offset; tx_index = txq->tx_curr_desc++; if (txq->tx_curr_desc == txq->tx_ring_size) txq->tx_curr_desc = 0; desc = &txq->tx_desc_area[tx_index]; + txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_PAGE; /* * The last fragment will generate an interrupt @@ -902,8 +907,9 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) desc->l4i_chk = 0; desc->byte_cnt = skb_frag_size(this_frag); - desc->buf_ptr = dma_map_single(mp->dev->dev.parent, addr, - desc->byte_cnt, DMA_TO_DEVICE); + desc->buf_ptr = skb_frag_dma_map(mp->dev->dev.parent, + this_frag, 0, desc->byte_cnt, + DMA_TO_DEVICE); } } @@ -936,6 +942,7 @@ static int txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb, if (txq->tx_curr_desc == txq->tx_ring_size) txq->tx_curr_desc = 0; desc = &txq->tx_desc_area[tx_index]; + txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE; if (nr_frags) { txq_submit_frag_skb(txq, skb); @@ -1047,9 +1054,12 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) int tx_index; struct tx_desc *desc; u32 cmd_sts; + char desc_dma_map; tx_index = txq->tx_used_desc; desc = &txq->tx_desc_area[tx_index]; + desc_dma_map = txq->tx_desc_mapping[tx_index]; + cmd_sts = desc->cmd_sts; if (cmd_sts & BUFFER_OWNED_BY_DMA) { @@ -1065,9 +1075,19 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) reclaimed++; txq->tx_desc_count--; - if (!IS_TSO_HEADER(txq, desc->buf_ptr)) - dma_unmap_single(mp->dev->dev.parent, desc->buf_ptr, - desc->byte_cnt, DMA_TO_DEVICE); + if (!IS_TSO_HEADER(txq, desc->buf_ptr)) { + + if (desc_dma_map == DESC_DMA_MAP_PAGE) + dma_unmap_page(mp->dev->dev.parent, + desc->buf_ptr, + desc->byte_cnt, + DMA_TO_DEVICE); + else + dma_unmap_single(mp->dev->dev.parent, + desc->buf_ptr, + desc->byte_cnt, + DMA_TO_DEVICE); + } if (cmd_sts & TX_ENABLE_INTERRUPT) { struct sk_buff *skb = __skb_dequeue(&txq->tx_skb); @@ -1996,6 +2016,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) struct tx_queue *txq = mp->txq + index; struct tx_desc *tx_desc; int size; + int ret; int i; txq->index = index; @@ -2048,18 +2069,34 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) nexti * sizeof(struct tx_desc); } + txq->tx_desc_mapping = kcalloc(txq->tx_ring_size, sizeof(char), + GFP_KERNEL); + if (!txq->tx_desc_mapping) { + ret = -ENOMEM; + goto err_free_desc_area; + } + /* Allocate DMA buffers for TSO MAC/IP/TCP headers */ txq->tso_hdrs = dma_alloc_coherent(mp->dev->dev.parent, txq->tx_ring_size * TSO_HEADER_SIZE, &txq->tso_hdrs_dma, GFP_KERNEL); if (txq->tso_hdrs == NULL) { - dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, - txq->tx_desc_area, txq->tx_desc_dma); - return -ENOMEM; + ret = -ENOMEM; + goto err_free_desc_mapping; } skb_queue_head_init(&txq->tx_skb); return 0; + +err_free_desc_mapping: + kfree(txq->tx_desc_mapping); +err_free_desc_area: + if (index == 0 && size <= mp->tx_desc_sram_size) + iounmap(txq->tx_desc_area); + else + dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, + txq->tx_desc_area, txq->tx_desc_dma); + return ret; } static void txq_deinit(struct tx_queue *txq) @@ -2077,6 +2114,8 @@ static void txq_deinit(struct tx_queue *txq) else dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, txq->tx_desc_area, txq->tx_desc_dma); + kfree(txq->tx_desc_mapping); + if (txq->tso_hdrs) dma_free_coherent(mp->dev->dev.parent, txq->tx_ring_size * TSO_HEADER_SIZE, -- cgit v0.10.2 From 600ddd6825543962fb807884169e57b580dba208 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Thu, 22 Jan 2015 18:26:54 +0100 Subject: net: sctp: fix slab corruption from use after free on INIT collisions When hitting an INIT collision case during the 4WHS with AUTH enabled, as already described in detail in commit 1be9a950c646 ("net: sctp: inherit auth_capable on INIT collisions"), it can happen that we occasionally still remotely trigger the following panic on server side which seems to have been uncovered after the fix from commit 1be9a950c646 ... [ 533.876389] BUG: unable to handle kernel paging request at 00000000ffffffff [ 533.913657] IP: [] __kmalloc+0x95/0x230 [ 533.940559] PGD 5030f2067 PUD 0 [ 533.957104] Oops: 0000 [#1] SMP [ 533.974283] Modules linked in: sctp mlx4_en [...] [ 534.939704] Call Trace: [ 534.951833] [] ? crypto_init_shash_ops+0x60/0xf0 [ 534.984213] [] crypto_init_shash_ops+0x60/0xf0 [ 535.015025] [] __crypto_alloc_tfm+0x6d/0x170 [ 535.045661] [] crypto_alloc_base+0x4c/0xb0 [ 535.074593] [] ? _raw_spin_lock_bh+0x12/0x50 [ 535.105239] [] sctp_inet_listen+0x161/0x1e0 [sctp] [ 535.138606] [] SyS_listen+0x9d/0xb0 [ 535.166848] [] system_call_fastpath+0x16/0x1b ... or depending on the the application, for example this one: [ 1370.026490] BUG: unable to handle kernel paging request at 00000000ffffffff [ 1370.026506] IP: [] kmem_cache_alloc+0x75/0x1d0 [ 1370.054568] PGD 633c94067 PUD 0 [ 1370.070446] Oops: 0000 [#1] SMP [ 1370.085010] Modules linked in: sctp kvm_amd kvm [...] [ 1370.963431] Call Trace: [ 1370.974632] [] ? SyS_epoll_ctl+0x53f/0x960 [ 1371.000863] [] SyS_epoll_ctl+0x53f/0x960 [ 1371.027154] [] ? anon_inode_getfile+0xd3/0x170 [ 1371.054679] [] ? __alloc_fd+0xa7/0x130 [ 1371.080183] [] system_call_fastpath+0x16/0x1b With slab debugging enabled, we can see that the poison has been overwritten: [ 669.826368] BUG kmalloc-128 (Tainted: G W ): Poison overwritten [ 669.826385] INFO: 0xffff880228b32e50-0xffff880228b32e50. First byte 0x6a instead of 0x6b [ 669.826414] INFO: Allocated in sctp_auth_create_key+0x23/0x50 [sctp] age=3 cpu=0 pid=18494 [ 669.826424] __slab_alloc+0x4bf/0x566 [ 669.826433] __kmalloc+0x280/0x310 [ 669.826453] sctp_auth_create_key+0x23/0x50 [sctp] [ 669.826471] sctp_auth_asoc_create_secret+0xcb/0x1e0 [sctp] [ 669.826488] sctp_auth_asoc_init_active_key+0x68/0xa0 [sctp] [ 669.826505] sctp_do_sm+0x29d/0x17c0 [sctp] [...] [ 669.826629] INFO: Freed in kzfree+0x31/0x40 age=1 cpu=0 pid=18494 [ 669.826635] __slab_free+0x39/0x2a8 [ 669.826643] kfree+0x1d6/0x230 [ 669.826650] kzfree+0x31/0x40 [ 669.826666] sctp_auth_key_put+0x19/0x20 [sctp] [ 669.826681] sctp_assoc_update+0x1ee/0x2d0 [sctp] [ 669.826695] sctp_do_sm+0x674/0x17c0 [sctp] Since this only triggers in some collision-cases with AUTH, the problem at heart is that sctp_auth_key_put() on asoc->asoc_shared_key is called twice when having refcnt 1, once directly in sctp_assoc_update() and yet again from within sctp_auth_asoc_init_active_key() via sctp_assoc_update() on the already kzfree'd memory, which is also consistent with the observation of the poison decrease from 0x6b to 0x6a (note: the overwrite is detected at a later point in time when poison is checked on new allocation). Reference counting of auth keys revisited: Shared keys for AUTH chunks are being stored in endpoints and associations in endpoint_shared_keys list. On endpoint creation, a null key is being added; on association creation, all endpoint shared keys are being cached and thus cloned over to the association. struct sctp_shared_key only holds a pointer to the actual key bytes, that is, struct sctp_auth_bytes which keeps track of users internally through refcounting. Naturally, on assoc or enpoint destruction, sctp_shared_key are being destroyed directly and the reference on sctp_auth_bytes dropped. User space can add keys to either list via setsockopt(2) through struct sctp_authkey and by passing that to sctp_auth_set_key() which replaces or adds a new auth key. There, sctp_auth_create_key() creates a new sctp_auth_bytes with refcount 1 and in case of replacement drops the reference on the old sctp_auth_bytes. A key can be set active from user space through setsockopt() on the id via sctp_auth_set_active_key(), which iterates through either endpoint_shared_keys and in case of an assoc, invokes (one of various places) sctp_auth_asoc_init_active_key(). sctp_auth_asoc_init_active_key() computes the actual secret from local's and peer's random, hmac and shared key parameters and returns a new key directly as sctp_auth_bytes, that is asoc->asoc_shared_key, plus drops the reference if there was a previous one. The secret, which where we eventually double drop the ref comes from sctp_auth_asoc_set_secret() with intitial refcount of 1, which also stays unchanged eventually in sctp_assoc_update(). This key is later being used for crypto layer to set the key for the hash in crypto_hash_setkey() from sctp_auth_calculate_hmac(). To close the loop: asoc->asoc_shared_key is freshly allocated secret material and independant of the sctp_shared_key management keeping track of only shared keys in endpoints and assocs. Hence, also commit 4184b2a79a76 ("net: sctp: fix memory leak in auth key management") is independant of this bug here since it concerns a different layer (though same structures being used eventually). asoc->asoc_shared_key is reference dropped correctly on assoc destruction in sctp_association_free() and when active keys are being replaced in sctp_auth_asoc_init_active_key(), it always has a refcount of 1. Hence, it's freed prematurely in sctp_assoc_update(). Simple fix is to remove that sctp_auth_key_put() from there which fixes these panics. Fixes: 730fc3d05cd4 ("[SCTP]: Implete SCTP-AUTH parameter processing") Signed-off-by: Daniel Borkmann Acked-by: Vlad Yasevich Acked-by: Neil Horman Signed-off-by: David S. Miller diff --git a/net/sctp/associola.c b/net/sctp/associola.c index f791edd..26d06db 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -1182,7 +1182,6 @@ void sctp_assoc_update(struct sctp_association *asoc, asoc->peer.peer_hmacs = new->peer.peer_hmacs; new->peer.peer_hmacs = NULL; - sctp_auth_key_put(asoc->asoc_shared_key); sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC); } -- cgit v0.10.2 From 8ebe667c41e054384df19f2f382bc415badfaee1 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 22 Jan 2015 17:11:08 -0800 Subject: bpf: rcu lock must not be held when calling copy_to_user() BUG: sleeping function called from invalid context at mm/memory.c:3732 in_atomic(): 0, irqs_disabled(): 0, pid: 671, name: test_maps 1 lock held by test_maps/671: #0: (rcu_read_lock){......}, at: [<0000000000264190>] map_lookup_elem+0xe8/0x260 Call Trace: ([<0000000000115b7e>] show_trace+0x12e/0x150) [<0000000000115c40>] show_stack+0xa0/0x100 [<00000000009b163c>] dump_stack+0x74/0xc8 [<000000000017424a>] ___might_sleep+0x23a/0x248 [<00000000002b58e8>] might_fault+0x70/0xe8 [<0000000000264230>] map_lookup_elem+0x188/0x260 [<0000000000264716>] SyS_bpf+0x20e/0x840 Fix it by allocating temporary buffer to store map element value. Fixes: db20fd2b0108 ("bpf: add lookup/update/delete/iterate methods to BPF maps") Reported-by: Michael Holzheu Signed-off-by: Alexei Starovoitov Acked-by: Daniel Borkmann Signed-off-by: David S. Miller diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 088ac0b..536edc2 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -150,7 +150,7 @@ static int map_lookup_elem(union bpf_attr *attr) int ufd = attr->map_fd; struct fd f = fdget(ufd); struct bpf_map *map; - void *key, *value; + void *key, *value, *ptr; int err; if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM)) @@ -169,20 +169,29 @@ static int map_lookup_elem(union bpf_attr *attr) if (copy_from_user(key, ukey, map->key_size) != 0) goto free_key; - err = -ENOENT; - rcu_read_lock(); - value = map->ops->map_lookup_elem(map, key); + err = -ENOMEM; + value = kmalloc(map->value_size, GFP_USER); if (!value) - goto err_unlock; + goto free_key; + + rcu_read_lock(); + ptr = map->ops->map_lookup_elem(map, key); + if (ptr) + memcpy(value, ptr, map->value_size); + rcu_read_unlock(); + + err = -ENOENT; + if (!ptr) + goto free_value; err = -EFAULT; if (copy_to_user(uvalue, value, map->value_size) != 0) - goto err_unlock; + goto free_value; err = 0; -err_unlock: - rcu_read_unlock(); +free_value: + kfree(value); free_key: kfree(key); err_put: -- cgit v0.10.2 From ba1a68bf1308a71a07d2462f4c38c242e08f92ba Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 22 Jan 2015 17:11:09 -0800 Subject: samples: bpf: relax test_maps check hash map is unordered, so get_next_key() iterator shouldn't rely on particular order of elements. So relax this test. Fixes: ffb65f27a155 ("bpf: add a testsuite for eBPF maps") Reported-by: Michael Holzheu Signed-off-by: Alexei Starovoitov Acked-by: Daniel Borkmann Signed-off-by: David S. Miller diff --git a/samples/bpf/test_maps.c b/samples/bpf/test_maps.c index e286b42..6299ee9 100644 --- a/samples/bpf/test_maps.c +++ b/samples/bpf/test_maps.c @@ -69,9 +69,9 @@ static void test_hashmap_sanity(int i, void *data) /* iterate over two elements */ assert(bpf_get_next_key(map_fd, &key, &next_key) == 0 && - next_key == 2); + (next_key == 1 || next_key == 2)); assert(bpf_get_next_key(map_fd, &next_key, &next_key) == 0 && - next_key == 1); + (next_key == 1 || next_key == 2)); assert(bpf_get_next_key(map_fd, &next_key, &next_key) == -1 && errno == ENOENT); -- cgit v0.10.2 From df4d92549f23e1c037e83323aff58a21b3de7fe0 Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Fri, 23 Jan 2015 12:01:26 +0100 Subject: ipv4: try to cache dst_entries which would cause a redirect Not caching dst_entries which cause redirects could be exploited by hosts on the same subnet, causing a severe DoS attack. This effect aggravated since commit f88649721268999 ("ipv4: fix dst race in sk_dst_get()"). Lookups causing redirects will be allocated with DST_NOCACHE set which will force dst_release to free them via RCU. Unfortunately waiting for RCU grace period just takes too long, we can end up with >1M dst_entries waiting to be released and the system will run OOM. rcuos threads cannot catch up under high softirq load. Attaching the flag to emit a redirect later on to the specific skb allows us to cache those dst_entries thus reducing the pressure on allocation and deallocation. This issue was discovered by Marcelo Leitner. Cc: Julian Anastasov Signed-off-by: Marcelo Leitner Signed-off-by: Florian Westphal Signed-off-by: Hannes Frederic Sowa Signed-off-by: Julian Anastasov Signed-off-by: David S. Miller diff --git a/include/net/ip.h b/include/net/ip.h index 0bb6207..f7cbd70 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -39,11 +39,12 @@ struct inet_skb_parm { struct ip_options opt; /* Compiled IP options */ unsigned char flags; -#define IPSKB_FORWARDED 1 -#define IPSKB_XFRM_TUNNEL_SIZE 2 -#define IPSKB_XFRM_TRANSFORMED 4 -#define IPSKB_FRAG_COMPLETE 8 -#define IPSKB_REROUTED 16 +#define IPSKB_FORWARDED BIT(0) +#define IPSKB_XFRM_TUNNEL_SIZE BIT(1) +#define IPSKB_XFRM_TRANSFORMED BIT(2) +#define IPSKB_FRAG_COMPLETE BIT(3) +#define IPSKB_REROUTED BIT(4) +#define IPSKB_DOREDIRECT BIT(5) u16 frag_max_size; }; diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index 3a83ce5..787b3c2 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -129,7 +129,8 @@ int ip_forward(struct sk_buff *skb) * We now generate an ICMP HOST REDIRECT giving the route * we calculated. */ - if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb)) + if (IPCB(skb)->flags & IPSKB_DOREDIRECT && !opt->srr && + !skb_sec_path(skb)) ip_rt_send_redirect(skb); skb->priority = rt_tos2priority(iph->tos); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 6a2155b..d58dd0e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1554,11 +1554,10 @@ static int __mkroute_input(struct sk_buff *skb, do_cache = res->fi && !itag; if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) && + skb->protocol == htons(ETH_P_IP) && (IN_DEV_SHARED_MEDIA(out_dev) || - inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) { - flags |= RTCF_DOREDIRECT; - do_cache = false; - } + inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) + IPCB(skb)->flags |= IPSKB_DOREDIRECT; if (skb->protocol != htons(ETH_P_IP)) { /* Not IP (i.e. ARP). Do not create route, if it is @@ -2303,6 +2302,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; if (rt->rt_flags & RTCF_NOTIFY) r->rtm_flags |= RTM_F_NOTIFY; + if (IPCB(skb)->flags & IPSKB_DOREDIRECT) + r->rtm_flags |= RTCF_DOREDIRECT; if (nla_put_be32(skb, RTA_DST, dst)) goto nla_put_failure; -- cgit v0.10.2 From ded5006667318c06df875609535176bd33f243a1 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 26 Jan 2015 07:20:39 +0200 Subject: can: kvaser_usb: Do not sleep in atomic context Upon receiving a hardware event with the BUS_RESET flag set, the driver kills all of its anchored URBs and resets all of its transmit URB contexts. Unfortunately it does so under the context of URB completion handler `kvaser_usb_read_bulk_callback()', which is often called in an atomic context. While the device is flooded with many received error packets, usb_kill_urb() typically sleeps/reschedules till the transfer request of each killed URB in question completes, leading to the sleep in atomic bug. [3] In v2 submission of the original driver patch [1], it was stated that the URBs kill and tx contexts reset was needed since we don't receive any tx acknowledgments later and thus such resources will be locked down forever. Fortunately this is no longer needed since an earlier bugfix in this patch series is now applied: all tx URB contexts are reset upon CAN channel close. [2] Moreover, a BUS_RESET is now treated _exactly_ like a BUS_OFF event, which is the recommended handling method advised by the device manufacturer. [1] http://article.gmane.org/gmane.linux.network/239442 http://www.webcitation.org/6Vr2yagAQ [2] can: kvaser_usb: Reset all URB tx contexts upon channel close 889b77f7fd2bcc922493d73a4c51d8a851505815 [3] Stacktrace: [] dump_stack+0x45/0x57 [] __schedule_bug+0x41/0x4f [] __schedule+0x5f1/0x700 [] ? _raw_spin_unlock_irqrestore+0xa/0x10 [] schedule+0x24/0x70 [] usb_kill_urb+0x65/0xa0 [] ? prepare_to_wait_event+0x110/0x110 [] usb_kill_anchored_urbs+0x48/0x80 [] kvaser_usb_unlink_tx_urbs+0x18/0x50 [kvaser_usb] [] kvaser_usb_rx_error+0xc0/0x400 [kvaser_usb] [] ? vprintk_default+0x1a/0x20 [] kvaser_usb_read_bulk_callback+0x4c1/0x5f0 [kvaser_usb] [] __usb_hcd_giveback_urb+0x5e/0xc0 [] usb_hcd_giveback_urb+0x41/0x110 [] finish_urb+0x98/0x180 [ohci_hcd] [] ? acct_account_cputime+0x17/0x20 [] ? local_clock+0x15/0x30 [] ohci_work+0x1fb/0x5a0 [ohci_hcd] [] ? process_backlog+0xb1/0x130 [] ohci_irq+0xeb/0x270 [ohci_hcd] [] usb_hcd_irq+0x21/0x30 [] handle_irq_event_percpu+0x43/0x120 [] handle_irq_event+0x3d/0x60 [] handle_fasteoi_irq+0x74/0x110 [] handle_irq+0x1d/0x30 [] do_IRQ+0x57/0x100 [] common_interrupt+0x6a/0x6a Signed-off-by: Ahmed S. Darwish Cc: linux-stable Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index c32cd61..978a25e 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -662,11 +662,6 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, priv = dev->nets[channel]; stats = &priv->netdev->stats; - if (status & M16C_STATE_BUS_RESET) { - kvaser_usb_unlink_tx_urbs(priv); - return; - } - skb = alloc_can_err_skb(priv->netdev, &cf); if (!skb) { stats->rx_dropped++; @@ -677,7 +672,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status); - if (status & M16C_STATE_BUS_OFF) { + if (status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) { cf->can_id |= CAN_ERR_BUSOFF; priv->can.can_stats.bus_off++; -- cgit v0.10.2 From 3803fa6977f1de15fda4e8646c8fec97c8045cae Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 26 Jan 2015 07:22:54 +0200 Subject: can: kvaser_usb: Send correct context to URB completion Send expected argument to the URB completion hander: a CAN netdevice instead of the network interface private context `kvaser_usb_net_priv'. This was discovered by having some garbage in the kernel log in place of the netdevice names: can0 and can1. Signed-off-by: Ahmed S. Darwish Cc: linux-stable Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 978a25e..f0c6207 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -587,7 +587,7 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv, usb_sndbulkpipe(dev->udev, dev->bulk_out->bEndpointAddress), buf, msg->len, - kvaser_usb_simple_msg_callback, priv); + kvaser_usb_simple_msg_callback, netdev); usb_anchor_urb(urb, &priv->tx_submitted); err = usb_submit_urb(urb, GFP_ATOMIC); -- cgit v0.10.2 From 14c10c2a1dd8eb8e00b750b521753260befa2789 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 26 Jan 2015 07:24:06 +0200 Subject: can: kvaser_usb: Retry the first bulk transfer on -ETIMEDOUT On some x86 laptops, plugging a Kvaser device again after an unplug makes the firmware always ignore the very first command. For such a case, provide some room for retries instead of completely exiting the driver init code. Signed-off-by: Ahmed S. Darwish Cc: linux-stable Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index f0c6207..55407b9 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -1585,7 +1585,7 @@ static int kvaser_usb_probe(struct usb_interface *intf, { struct kvaser_usb *dev; int err = -ENOMEM; - int i; + int i, retry = 3; dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); if (!dev) @@ -1603,7 +1603,15 @@ static int kvaser_usb_probe(struct usb_interface *intf, usb_set_intfdata(intf, dev); - err = kvaser_usb_get_software_info(dev); + /* On some x86 laptops, plugging a Kvaser device again after + * an unplug makes the firmware always ignore the very first + * command. For such a case, provide some room for retries + * instead of completely exiting the driver. + */ + do { + err = kvaser_usb_get_software_info(dev); + } while (--retry && err == -ETIMEDOUT); + if (err) { dev_err(&intf->dev, "Cannot get software infos, error %d\n", err); -- cgit v0.10.2 From e638642b08c170d2021b706f0b1c4f4ae93d8cbd Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 26 Jan 2015 07:25:43 +0200 Subject: can: kvaser_usb: Fix state handling upon BUS_ERROR events While being in an ERROR_WARNING state, and receiving further bus error events with error counters still in the ERROR_WARNING range of 97-127 inclusive, the state handling code erroneously reverts back to ERROR_ACTIVE. Per the CAN standard, only revert to ERROR_ACTIVE when the error counters are less than 96. Moreover, in certain Kvaser models, the BUS_ERROR flag is always set along with undefined bits in the M16C status register. Thus use bitwise operators instead of full equality for checking that register against bus errors. Signed-off-by: Ahmed S. Darwish Cc: linux-stable Signed-off-by: Marc Kleine-Budde diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 55407b9..7af379c 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -698,9 +698,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, } new_state = CAN_STATE_ERROR_PASSIVE; - } - - if (status == M16C_STATE_BUS_ERROR) { + } else if (status & M16C_STATE_BUS_ERROR) { if ((priv->can.state < CAN_STATE_ERROR_WARNING) && ((txerr >= 96) || (rxerr >= 96))) { cf->can_id |= CAN_ERR_CRTL; @@ -710,7 +708,8 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, priv->can.can_stats.error_warning++; new_state = CAN_STATE_ERROR_WARNING; - } else if (priv->can.state > CAN_STATE_ERROR_ACTIVE) { + } else if ((priv->can.state > CAN_STATE_ERROR_ACTIVE) && + ((txerr < 96) && (rxerr < 96))) { cf->can_id |= CAN_ERR_PROT; cf->data[2] = CAN_ERR_PROT_ACTIVE; -- cgit v0.10.2 From 86f3cddbc3037882414c7308973530167906b7e9 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 24 Jan 2015 08:02:40 +1100 Subject: udp_diag: Fix socket skipping within chain While working on rhashtable walking I noticed that the UDP diag dumping code is buggy. In particular, the socket skipping within a chain never happens, even though we record the number of sockets that should be skipped. As this code was supposedly copied from TCP, this patch does what TCP does and resets num before we walk a chain. Signed-off-by: Herbert Xu Acked-by: Pavel Emelyanov Signed-off-by: David S. Miller diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c index 7927db0..4a000f1 100644 --- a/net/ipv4/udp_diag.c +++ b/net/ipv4/udp_diag.c @@ -99,11 +99,13 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlin s_slot = cb->args[0]; num = s_num = cb->args[1]; - for (slot = s_slot; slot <= table->mask; num = s_num = 0, slot++) { + for (slot = s_slot; slot <= table->mask; s_num = 0, slot++) { struct sock *sk; struct hlist_nulls_node *node; struct udp_hslot *hslot = &table->hash[slot]; + num = 0; + if (hlist_nulls_empty(&hslot->head)) continue; -- cgit v0.10.2 From fc752f1f43c1c038a2c6ae58cc739ebb5953ccb0 Mon Sep 17 00:00:00 2001 From: "subashab@codeaurora.org" Date: Fri, 23 Jan 2015 22:26:02 +0000 Subject: ping: Fix race in free in receive path An exception is seen in ICMP ping receive path where the skb destructor sock_rfree() tries to access a freed socket. This happens because ping_rcv() releases socket reference with sock_put() and this internally frees up the socket. Later icmp_rcv() will try to free the skb and as part of this, skb destructor is called and which leads to a kernel panic as the socket is freed already in ping_rcv(). -->|exception -007|sk_mem_uncharge -007|sock_rfree -008|skb_release_head_state -009|skb_release_all -009|__kfree_skb -010|kfree_skb -011|icmp_rcv -012|ip_local_deliver_finish Fix this incorrect free by cloning this skb and processing this cloned skb instead. This patch was suggested by Eric Dumazet Signed-off-by: Subash Abhinov Kasiviswanathan Cc: Eric Dumazet Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index c0d82f7..2a3720f 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -966,8 +966,11 @@ bool ping_rcv(struct sk_buff *skb) sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id)); if (sk != NULL) { + struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); + pr_debug("rcv on socket %p\n", sk); - ping_queue_rcv_skb(sk, skb_get(skb)); + if (skb2) + ping_queue_rcv_skb(sk, skb2); sock_put(sk); return true; } -- cgit v0.10.2 From dc1d0e6d55006a48ebc0f40a74485ca430f05046 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 27 Jan 2015 00:41:16 +0000 Subject: sh_eth: Remove RX overflow log messages If RX traffic is overflowing the FIFO or DMA ring, logging every time this happens just makes things worse. These errors are visible in the statistics anyway. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 99a838d..bb15cd8 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1575,7 +1575,6 @@ ignore_link: if (intr_status & EESR_RFRMER) { /* Receive Frame Overflow int */ ndev->stats.rx_frame_errors++; - netif_err(mdp, rx_err, ndev, "Receive Abort\n"); } } @@ -1594,13 +1593,11 @@ ignore_link: if (intr_status & EESR_RDE) { /* Receive Descriptor Empty int */ ndev->stats.rx_over_errors++; - netif_err(mdp, rx_err, ndev, "Receive Descriptor Empty\n"); } if (intr_status & EESR_RFE) { /* Receive FIFO Overflow int */ ndev->stats.rx_fifo_errors++; - netif_err(mdp, rx_err, ndev, "Receive FIFO Overflow\n"); } if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) { -- cgit v0.10.2 From 740c7f31c094703cfb3902412e66e243eb24b707 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 27 Jan 2015 00:49:32 +0000 Subject: sh_eth: Ensure DMA engines are stopped before freeing buffers Currently we try to clear EDRRR and EDTRR and immediately continue to free buffers. This is unsafe because: - In general, register writes are not serialised with DMA, so we still have to wait for DMA to complete somehow - The R8A7790 (R-Car H2) manual states that the TX running flag cannot be cleared by writing to EDTRR - The same manual states that clearing the RX running flag only stops RX DMA at the next packet boundary I applied this patch to the driver to detect DMA writes to freed buffers: > --- a/drivers/net/ethernet/renesas/sh_eth.c > +++ b/drivers/net/ethernet/renesas/sh_eth.c > @@ -1098,7 +1098,14 @@ static void sh_eth_ring_free(struct net_device *ndev) > /* Free Rx skb ringbuffer */ > if (mdp->rx_skbuff) { > for (i = 0; i < mdp->num_rx_ring; i++) > + memcpy(mdp->rx_skbuff[i]->data, > + "Hello, world", 12); > + msleep(100); > + for (i = 0; i < mdp->num_rx_ring; i++) { > + WARN_ON(memcmp(mdp->rx_skbuff[i]->data, > + "Hello, world", 12)); > dev_kfree_skb(mdp->rx_skbuff[i]); > + } > } > kfree(mdp->rx_skbuff); > mdp->rx_skbuff = NULL; then ran the loop: while ethtool -G eth0 rx 128 ; ethtool -G eth0 rx 64; do echo -n .; done and 'ping -f' toward the sh_eth port from another machine. The warning fired several times a minute. To fix these issues: - Deactivate all TX descriptors rather than writing to EDTRR - As there seems to be no way of telling when RX DMA is stopped, perform a soft reset to ensure that both DMA enginess are stopped - To reduce the possibility of the reset truncating a transmitted frame, disable egress and wait a reasonable time to reach a packet boundary before resetting - Update statistics before resetting (The 'reasonable time' does not allow for CS/CD in half-duplex mode, but half-duplex no longer seems reasonable!) Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index bb15cd8..245166b 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -396,6 +396,9 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { [TSU_ADRL31] = 0x01fc, }; +static void sh_eth_rcv_snd_disable(struct net_device *ndev); +static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev); + static bool sh_eth_is_gether(struct sh_eth_private *mdp) { return mdp->reg_offset == sh_eth_offset_gigabit; @@ -1358,6 +1361,33 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) return ret; } +static void sh_eth_dev_exit(struct net_device *ndev) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + int i; + + /* Deactivate all TX descriptors, so DMA should stop at next + * packet boundary if it's currently running + */ + for (i = 0; i < mdp->num_tx_ring; i++) + mdp->tx_ring[i].status &= ~cpu_to_edmac(mdp, TD_TACT); + + /* Disable TX FIFO egress to MAC */ + sh_eth_rcv_snd_disable(ndev); + + /* Stop RX DMA at next packet boundary */ + sh_eth_write(ndev, 0, EDRRR); + + /* Aside from TX DMA, we can't tell when the hardware is + * really stopped, so we need to reset to make sure. + * Before doing that, wait for long enough to *probably* + * finish transmitting the last packet and poll stats. + */ + msleep(2); /* max frame time at 10 Mbps < 1250 us */ + sh_eth_get_stats(ndev); + sh_eth_reset(ndev); +} + /* free Tx skb function */ static int sh_eth_txfree(struct net_device *ndev) { @@ -1986,9 +2016,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev, napi_synchronize(&mdp->napi); sh_eth_write(ndev, 0x0000, EESIPR); - /* Stop the chip's Tx and Rx processes. */ - sh_eth_write(ndev, 0, EDTRR); - sh_eth_write(ndev, 0, EDRRR); + sh_eth_dev_exit(ndev); /* Free all the skbuffs in the Rx queue. */ sh_eth_ring_free(ndev); @@ -2207,11 +2235,8 @@ static int sh_eth_close(struct net_device *ndev) napi_disable(&mdp->napi); sh_eth_write(ndev, 0x0000, EESIPR); - /* Stop the chip's Tx and Rx processes. */ - sh_eth_write(ndev, 0, EDTRR); - sh_eth_write(ndev, 0, EDRRR); + sh_eth_dev_exit(ndev); - sh_eth_get_stats(ndev); /* PHY Disconnect */ if (mdp->phydev) { phy_stop(mdp->phydev); -- cgit v0.10.2 From aa3933b87309c61b4fa4bb93c1ad4c3f08afb1b8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 27 Jan 2015 00:49:47 +0000 Subject: sh_eth: Check for DMA mapping errors on transmit dma_map_single() may fail if an IOMMU or swiotlb is in use, so we need to check for this. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 245166b..4a085da 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2174,6 +2174,10 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) skb->len + 2); txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(&ndev->dev, txdesc->addr)) { + kfree_skb(skb); + return NETDEV_TX_OK; + } txdesc->buffer_length = skb->len; if (entry >= mdp->num_tx_ring - 1) -- cgit v0.10.2 From 52b9fa3696c44151a2f1d361a00be7c5513db026 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 27 Jan 2015 00:50:24 +0000 Subject: sh_eth: Fix DMA-API usage for RX buffers - Use the return value of dma_map_single(), rather than calling virt_to_page() separately - Check for mapping failue - Call dma_unmap_single() rather than dma_sync_single_for_cpu() Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 4a085da..04283fe 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1123,6 +1123,7 @@ static void sh_eth_ring_format(struct net_device *ndev) int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring; int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring; int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; + dma_addr_t dma_addr; mdp->cur_rx = 0; mdp->cur_tx = 0; @@ -1136,7 +1137,6 @@ static void sh_eth_ring_format(struct net_device *ndev) /* skb */ mdp->rx_skbuff[i] = NULL; skb = netdev_alloc_skb(ndev, skbuff_size); - mdp->rx_skbuff[i] = skb; if (skb == NULL) break; sh_eth_set_receive_align(skb); @@ -1145,9 +1145,15 @@ static void sh_eth_ring_format(struct net_device *ndev) rxdesc = &mdp->rx_ring[i]; /* The size of the buffer is a multiple of 16 bytes. */ rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); - dma_map_single(&ndev->dev, skb->data, rxdesc->buffer_length, - DMA_FROM_DEVICE); - rxdesc->addr = virt_to_phys(skb->data); + dma_addr = dma_map_single(&ndev->dev, skb->data, + rxdesc->buffer_length, + DMA_FROM_DEVICE); + if (dma_mapping_error(&ndev->dev, dma_addr)) { + kfree_skb(skb); + break; + } + mdp->rx_skbuff[i] = skb; + rxdesc->addr = dma_addr; rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP); /* Rx descriptor address set */ @@ -1432,6 +1438,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) u16 pkt_len = 0; u32 desc_status; int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; + dma_addr_t dma_addr; boguscnt = min(boguscnt, *quota); limit = boguscnt; @@ -1479,9 +1486,9 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) mdp->rx_skbuff[entry] = NULL; if (mdp->cd->rpadir) skb_reserve(skb, NET_IP_ALIGN); - dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr, - ALIGN(mdp->rx_buf_sz, 16), - DMA_FROM_DEVICE); + dma_unmap_single(&ndev->dev, rxdesc->addr, + ALIGN(mdp->rx_buf_sz, 16), + DMA_FROM_DEVICE); skb_put(skb, pkt_len); skb->protocol = eth_type_trans(skb, ndev); netif_receive_skb(skb); @@ -1501,15 +1508,20 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) if (mdp->rx_skbuff[entry] == NULL) { skb = netdev_alloc_skb(ndev, skbuff_size); - mdp->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ sh_eth_set_receive_align(skb); - dma_map_single(&ndev->dev, skb->data, - rxdesc->buffer_length, DMA_FROM_DEVICE); + dma_addr = dma_map_single(&ndev->dev, skb->data, + rxdesc->buffer_length, + DMA_FROM_DEVICE); + if (dma_mapping_error(&ndev->dev, dma_addr)) { + kfree_skb(skb); + break; + } + mdp->rx_skbuff[entry] = skb; skb_checksum_none_assert(skb); - rxdesc->addr = virt_to_phys(skb->data); + rxdesc->addr = dma_addr; } if (entry >= mdp->num_rx_ring - 1) rxdesc->status |= -- cgit v0.10.2 From 6e9e16e6143b725662e47026a1d0f270721cdd24 Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Mon, 26 Jan 2015 15:11:17 +0100 Subject: ipv6: replacing a rt6_info needs to purge possible propagated rt6_infos too Lubomir Rintel reported that during replacing a route the interface reference counter isn't correctly decremented. To quote bug : | [root@rhel7-5 lkundrak]# sh -x lal | + ip link add dev0 type dummy | + ip link set dev0 up | + ip link add dev1 type dummy | + ip link set dev1 up | + ip addr add 2001:db8:8086::2/64 dev dev0 | + ip route add 2001:db8:8086::/48 dev dev0 proto static metric 20 | + ip route add 2001:db8:8088::/48 dev dev1 proto static metric 10 | + ip route replace 2001:db8:8086::/48 dev dev1 proto static metric 20 | + ip link del dev0 type dummy | Message from syslogd@rhel7-5 at Jan 23 10:54:41 ... | kernel:unregister_netdevice: waiting for dev0 to become free. Usage count = 2 | | Message from syslogd@rhel7-5 at Jan 23 10:54:51 ... | kernel:unregister_netdevice: waiting for dev0 to become free. Usage count = 2 During replacement of a rt6_info we must walk all parent nodes and check if the to be replaced rt6_info got propagated. If so, replace it with an alive one. Fixes: 4a287eba2de3957 ("IPv6 routing, NLM_F_* flag support: REPLACE and EXCL flags support, warn about missing CREATE flag") Reported-by: Lubomir Rintel Signed-off-by: Hannes Frederic Sowa Tested-by: Lubomir Rintel Signed-off-by: David S. Miller diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index b2d1838..f1c6d5e 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -659,6 +659,29 @@ static int fib6_commit_metrics(struct dst_entry *dst, return 0; } +static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn, + struct net *net) +{ + if (atomic_read(&rt->rt6i_ref) != 1) { + /* This route is used as dummy address holder in some split + * nodes. It is not leaked, but it still holds other resources, + * which must be released in time. So, scan ascendant nodes + * and replace dummy references to this route with references + * to still alive ones. + */ + while (fn) { + if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { + fn->leaf = fib6_find_prefix(net, fn); + atomic_inc(&fn->leaf->rt6i_ref); + rt6_release(rt); + } + fn = fn->parent; + } + /* No more references are possible at this point. */ + BUG_ON(atomic_read(&rt->rt6i_ref) != 1); + } +} + /* * Insert routing information in a node. */ @@ -807,11 +830,12 @@ add: rt->dst.rt6_next = iter->dst.rt6_next; atomic_inc(&rt->rt6i_ref); inet6_rt_notify(RTM_NEWROUTE, rt, info); - rt6_release(iter); if (!(fn->fn_flags & RTN_RTINFO)) { info->nl_net->ipv6.rt6_stats->fib_route_nodes++; fn->fn_flags |= RTN_RTINFO; } + fib6_purge_rt(iter, fn, info->nl_net); + rt6_release(iter); } return 0; @@ -1322,24 +1346,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, fn = fib6_repair_tree(net, fn); } - if (atomic_read(&rt->rt6i_ref) != 1) { - /* This route is used as dummy address holder in some split - * nodes. It is not leaked, but it still holds other resources, - * which must be released in time. So, scan ascendant nodes - * and replace dummy references to this route with references - * to still alive ones. - */ - while (fn) { - if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { - fn->leaf = fib6_find_prefix(net, fn); - atomic_inc(&fn->leaf->rt6i_ref); - rt6_release(rt); - } - fn = fn->parent; - } - /* No more references are possible at this point. */ - BUG_ON(atomic_read(&rt->rt6i_ref) != 1); - } + fib6_purge_rt(rt, fn, net); inet6_rt_notify(RTM_DELROUTE, rt, info); rt6_release(rt); -- cgit v0.10.2 From 24e579c8898aa641ede3149234906982290934e5 Mon Sep 17 00:00:00 2001 From: Govindarajulu Varadarajan <_govind@gmx.com> Date: Sun, 25 Jan 2015 16:09:23 +0530 Subject: bnx2x: fix napi poll return value for repoll With the commit d75b1ade567ffab ("net: less interrupt masking in NAPI") napi repoll is done only when work_done == budget. When in busy_poll is we return 0 in napi_poll. We should return budget. Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com> Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 1d1147c..e468ed3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3175,7 +3175,7 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) } #endif if (!bnx2x_fp_lock_napi(fp)) - return work_done; + return budget; for_each_cos_in_tx_queue(fp, cos) if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos])) -- cgit v0.10.2 From 9afec6efc6b1043692eada758cd7837623dd943b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 27 Jan 2015 18:38:03 +0200 Subject: stmmac: prevent probe drivers to crash kernel In the case when alloc_netdev fails we return NULL to a caller. But there is no check for NULL in the probe drivers. This patch changes NULL to an error pointer. The function description is amended to reflect what we may get returned. Signed-off-by: Andy Shevchenko Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 8c6b7c1..cf62ff4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2778,6 +2778,9 @@ static int stmmac_hw_init(struct stmmac_priv *priv) * @addr: iobase memory address * Description: this is the main probe function used to * call the alloc_etherdev, allocate the priv structure. + * Return: + * on success the new private structure is returned, otherwise the error + * pointer. */ struct stmmac_priv *stmmac_dvr_probe(struct device *device, struct plat_stmmacenet_data *plat_dat, @@ -2789,7 +2792,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, ndev = alloc_etherdev(sizeof(struct stmmac_priv)); if (!ndev) - return NULL; + return ERR_PTR(-ENOMEM); SET_NETDEV_DEV(ndev, device); -- cgit v0.10.2 From 06539d3071067ff146a9bffd1c801fa56d290909 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 27 Jan 2015 12:25:33 -0800 Subject: net: don't OOPS on socket aio Signed-off-by: Christoph Hellwig Signed-off-by: David S. Miller diff --git a/net/socket.c b/net/socket.c index a2c33a4..418795c 100644 --- a/net/socket.c +++ b/net/socket.c @@ -869,9 +869,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, struct sock_iocb *siocb) { - if (!is_sync_kiocb(iocb)) - BUG(); - siocb->kiocb = iocb; iocb->private = siocb; return siocb; -- cgit v0.10.2