From: Peter Ujfalusi peter.ujfalusi@ti.com
[ Upstream commit 7ad9db66fafb0f0ad53fd2a66217105da5ddeffe ]
In case mipi_dsi_attach() fails remove the registered panel to avoid added panel without corresponding device.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Signed-off-by: Thierry Reding treding@nvidia.com Link: https://patchwork.freedesktop.org/patch/msgid/20190226081153.31334-1-peter.u... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-simple.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 97964f7f2ace..b1d41c4921dd 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2803,7 +2803,14 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi) dsi->format = desc->format; dsi->lanes = desc->lanes;
- return mipi_dsi_attach(dsi); + err = mipi_dsi_attach(dsi); + if (err) { + struct panel_simple *panel = dev_get_drvdata(&dsi->dev); + + drm_panel_remove(&panel->base); + } + + return err; }
static int panel_simple_dsi_remove(struct mipi_dsi_device *dsi)
From: Fabien Dessenne fabien.dessenne@st.com
[ Upstream commit 3e53ef91f826957dec013c47707ffc1bb42b42d7 ]
During probe, check the "get_irq" error value.
Signed-off-by: Fabien Dessenne fabien.dessenne@st.com Acked-by: Fabrice Gasnier fabrice.gasnier@st.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/stm32-dfsdm-adc.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index fcd4a1c00ca0..15a115210108 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c @@ -1144,6 +1144,12 @@ static int stm32_dfsdm_adc_probe(struct platform_device *pdev) * So IRQ associated to filter instance 0 is dedicated to the Filter 0. */ irq = platform_get_irq(pdev, 0); + if (irq < 0) { + if (irq != -EPROBE_DEFER) + dev_err(dev, "Failed to get IRQ: %d\n", irq); + return irq; + } + ret = devm_request_irq(dev, irq, stm32_dfsdm_irq, 0, pdev->name, adc); if (ret < 0) {
From: Fabien Dessenne fabien.dessenne@st.com
[ Upstream commit d2fc0156963cae8f1eec8e2dd645fbbf1e1c1c8e ]
During probe, check the devm_ioremap_resource() error value. Also return the devm_clk_get() error value instead of -EINVAL.
Signed-off-by: Fabien Dessenne fabien.dessenne@st.com Acked-by: Fabrice Gasnier fabrice.gasnier@st.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/stm32-dfsdm-core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c index bf089f5d6225..941630615e88 100644 --- a/drivers/iio/adc/stm32-dfsdm-core.c +++ b/drivers/iio/adc/stm32-dfsdm-core.c @@ -213,6 +213,8 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, } priv->dfsdm.phys_base = res->start; priv->dfsdm.base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->dfsdm.base)) + return PTR_ERR(priv->dfsdm.base);
/* * "dfsdm" clock is mandatory for DFSDM peripheral clocking. @@ -222,8 +224,10 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, */ priv->clk = devm_clk_get(&pdev->dev, "dfsdm"); if (IS_ERR(priv->clk)) { - dev_err(&pdev->dev, "No stm32_dfsdm_clk clock found\n"); - return -EINVAL; + ret = PTR_ERR(priv->clk); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "Failed to get clock (%d)\n", ret); + return ret; }
priv->aclk = devm_clk_get(&pdev->dev, "audio");
From: Quentin Deslandes quentin.deslandes@itdev.co.uk
[ Upstream commit d8c2869300ab5f7a19bf6f5a04fe473c5c9887e3 ]
Check on called function's returned value for error and return 0 on success or a negative errno value on error instead of a boolean value.
Signed-off-by: Quentin Deslandes quentin.deslandes@itdev.co.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/vt6656/main_usb.c | 42 ++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index ccafcc2c87ac..70433f756d8e 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -402,16 +402,19 @@ static void vnt_free_int_bufs(struct vnt_private *priv) kfree(priv->int_buf.data_buf); }
-static bool vnt_alloc_bufs(struct vnt_private *priv) +static int vnt_alloc_bufs(struct vnt_private *priv) { + int ret = 0; struct vnt_usb_send_context *tx_context; struct vnt_rcb *rcb; int ii;
for (ii = 0; ii < priv->num_tx_context; ii++) { tx_context = kmalloc(sizeof(*tx_context), GFP_KERNEL); - if (!tx_context) + if (!tx_context) { + ret = -ENOMEM; goto free_tx; + }
priv->tx_context[ii] = tx_context; tx_context->priv = priv; @@ -419,16 +422,20 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
/* allocate URBs */ tx_context->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!tx_context->urb) + if (!tx_context->urb) { + ret = -ENOMEM; goto free_tx; + }
tx_context->in_use = false; }
for (ii = 0; ii < priv->num_rcb; ii++) { priv->rcb[ii] = kzalloc(sizeof(*priv->rcb[ii]), GFP_KERNEL); - if (!priv->rcb[ii]) + if (!priv->rcb[ii]) { + ret = -ENOMEM; goto free_rx_tx; + }
rcb = priv->rcb[ii];
@@ -436,39 +443,46 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
/* allocate URBs */ rcb->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!rcb->urb) + if (!rcb->urb) { + ret = -ENOMEM; goto free_rx_tx; + }
rcb->skb = dev_alloc_skb(priv->rx_buf_sz); - if (!rcb->skb) + if (!rcb->skb) { + ret = -ENOMEM; goto free_rx_tx; + }
rcb->in_use = false;
/* submit rx urb */ - if (vnt_submit_rx_urb(priv, rcb)) + ret = vnt_submit_rx_urb(priv, rcb); + if (ret) goto free_rx_tx; }
priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->interrupt_urb) + if (!priv->interrupt_urb) { + ret = -ENOMEM; goto free_rx_tx; + }
priv->int_buf.data_buf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL); if (!priv->int_buf.data_buf) { - usb_free_urb(priv->interrupt_urb); - goto free_rx_tx; + ret = -ENOMEM; + goto free_rx_tx_urb; }
- return true; + return 0;
+free_rx_tx_urb: + usb_free_urb(priv->interrupt_urb); free_rx_tx: vnt_free_rx_bufs(priv); - free_tx: vnt_free_tx_bufs(priv); - - return false; + return ret; }
static void vnt_tx_80211(struct ieee80211_hw *hw,
From: Thinh Nguyen Thinh.Nguyen@synopsys.com
[ Upstream commit 561759292774707b71ee61aecc07724905bb7ef1 ]
If the device rejects the control transfer to enable device-initiated U1/U2 entry, then the device will not initiate U1/U2 transition. To improve the performance, the downstream port should not initate transition to U1/U2 to avoid the delay from the device link command response (no packet can be transmitted while waiting for a response from the device). If the device has some quirks and does not implement U1/U2, it may reject all the link state change requests, and the downstream port may resend and flood the bus with more requests. This will affect the device performance even further. This patch disables the hub-initated U1/U2 if the device-initiated U1/U2 entry fails.
Reference: USB 3.2 spec 7.2.4.2.3
Signed-off-by: Thinh Nguyen thinhn@synopsys.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/core/hub.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index eb24ec0e160d..c4281d16bcb7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3958,6 +3958,9 @@ static int usb_set_lpm_timeout(struct usb_device *udev, * control transfers to set the hub timeout or enable device-initiated U1/U2 * will be successful. * + * If the control transfer to enable device-initiated U1/U2 entry fails, then + * hub-initiated U1/U2 will be disabled. + * * If we cannot set the parent hub U1/U2 timeout, we attempt to let the xHCI * driver know about it. If that call fails, it should be harmless, and just * take up more slightly more bus bandwidth for unnecessary U1/U2 exit latency. @@ -4012,23 +4015,24 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, * host know that this link state won't be enabled. */ hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); - } else { - /* Only a configured device will accept the Set Feature - * U1/U2_ENABLE - */ - if (udev->actconfig) - usb_set_device_initiated_lpm(udev, state, true); + return; + }
- /* As soon as usb_set_lpm_timeout(timeout) returns 0, the - * hub-initiated LPM is enabled. Thus, LPM is enabled no - * matter the result of usb_set_device_initiated_lpm(). - * The only difference is whether device is able to initiate - * LPM. - */ + /* Only a configured device will accept the Set Feature + * U1/U2_ENABLE + */ + if (udev->actconfig && + usb_set_device_initiated_lpm(udev, state, true) == 0) { if (state == USB3_LPM_U1) udev->usb3_lpm_u1_enabled = 1; else if (state == USB3_LPM_U2) udev->usb3_lpm_u2_enabled = 1; + } else { + /* Don't request U1/U2 entry if the device + * cannot transition to U1/U2. + */ + usb_set_lpm_timeout(udev, state, 0); + hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); } }
From: Serge Semin fancer.lancer@gmail.com
[ Upstream commit 35240ba26a932b279a513f66fa4cabfd7af55221 ]
Current calculator doesn't do it' job quite correct. First of all the max310x baud-rates generator supports the divisor being less than 16. In this case the x2/x4 modes can be used to double or quadruple the reference frequency. But the current baud-rate setter function just filters all these modes out by the first condition and setups these modes only if there is a clocks-baud division remainder. The former doesn't seem right at all, since enabling the x2/x4 modes causes the line noise tolerance reduction and should be only used as a last resort to enable a requested too high baud-rate.
Finally the fraction is supposed to be calculated from D = Fref/(c*baud) formulae, but not from D % 16, which causes the precision loss. So to speak the current baud-rate calculator code works well only if the baud perfectly fits to the uart reference input frequency.
Lets fix the calculator by implementing the algo fully compliant with the fractional baud-rate generator described in the datasheet: D = Fref / (c*baud), where c={16,8,4} is the x1/x2/x4 rate mode respectively, Fref - reference input frequency. The divisor fraction is calculated from the same formulae, but making sure it is found with a resolution of 0.0625 (four bits).
Signed-off-by: Serge Semin fancer.lancer@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/max310x.c | 51 ++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 20 deletions(-)
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 38c48a02b920..bd3e6cf81af5 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -491,37 +491,48 @@ static bool max310x_reg_precious(struct device *dev, unsigned int reg)
static int max310x_set_baud(struct uart_port *port, int baud) { - unsigned int mode = 0, clk = port->uartclk, div = clk / baud; + unsigned int mode = 0, div = 0, frac = 0, c = 0, F = 0;
- /* Check for minimal value for divider */ - if (div < 16) - div = 16; - - if (clk % baud && (div / 16) < 0x8000) { + /* + * Calculate the integer divisor first. Select a proper mode + * in case if the requested baud is too high for the pre-defined + * clocks frequency. + */ + div = port->uartclk / baud; + if (div < 8) { + /* Mode x4 */ + c = 4; + mode = MAX310X_BRGCFG_4XMODE_BIT; + } else if (div < 16) { /* Mode x2 */ + c = 8; mode = MAX310X_BRGCFG_2XMODE_BIT; - clk = port->uartclk * 2; - div = clk / baud; - - if (clk % baud && (div / 16) < 0x8000) { - /* Mode x4 */ - mode = MAX310X_BRGCFG_4XMODE_BIT; - clk = port->uartclk * 4; - div = clk / baud; - } + } else { + c = 16; }
- max310x_port_write(port, MAX310X_BRGDIVMSB_REG, (div / 16) >> 8); - max310x_port_write(port, MAX310X_BRGDIVLSB_REG, div / 16); - max310x_port_write(port, MAX310X_BRGCFG_REG, (div % 16) | mode); + /* Calculate the divisor in accordance with the fraction coefficient */ + div /= c; + F = c*baud; + + /* Calculate the baud rate fraction */ + if (div > 0) + frac = (16*(port->uartclk % F)) / F; + else + div = 1; + + max310x_port_write(port, MAX310X_BRGDIVMSB_REG, div >> 8); + max310x_port_write(port, MAX310X_BRGDIVLSB_REG, div); + max310x_port_write(port, MAX310X_BRGCFG_REG, frac | mode);
- return DIV_ROUND_CLOSEST(clk, div); + /* Return the actual baud rate we just programmed */ + return (16*port->uartclk) / (c*(16*div + frac)); }
static int max310x_update_best_err(unsigned long f, long *besterr) { /* Use baudrate 115200 for calculate error */ - long err = f % (115200 * 16); + long err = f % (460800 * 16);
if ((*besterr < 0) || (*besterr > err)) { *besterr = err;
From: Wen Yang wen.yang99@zte.com.cn
[ Upstream commit 3c89c70634bb0b6f48512de873e7a45c7e1fbaa5 ]
The call to of_parse_phandle returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: ./drivers/pinctrl/pinctrl-rockchip.c:3221:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 3196, but without a corresponding object release within this function. ./drivers/pinctrl/pinctrl-rockchip.c:3223:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 3196, but without a corresponding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Cc: Linus Walleij linus.walleij@linaro.org Cc: Heiko Stuebner heiko@sntech.de Cc: linux-gpio@vger.kernel.org Cc: linux-rockchip@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-rockchip.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index f4a61429e06e..8d83817935da 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -3172,6 +3172,7 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, base, &rockchip_regmap_config); } + of_node_put(node); }
bank->irq = irq_of_parse_and_map(bank->of_node, 0);
From: Christophe Leroy christophe.leroy@c-s.fr
[ Upstream commit 06aaa3d066db87e8478522d910285141d44b1e58 ]
SMC relocation can also be activated earlier by the bootloader, so the driver's behaviour cannot rely on selected kernel config.
When the SMC is relocated, CPM_CR_INIT_TRX cannot be used.
But the only thing CPM_CR_INIT_TRX does is to clear the rstate and tstate registers, so this can be done manually, even when SMC is not relocated.
Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr Fixes: 9ab921201444 ("cpm_uart: fix non-console port startup bug") Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index e5389591bb4f..ad40c75bb58f 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -407,7 +407,16 @@ static int cpm_uart_startup(struct uart_port *port) clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); } cpm_uart_initbd(pinfo); - cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); + if (IS_SMC(pinfo)) { + out_be32(&pinfo->smcup->smc_rstate, 0); + out_be32(&pinfo->smcup->smc_tstate, 0); + out_be16(&pinfo->smcup->smc_rbptr, + in_be16(&pinfo->smcup->smc_rbase)); + out_be16(&pinfo->smcup->smc_tbptr, + in_be16(&pinfo->smcup->smc_tbase)); + } else { + cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); + } } /* Install interrupt handler. */ retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port); @@ -861,16 +870,14 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE);
/* - * In case SMC1 is being relocated... + * In case SMC is being relocated... */ -#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH) out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase)); out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase)); out_be32(&up->smc_rstate, 0); out_be32(&up->smc_tstate, 0); out_be16(&up->smc_brkcr, 1); /* number of break chars */ out_be16(&up->smc_brkec, 0); -#endif
/* Set up the uart parameters in the * parameter ram. @@ -884,8 +891,6 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) out_be16(&up->smc_brkec, 0); out_be16(&up->smc_brkcr, 1);
- cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); - /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */
From: Gen Zhang blackgod016574@gmail.com
[ Upstream commit 84ecc2f6eb1cb12e6d44818f94fa49b50f06e6ac ]
In function con_insert_unipair(), when allocation for p2 and p1[n] fails, ENOMEM is returned, but previously allocated p1 is not freed, remains as leaking memory. Thus we should free p1 as well when this allocation fails.
Signed-off-by: Gen Zhang blackgod016574@gmail.com Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/vt/consolemap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 7c7ada0b3ea0..814d1b7967ae 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -489,7 +489,11 @@ con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos) p2 = p1[n = (unicode >> 6) & 0x1f]; if (!p2) { p2 = p1[n] = kmalloc_array(64, sizeof(u16), GFP_KERNEL); - if (!p2) return -ENOMEM; + if (!p2) { + kfree(p1); + p->uni_pgdir[n] = NULL; + return -ENOMEM; + } memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */ }
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit 1352c779cb74d427f4150cbe779a2f7886f70cae ]
[Why] An assertion is thrown when using SURFACE_PIXEL_FORMAT_GRPH_RGB565 formats on DCE since the prescale_params->scale wasn't being filled.
Found by a dmesg-fail when running the igt@kms_plane@pixel-format-pipe-a-planes test on Baffin.
[How] Fill in the scale parameter.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Roman Li Roman.Li@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 53ccacf99eca..c3ad2bbec1a5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -242,6 +242,9 @@ static void build_prescale_params(struct ipp_prescale_params *prescale_params, prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED;
switch (plane_state->format) { + case SURFACE_PIXEL_FORMAT_GRPH_RGB565: + prescale_params->scale = 0x2082; + break; case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: prescale_params->scale = 0x2020;
From: Tiecheng Zhou Tiecheng.Zhou@amd.com
[ Upstream commit fe2b5323d2c3cedaa3bf943dc7a0d233c853c914 ]
it requires to initialize HDP_NONSURFACE_BASE, so as to avoid using the value left by a previous VM under sriov scenario.
v2: it should not hurt baremetal, generalize it for both sriov and baremetal
Signed-off-by: Emily Deng Emily.Deng@amd.com Signed-off-by: Tiecheng Zhou Tiecheng.Zhou@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 72f8018fa2a8..ede27dab675f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1037,6 +1037,9 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) tmp = RREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL); WREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL, tmp);
+ WREG32_SOC15(HDP, 0, mmHDP_NONSURFACE_BASE, (adev->gmc.vram_start >> 8)); + WREG32_SOC15(HDP, 0, mmHDP_NONSURFACE_BASE_HI, (adev->gmc.vram_start >> 40)); + /* After HDP is initialized, flush HDP.*/ adev->nbio_funcs->hdp_flush(adev, NULL);
From: Paul Hsieh paul.hsieh@amd.com
[ Upstream commit 1090d58d4815b1fcd95a80987391006c86398b4c ]
[Why] When disable driver, OS will set backlight optimization then do stop device. But this flag will cause driver to enable ABM when driver disabled.
[How] Send ABM disable command before destroy ABM construct
Signed-off-by: Paul Hsieh paul.hsieh@amd.com Reviewed-by: Anthony Koo Anthony.Koo@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index 29294db1a96b..070ab56a8aca 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -474,6 +474,8 @@ void dce_abm_destroy(struct abm **abm) { struct dce_abm *abm_dce = TO_DCE_ABM(*abm);
+ abm_dce->base.funcs->set_abm_immediate_disable(*abm); + kfree(abm_dce); *abm = NULL; }
From: Oak Zeng ozeng@amd.com
[ Upstream commit e73390d181103a19e1111ec2f25559a0570e9fe0 ]
Free mqd_mem_obj it GTT buffer allocation for MQD+control stack fails.
Signed-off-by: Oak Zeng ozeng@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c index 0cedb37cf513..985bebde5a34 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c @@ -75,6 +75,7 @@ static int init_mqd(struct mqd_manager *mm, void **mqd, struct v9_mqd *m; struct kfd_dev *kfd = mm->dev;
+ *mqd_mem_obj = NULL; /* From V9, for CWSR, the control stack is located on the next page * boundary after the mqd, we will use the gtt allocation function * instead of sub-allocation function. @@ -92,8 +93,10 @@ static int init_mqd(struct mqd_manager *mm, void **mqd, } else retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct v9_mqd), mqd_mem_obj); - if (retval != 0) + if (retval) { + kfree(*mqd_mem_obj); return -ENOMEM; + }
m = (struct v9_mqd *) (*mqd_mem_obj)->cpu_ptr; addr = (*mqd_mem_obj)->gpu_addr;
From: Oak Zeng Oak.Zeng@amd.com
[ Upstream commit 065e4bdfa1f3ab2884c110394d8b7e7ebe3b988c ]
Previous codes assumes there are two sdma engines. This is not true e.g., Raven only has 1 SDMA engine. Fix the issue by using sdma engine number info in device_info.
Signed-off-by: Oak Zeng Oak.Zeng@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/amdkfd/kfd_device_queue_manager.c | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-)
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 4f22e745df51..189212cb3547 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1268,12 +1268,17 @@ int amdkfd_fence_wait_timeout(unsigned int *fence_addr, return 0; }
-static int unmap_sdma_queues(struct device_queue_manager *dqm, - unsigned int sdma_engine) +static int unmap_sdma_queues(struct device_queue_manager *dqm) { - return pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_SDMA, - KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0, false, - sdma_engine); + int i, retval = 0; + + for (i = 0; i < dqm->dev->device_info->num_sdma_engines; i++) { + retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_SDMA, + KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0, false, i); + if (retval) + return retval; + } + return retval; }
/* dqm->lock mutex has to be locked before calling this function */ @@ -1312,10 +1317,8 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, pr_debug("Before destroying queues, sdma queue count is : %u\n", dqm->sdma_queue_count);
- if (dqm->sdma_queue_count > 0) { - unmap_sdma_queues(dqm, 0); - unmap_sdma_queues(dqm, 1); - } + if (dqm->sdma_queue_count > 0) + unmap_sdma_queues(dqm);
retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE, filter, filter_param, false, 0);
From: Gen Zhang blackgod016574@gmail.com
[ Upstream commit 9f1f1a2dab38d4ce87a13565cf4dc1b73bef3a5f ]
In drm_load_edid_firmware(), fwstr is allocated by kstrdup(). And fwstr is dereferenced in the following codes. However, memory allocation functions such as kstrdup() may fail and returns NULL. Dereferencing this null pointer may cause the kernel go wrong. Thus we should check this kstrdup() operation. Further, if kstrdup() returns NULL, we should return ERR_PTR(-ENOMEM) to the caller site.
Signed-off-by: Gen Zhang blackgod016574@gmail.com Reviewed-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Jani Nikula jani.nikula@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20190524023222.GA5302@zhanggen... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_edid_load.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c index a4915099aaa9..a0e107abc40d 100644 --- a/drivers/gpu/drm/drm_edid_load.c +++ b/drivers/gpu/drm/drm_edid_load.c @@ -290,6 +290,8 @@ struct edid *drm_load_edid_firmware(struct drm_connector *connector) * the last one found one as a fallback. */ fwstr = kstrdup(edid_firmware, GFP_KERNEL); + if (!fwstr) + return ERR_PTR(-ENOMEM); edidstr = fwstr;
while ((edidname = strsep(&edidstr, ","))) {
From: Alex Williamson alex.williamson@redhat.com
[ Upstream commit 76002d8b48c4b08c9bd414517dd295e132ad910b ]
Commit 0e7df22401a3 ("PCI: Add sysfs sriov_drivers_autoprobe to control VF driver binding") allows the user to specify that drivers for VFs of a PF should not be probed, but it actually causes pci_device_probe() to return success back to the driver core in this case. Therefore by all sysfs appearances the device is bound to a driver, the driver link from the device exists as does the device link back from the driver, yet the driver's probe function is never called on the device. We also fail to do any sort of cleanup when we're prohibited from probing the device, the IRQ setup remains in place and we even hold a device reference.
Instead, abort with errno before any setup or references are taken when pci_device_can_probe() prevents us from trying to probe the device.
Link: https://lore.kernel.org/lkml/155672991496.20698.4279330795743262888.stgit@gi... Fixes: 0e7df22401a3 ("PCI: Add sysfs sriov_drivers_autoprobe to control VF driver binding") Signed-off-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci-driver.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 33f3f475e5c6..956ee7527d2c 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -414,6 +414,9 @@ static int pci_device_probe(struct device *dev) struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *drv = to_pci_driver(dev->driver);
+ if (!pci_device_can_probe(pci_dev)) + return -ENODEV; + pci_assign_irq(pci_dev);
error = pcibios_alloc_irq(pci_dev); @@ -421,12 +424,10 @@ static int pci_device_probe(struct device *dev) return error;
pci_dev_get(pci_dev); - if (pci_device_can_probe(pci_dev)) { - error = __pci_device_probe(drv, pci_dev); - if (error) { - pcibios_free_irq(pci_dev); - pci_dev_put(pci_dev); - } + error = __pci_device_probe(drv, pci_dev); + if (error) { + pcibios_free_irq(pci_dev); + pci_dev_put(pci_dev); }
return error;
From: Tomi Valkeinen tomi.valkeinen@ti.com
[ Upstream commit 3231573065ad4f4ecc5c9147b24f29f846dc0c2f ]
We need to know the link bandwidth to filter out modes we cannot support, so we need to have read the display props before doing the filtering.
To ensure we have up to date display props, call tc_get_display_props() in the beginning of tc_connector_get_modes().
Signed-off-by: Tomi Valkeinen tomi.valkeinen@ti.com Reviewed-by: Andrzej Hajda a.hajda@samsung.com Signed-off-by: Andrzej Hajda a.hajda@samsung.com Link: https://patchwork.freedesktop.org/patch/msgid/20190528082747.3631-22-tomi.va... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358767.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 391547358756..aaca5248da07 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -1149,6 +1149,13 @@ static int tc_connector_get_modes(struct drm_connector *connector) struct tc_data *tc = connector_to_tc(connector); struct edid *edid; unsigned int count; + int ret; + + ret = tc_get_display_props(tc); + if (ret < 0) { + dev_err(tc->dev, "failed to read display props: %d\n", ret); + return 0; + }
if (tc->panel && tc->panel->funcs && tc->panel->funcs->get_modes) { count = tc->panel->funcs->get_modes(tc->panel);
From: Jyri Sarha jsarha@ti.com
[ Upstream commit 8dbfc5b65023b67397aca28e8adb25c819f6398c ]
The pixel clock unit in the first two registers (0x00 and 0x01) of sii9022 is 10kHz, not 1kHz as in struct drm_display_mode. Division by 10 fixes the issue.
Signed-off-by: Jyri Sarha jsarha@ti.com Reviewed-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Andrzej Hajda a.hajda@samsung.com Link: https://patchwork.freedesktop.org/patch/msgid/1a2a8eae0b9d6333e7a5841026bf7f... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/sii902x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c index e59a13542333..0cc6dbbcddcf 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -261,10 +261,11 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge, struct regmap *regmap = sii902x->regmap; u8 buf[HDMI_INFOFRAME_SIZE(AVI)]; struct hdmi_avi_infoframe frame; + u16 pixel_clock_10kHz = adj->clock / 10; int ret;
- buf[0] = adj->clock; - buf[1] = adj->clock >> 8; + buf[0] = pixel_clock_10kHz & 0xff; + buf[1] = pixel_clock_10kHz >> 8; buf[2] = adj->vrefresh; buf[3] = 0x00; buf[4] = adj->hdisplay;
From: Thierry Reding treding@nvidia.com
[ Upstream commit 1e390478cfb527e34c9ab89ba57212cb05c33c51 ]
Recent versions of the DMA API debug code have started to warn about violations of the maximum DMA segment size. This is because the segment size defaults to 64 KiB, which can easily be exceeded in large buffer allocations such as used in DRM/KMS for framebuffers.
Technically the Tegra SMMU and ARM SMMU don't have a maximum segment size (they map individual pages irrespective of whether they are contiguous or not), so the choice of 4 MiB is a bit arbitrary here. The maximum segment size is a 32-bit unsigned integer, though, so we can't set it to the correct maximum size, which would be the size of the aperture.
Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/host1x/bus.c | 3 +++ include/linux/host1x.h | 2 ++ 2 files changed, 5 insertions(+)
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 815bdb42e3f0..0121fe7a4548 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -423,6 +423,9 @@ static int host1x_device_add(struct host1x *host1x,
of_dma_configure(&device->dev, host1x->dev->of_node, true);
+ device->dev.dma_parms = &device->dma_parms; + dma_set_max_seg_size(&device->dev, SZ_4M); + err = host1x_device_parse_dt(device, driver); if (err < 0) { kfree(device); diff --git a/include/linux/host1x.h b/include/linux/host1x.h index 89110d896d72..aef6e2f73802 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -310,6 +310,8 @@ struct host1x_device { struct list_head clients;
bool registered; + + struct device_dma_parameters dma_parms; };
static inline struct host1x_device *to_host1x_device(struct device *dev)
From: Daniel Vetter daniel.vetter@ffwll.ch
[ Upstream commit 1882018a70e06376234133e69ede9dd743b4dbd9 ]
We can be called from any context, we need to be prepared.
Noticed this while hacking on vkms, which calls this function from a normal worker. Which really upsets lockdep.
Cc: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Cc: Tomeu Vizoso tomeu.vizoso@collabora.com Cc: Emil Velikov emil.velikov@collabora.com Cc: Benjamin Gaignard benjamin.gaignard@linaro.org Reviewed-by: Benjamin Gaignard benjamin.gaignard@linaro.org Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20190605194556.16744-1-daniel.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_debugfs_crc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index 99961192bf03..a334a82fcb36 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -379,8 +379,9 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, struct drm_crtc_crc *crc = &crtc->crc; struct drm_crtc_crc_entry *entry; int head, tail; + unsigned long flags;
- spin_lock(&crc->lock); + spin_lock_irqsave(&crc->lock, flags);
/* Caller may not have noticed yet that userspace has stopped reading */ if (!crc->entries) { @@ -411,7 +412,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, head = (head + 1) & (DRM_CRC_ENTRIES_NR - 1); crc->head = head;
- spin_unlock(&crc->lock); + spin_unlock_irqrestore(&crc->lock, flags);
wake_up_interruptible(&crc->wq);
From: Daniel Vetter daniel.vetter@ffwll.ch
[ Upstream commit d99004d7201aa653658ff2390d6e516567c96ebc ]
I. was. blind.
Caught with vkms, which has some really slow crc computation function.
Fixes: 1882018a70e0 ("drm/crc-debugfs: User irqsafe spinlock in drm_crtc_add_crc_entry") Cc: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Cc: Tomeu Vizoso tomeu.vizoso@collabora.com Cc: Emil Velikov emil.velikov@collabora.com Cc: Benjamin Gaignard benjamin.gaignard@linaro.org Cc: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Emil Velikov emil.velikov@collabora.com Reviewed-by: Benjamin Gaignard benjamin.gaignard@linaro.org Signed-off-by: Daniel Vetter daniel.vetter@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20190606211544.5389-1-daniel.v... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_debugfs_crc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index a334a82fcb36..c88e5ff41add 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -385,7 +385,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame,
/* Caller may not have noticed yet that userspace has stopped reading */ if (!crc->entries) { - spin_unlock(&crc->lock); + spin_unlock_irqrestore(&crc->lock, flags); return -EINVAL; }
@@ -396,7 +396,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, bool was_overflow = crc->overflow;
crc->overflow = true; - spin_unlock(&crc->lock); + spin_unlock_irqrestore(&crc->lock, flags);
if (!was_overflow) DRM_ERROR("Overflow of CRC buffer, userspace reads too slow.\n");
From: Wang Hai wanghai26@huawei.com
[ Upstream commit 65f1a0d39c289bb6fc85635528cd36c4b07f560e ]
If bus_register fails. On its error handling path, it has cleaned up what it has done. There is no need to call bus_unregister again. Otherwise, if bus_unregister is called, issues such as null-ptr-deref will arise.
Syzkaller report this:
kobject_add_internal failed for memstick (error: -12 parent: bus) BUG: KASAN: null-ptr-deref in sysfs_remove_file_ns+0x1b/0x40 fs/sysfs/file.c:467 Read of size 8 at addr 0000000000000078 by task syz-executor.0/4460
Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xa9/0x10e lib/dump_stack.c:113 __kasan_report+0x171/0x18d mm/kasan/report.c:321 kasan_report+0xe/0x20 mm/kasan/common.c:614 sysfs_remove_file_ns+0x1b/0x40 fs/sysfs/file.c:467 sysfs_remove_file include/linux/sysfs.h:519 [inline] bus_remove_file+0x6c/0x90 drivers/base/bus.c:145 remove_probe_files drivers/base/bus.c:599 [inline] bus_unregister+0x6e/0x100 drivers/base/bus.c:916 ? 0xffffffffc1590000 memstick_init+0x7a/0x1000 [memstick] do_one_initcall+0xb9/0x3b5 init/main.c:914 do_init_module+0xe0/0x330 kernel/module.c:3468 load_module+0x38eb/0x4270 kernel/module.c:3819 __do_sys_finit_module+0x162/0x190 kernel/module.c:3909 do_syscall_64+0x72/0x2a0 arch/x86/entry/common.c:298 entry_SYSCALL_64_after_hwframe+0x49/0xbe
Fixes: baf8532a147d ("memstick: initial commit for Sony MemoryStick support") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Wang Hai wanghai26@huawei.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memstick/core/memstick.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index 1246d69ba187..b1564cacd19e 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -629,13 +629,18 @@ static int __init memstick_init(void) return -ENOMEM;
rc = bus_register(&memstick_bus_type); - if (!rc) - rc = class_register(&memstick_host_class); + if (rc) + goto error_destroy_workqueue;
- if (!rc) - return 0; + rc = class_register(&memstick_host_class); + if (rc) + goto error_bus_unregister; + + return 0;
+error_bus_unregister: bus_unregister(&memstick_bus_type); +error_destroy_workqueue: destroy_workqueue(workqueue);
return rc;
From: Kefeng Wang wangkefeng.wang@huawei.com
[ Upstream commit c7ad9ba0611c53cfe194223db02e3bca015f0674 ]
When modprobe/rmmod/modprobe module, if platform_driver_register() fails, the kernel complained,
proc_dir_entry 'driver/digicolor-usart' already registered WARNING: CPU: 1 PID: 5636 at fs/proc/generic.c:360 proc_register+0x19d/0x270
Fix this by adding uart_unregister_driver() when platform_driver_register() fails.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Kefeng Wang wangkefeng.wang@huawei.com Acked-by: Baruch Siach baruch@tkos.co.il Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/digicolor-usart.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/digicolor-usart.c b/drivers/tty/serial/digicolor-usart.c index f460cca139e2..13ac36e2da4f 100644 --- a/drivers/tty/serial/digicolor-usart.c +++ b/drivers/tty/serial/digicolor-usart.c @@ -541,7 +541,11 @@ static int __init digicolor_uart_init(void) if (ret) return ret;
- return platform_driver_register(&digicolor_uart_platform); + ret = platform_driver_register(&digicolor_uart_platform); + if (ret) + uart_unregister_driver(&digicolor_uart); + + return ret; } module_init(digicolor_uart_init);
From: Jorge Ramirez-Ortiz jorge.ramirez-ortiz@linaro.org
[ Upstream commit ba3684f99f1b25d2a30b6956d02d339d7acb9799 ]
The function msm_wait_for_xmitr can be taken with interrupts disabled. In order to avoid a potential system lockup - demonstrated under stress testing conditions on SoC QCS404/5 - make sure we wait for a bounded amount of time.
Tested on SoC QCS404.
Signed-off-by: Jorge Ramirez-Ortiz jorge.ramirez-ortiz@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/msm_serial.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 0f41b936da03..310bbae515b0 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -383,10 +383,14 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base)
static inline void msm_wait_for_xmitr(struct uart_port *port) { + unsigned int timeout = 500000; + while (!(msm_read(port, UART_SR) & UART_SR_TX_EMPTY)) { if (msm_read(port, UART_ISR) & UART_ISR_TX_READY) break; udelay(1); + if (!timeout--) + break; } msm_write(port, UART_CR_CMD_RESET_TX_READY, UART_CR); }
From: Rautkoski Kimmo EXT ext-kimmo.rautkoski@vaisala.com
[ Upstream commit db1b5bc047b3cadaedab3826bba82c3d9e023c4b ]
Interrupt handler checked THRE bit (transmitter holding register empty) in LSR to detect if TX fifo is empty. In case when there is only receive interrupts the TX handling got called because THRE bit in LSR is set when there is no transmission (FIFO empty). TX handling caused TX stop, which in RS-485 half-duplex mode actually resets receiver FIFO. This is not desired during reception because of possible data loss.
The fix is to check if THRI is set in IER in addition of the TX fifo status. THRI in IER is set when TX is started and cleared when TX is stopped. This ensures that TX handling is only called when there is really transmission on going and an interrupt for THRE and not when there are only RX interrupts.
Signed-off-by: Kimmo Rautkoski ext-kimmo.rautkoski@vaisala.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index e26d87b6ffc5..aa4de6907f77 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1874,7 +1874,8 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) status = serial8250_rx_chars(up, status); } serial8250_modem_status(up); - if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE)) + if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE) && + (up->ier & UART_IER_THRI)) serial8250_tx_chars(up);
spin_unlock_irqrestore(&port->lock, flags);
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit f04bee34d6e35df26cbb2d65e801adfd0d8fe20d ]
[Why] Unlike our regular connectors, MST connectors don't start off with an initial connector state. This causes a NULL pointer dereference to occur when attaching the bpc property since it tries to modify the connector state.
We need an initial connector state on the connector to avoid the crash.
[How] Use our reset helper to allocate an initial state and reset the values to their defaults. We were already doing this before, just not for MST connectors.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index dac7978f5ee1..221de241535a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3644,6 +3644,13 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, { struct amdgpu_device *adev = dm->ddev->dev_private;
+ /* + * Some of the properties below require access to state, like bpc. + * Allocate some default initial connector state with our reset helper. + */ + if (aconnector->base.funcs->reset) + aconnector->base.funcs->reset(&aconnector->base); + aconnector->connector_id = link_index; aconnector->dc_link = link; aconnector->base.interlace_allowed = false; @@ -3811,9 +3818,6 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, &aconnector->base, &amdgpu_dm_connector_helper_funcs);
- if (aconnector->base.funcs->reset) - aconnector->base.funcs->reset(&aconnector->base); - amdgpu_dm_connector_init_helper( dm, aconnector,
From: David Riley davidriley@chromium.org
[ Upstream commit 9ff3a5c88e1f1ab17a31402b96d45abe14aab9d7 ]
After data is copied to the cache entry, atomic_set is used indicate that the data is the entry is valid without appropriate memory barriers. Similarly the read side was missing the corresponding memory barriers.
Signed-off-by: David Riley davidriley@chromium.org Link: http://patchwork.freedesktop.org/patch/msgid/20190610211810.253227-5-davidri... Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 3 +++ drivers/gpu/drm/virtio/virtgpu_vq.c | 2 ++ 2 files changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 7bdf6f0e58a5..8d2f5ded86d6 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -528,6 +528,9 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev, if (!ret) return -EBUSY;
+ /* is_valid check must proceed before copy of the cache entry. */ + smp_rmb(); + ptr = cache_ent->caps_cache;
copy_exit: diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 020070d483d3..c8a581b1f4c4 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -588,6 +588,8 @@ static void virtio_gpu_cmd_capset_cb(struct virtio_gpu_device *vgdev, cache_ent->id == le32_to_cpu(cmd->capset_id)) { memcpy(cache_ent->caps_cache, resp->capset_data, cache_ent->size); + /* Copy must occur before is_valid is signalled. */ + smp_wmb(); atomic_set(&cache_ent->is_valid, 1); break; }
From: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com
[ Upstream commit d4a36e82924d3305a17ac987a510f3902df5a4b2 ]
This patch fixes memory leak at error paths of the probe function. In for_each_child_of_node, if the loop returns, the driver should call of_put_node() before returns.
Reported-by: Julia Lawall julia.lawall@lip6.fr Fixes: 1233f59f745b237 ("phy: Renesas R-Car Gen2 PHY driver") Signed-off-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/renesas/phy-rcar-gen2.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/phy/renesas/phy-rcar-gen2.c b/drivers/phy/renesas/phy-rcar-gen2.c index 97d4dd6ea924..aa02b19b7e0e 100644 --- a/drivers/phy/renesas/phy-rcar-gen2.c +++ b/drivers/phy/renesas/phy-rcar-gen2.c @@ -288,6 +288,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) error = of_property_read_u32(np, "reg", &channel_num); if (error || channel_num > 2) { dev_err(dev, "Invalid "reg" property\n"); + of_node_put(np); return error; } channel->select_mask = select_mask[channel_num]; @@ -303,6 +304,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) &rcar_gen2_phy_ops); if (IS_ERR(phy->phy)) { dev_err(dev, "Failed to create PHY\n"); + of_node_put(np); return PTR_ERR(phy->phy); } phy_set_drvdata(phy->phy, phy);
From: Hariprasad Kelam hariprasad.kelam@gmail.com
[ Upstream commit 88099f53cc3717437f5fc9cf84205c5b65118377 ]
this patch fixes below compilation error
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_hw_sequencer.c: In function ‘dcn10_apply_ctx_for_surface’: drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_hw_sequencer.c:2378:3: error: implicit declaration of function ‘udelay’ [-Werror=implicit-function-declaration] udelay(underflow_check_delay_us);
Signed-off-by: Hariprasad Kelam hariprasad.kelam@gmail.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 7736ef123e9b..ead221ccb93e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -23,6 +23,7 @@ * */
+#include <linux/delay.h> #include "dm_services.h" #include "core_types.h" #include "resource.h"
From: Nathan Lynch nathanl@linux.ibm.com
[ Upstream commit e59a175faa8df9d674247946f2a5a9c29c835725 ]
CPU online/offline code paths are sensitive to parts of the device tree (various cpu node properties, cache nodes) that can be changed as a result of a migration.
Prevent CPU hotplug while the device tree potentially is inconsistent.
Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch nathanl@linux.ibm.com Reviewed-by: Gautham R. Shenoy ego@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/pseries/mobility.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index f0e30dc94988..7b60fcf04dc4 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -9,6 +9,7 @@ * 2 as published by the Free Software Foundation. */
+#include <linux/cpu.h> #include <linux/kernel.h> #include <linux/kobject.h> #include <linux/smp.h> @@ -344,11 +345,19 @@ void post_mobility_fixup(void) if (rc) printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc);
+ /* + * We don't want CPUs to go online/offline while the device + * tree is being updated. + */ + cpus_read_lock(); + rc = pseries_devicetree_update(MIGRATION_SCOPE); if (rc) printk(KERN_ERR "Post-mobility device tree update " "failed: %d\n", rc);
+ cpus_read_unlock(); + /* Possibly switch to a new RFI flush type */ pseries_setup_rfi_flush();
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 99b9683f2142b20bad78e61f7f829e8714e45685 ]
When fixing up the clock in vop_crtc_mode_fixup() we're not doing it quite correctly. Specifically if we've got the true clock 266666667 Hz, we'll perform this calculation: 266666667 / 1000 => 266666
Later when we try to set the clock we'll do clk_set_rate(266666 * 1000). The common clock framework won't actually pick the proper clock in this case since it always wants clocks <= the specified one.
Let's solve this by using DIV_ROUND_UP.
Fixes: b59b8de31497 ("drm/rockchip: return a true clock rate to adjusted_mode") Signed-off-by: Douglas Anderson dianders@chromium.org Signed-off-by: Sean Paul seanpaul@chromium.org Reviewed-by: Yakir Yang ykk@rock-chips.com Signed-off-by: Heiko Stuebner heiko@sntech.de Link: https://patchwork.freedesktop.org/patch/msgid/20190614224730.98622-1-diander... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index f8f9ae6622eb..873624a11ce8 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -880,7 +880,8 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, struct vop *vop = to_vop(crtc);
adjusted_mode->clock = - clk_round_rate(vop->dclk, mode->clock * 1000) / 1000; + DIV_ROUND_UP(clk_round_rate(vop->dclk, mode->clock * 1000), + 1000);
return true; }
From: Young Xiao 92siuyang@gmail.com
[ Upstream commit 936d3e536dcf88ce80d27bdb637009b13dba6d8c ]
The incorrect limit for the for_each_set_bit loop was noticed whilst fixing this other case. Note that as we only have 3 possible entries a the moment and the value was set to 4, the bug would not have any effect currently. It will bite fairly soon though, so best fix it now.
See commit ef4b4856593f ("iio:core: Fix bug in length of event info_mask and catch unhandled bits set in masks.") for details.
Signed-off-by: Young Xiao 92siuyang@gmail.com Reviewed-by: Alexandru Ardelean alexandru.ardelean@analog.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/industrialio-core.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 49d4b4f1a457..4bc9ea48da07 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1112,6 +1112,8 @@ static int iio_device_add_info_mask_type_avail(struct iio_dev *indio_dev, char *avail_postfix;
for_each_set_bit(i, infomask, sizeof(*infomask) * 8) { + if (i >= ARRAY_SIZE(iio_chan_info_postfix)) + return -EINVAL; avail_postfix = kasprintf(GFP_KERNEL, "%s_available", iio_chan_info_postfix[i]);
From: Sergey Organov sorganov@gmail.com
[ Upstream commit 4e828c3e09201512be5ee162393f334321f7cf01 ]
imx_uart_set_termios() called imx_uart_rts_active(), or imx_uart_rts_inactive() before taking port->port.lock.
As a consequence, sport->port.mctrl that these functions modify could have been changed without holding port->port.lock.
Moved locking of port->port.lock above the calls to fix the issue.
Signed-off-by: Sergey Organov sorganov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/imx.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 0f67197a3783..105de92b0b3b 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -382,6 +382,7 @@ static void imx_uart_ucrs_restore(struct imx_port *sport, } #endif
+/* called with port.lock taken and irqs caller dependent */ static void imx_uart_rts_active(struct imx_port *sport, u32 *ucr2) { *ucr2 &= ~(UCR2_CTSC | UCR2_CTS); @@ -390,6 +391,7 @@ static void imx_uart_rts_active(struct imx_port *sport, u32 *ucr2) mctrl_gpio_set(sport->gpios, sport->port.mctrl); }
+/* called with port.lock taken and irqs caller dependent */ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2) { *ucr2 &= ~UCR2_CTSC; @@ -399,6 +401,7 @@ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2) mctrl_gpio_set(sport->gpios, sport->port.mctrl); }
+/* called with port.lock taken and irqs caller dependent */ static void imx_uart_rts_auto(struct imx_port *sport, u32 *ucr2) { *ucr2 |= UCR2_CTSC; @@ -1554,6 +1557,16 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, old_csize = CS8; }
+ del_timer_sync(&sport->timer); + + /* + * Ask the core to calculate the divisor for us. + */ + baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); + quot = uart_get_divisor(port, baud); + + spin_lock_irqsave(&sport->port.lock, flags); + if ((termios->c_cflag & CSIZE) == CS8) ucr2 = UCR2_WS | UCR2_SRST | UCR2_IRTS; else @@ -1597,16 +1610,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, ucr2 |= UCR2_PROE; }
- del_timer_sync(&sport->timer); - - /* - * Ask the core to calculate the divisor for us. - */ - baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); - quot = uart_get_divisor(port, baud); - - spin_lock_irqsave(&sport->port.lock, flags); - sport->port.read_status_mask = 0; if (termios->c_iflag & INPCK) sport->port.read_status_mask |= (URXD_FRMERR | URXD_PRERR);
From: Serge Semin fancer.lancer@gmail.com
[ Upstream commit 13b18d35909707571af9539f7731389fbf0feb31 ]
A bug was introduced by commit b3b576461864 ("tty: serial_core: convert uart_open to use tty_port_open"). It caused a constant warning printed into the system log regarding the tty and port counter mismatch:
[ 21.644197] ttyS ttySx: tty_port_close_start: tty->count = 1 port count = 2
in case if session hangup was detected so the warning is printed starting from the second open-close iteration.
Particularly the problem was discovered in situation when there is a serial tty device without hardware back-end being setup. It is considered by the tty-serial subsystems as a hardware problem with session hang up. In this case uart_startup() will return a positive value with TTY_IO_ERROR flag set in corresponding tty_struct instance. The same value will get passed to be returned from the activate() callback and then being returned from tty_port_open(). But since in this case tty_port_block_til_ready() isn't called the TTY_PORT_ACTIVE flag isn't set (while the method had been called before tty_port_open conversion was introduced and the rest of the subsystem code expected the bit being set in this case), which prevents the uart_hangup() method to perform any cleanups including the tty port counter setting to zero. So the next attempt to open/close the tty device will discover the counters mismatch.
In order to fix the problem we need to manually set the TTY_PORT_ACTIVE flag in case if uart_startup() returned a positive value. In this case the hang up procedure will perform a full set of cleanup actions including the port ref-counter resetting.
Fixes: b3b576461864 "tty: serial_core: convert uart_open to use tty_port_open" Signed-off-by: Serge Semin fancer.lancer@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/serial_core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 8dbeb14a1e3a..fe9261ffe3db 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1738,6 +1738,7 @@ static int uart_port_activate(struct tty_port *port, struct tty_struct *tty) { struct uart_state *state = container_of(port, struct uart_state, port); struct uart_port *uport; + int ret;
uport = uart_port_check(state); if (!uport || uport->flags & UPF_DEAD) @@ -1748,7 +1749,11 @@ static int uart_port_activate(struct tty_port *port, struct tty_struct *tty) /* * Start up the serial port. */ - return uart_startup(tty, state, 0); + ret = uart_startup(tty, state, 0); + if (ret > 0) + tty_port_set_active(port, 1); + + return ret; }
static const char *uart_type(struct uart_port *port)
From: Andrzej Pietrasiewicz andrzej.p@collabora.com
[ Upstream commit 508595515f4bcfe36246e4a565cf280937aeaade ]
In some cases the "Allocate & copy" block in ffs_epfile_io() is not executed. Consequently, in such a case ffs_alloc_buffer() is never called and struct ffs_io_data is not initialized properly. This in turn leads to problems when ffs_free_buffer() is called at the end of ffs_epfile_io().
This patch uses kzalloc() instead of kmalloc() in the aio case and memset() in non-aio case to properly initialize struct ffs_io_data.
Signed-off-by: Andrzej Pietrasiewicz andrzej.p@collabora.com Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_fs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index aa15593a3ac4..2050993fb58b 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1101,11 +1101,12 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from) ENTER();
if (!is_sync_kiocb(kiocb)) { - p = kmalloc(sizeof(io_data), GFP_KERNEL); + p = kzalloc(sizeof(io_data), GFP_KERNEL); if (unlikely(!p)) return -ENOMEM; p->aio = true; } else { + memset(p, 0, sizeof(*p)); p->aio = false; }
@@ -1137,11 +1138,12 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to) ENTER();
if (!is_sync_kiocb(kiocb)) { - p = kmalloc(sizeof(io_data), GFP_KERNEL); + p = kzalloc(sizeof(io_data), GFP_KERNEL); if (unlikely(!p)) return -ENOMEM; p->aio = true; } else { + memset(p, 0, sizeof(*p)); p->aio = false; }
From: EJ Hsu ejh@nvidia.com
[ Upstream commit e70b3f5da00119e057b7faa557753fee7f786f17 ]
This change is to fix below warning message in following scenario: usb_composite_setup_continue: Unexpected call
When system tried to enter suspend, the fsg_disable() will be called to disable fsg driver and send a signal to fsg_main_thread. However, at this point, the fsg_main_thread has already been frozen and can not respond to this signal. So, this signal will be pended until fsg_main_thread wakes up.
Once system resumes from suspend, fsg_main_thread will detect a signal pended and do some corresponding action (in handle_exception()). Then, host will send some setup requests (get descriptor, set configuration...) to UDC driver trying to enumerate this device. During the handling of "set configuration" request, it will try to sync up with fsg_main_thread by sending a signal (which is the same as the signal sent by fsg_disable) to it. In a similar manner, once the fsg_main_thread receives this signal, it will call handle_exception() to handle the request.
However, if the fsg_main_thread wakes up from suspend a little late and "set configuration" request from Host arrives a little earlier, fsg_main_thread might come across the request from "set configuration" when it handles the signal from fsg_disable(). In this case, it will handle this request as well. So, when fsg_main_thread tries to handle the signal sent from "set configuration" later, there will nothing left to do and warning message "Unexpected call" is printed.
Acked-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: EJ Hsu ejh@nvidia.com Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_mass_storage.c | 21 ++++++++++++++------ drivers/usb/gadget/function/storage_common.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 1074cb82ec17..c712b338f05f 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -2293,8 +2293,7 @@ static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) static void fsg_disable(struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); - fsg->common->new_fsg = NULL; - raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); + raise_exception(fsg->common, FSG_STATE_DISCONNECT); }
@@ -2307,6 +2306,7 @@ static void handle_exception(struct fsg_common *common) enum fsg_state old_state; struct fsg_lun *curlun; unsigned int exception_req_tag; + struct fsg_dev *fsg;
/* * Clear the existing signals. Anything but SIGUSR1 is converted @@ -2413,9 +2413,19 @@ static void handle_exception(struct fsg_common *common) break;
case FSG_STATE_CONFIG_CHANGE: - do_set_interface(common, common->new_fsg); - if (common->new_fsg) + fsg = common->new_fsg; + /* + * Add a check here to double confirm if a disconnect event + * occurs and common->new_fsg has been cleared. + */ + if (fsg) { + do_set_interface(common, fsg); usb_composite_setup_continue(common->cdev); + } + break; + + case FSG_STATE_DISCONNECT: + do_set_interface(common, NULL); break;
case FSG_STATE_EXIT: @@ -2989,8 +2999,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(fsg, "unbind\n"); if (fsg->common->fsg == fsg) { - fsg->common->new_fsg = NULL; - raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); + raise_exception(fsg->common, FSG_STATE_DISCONNECT); /* FIXME: make interruptible or killable somehow? */ wait_event(common->fsg_wait, common->fsg != fsg); } diff --git a/drivers/usb/gadget/function/storage_common.h b/drivers/usb/gadget/function/storage_common.h index e5e3a2553aaa..12687f7e3de9 100644 --- a/drivers/usb/gadget/function/storage_common.h +++ b/drivers/usb/gadget/function/storage_common.h @@ -161,6 +161,7 @@ enum fsg_state { FSG_STATE_ABORT_BULK_OUT, FSG_STATE_PROTOCOL_RESET, FSG_STATE_CONFIG_CHANGE, + FSG_STATE_DISCONNECT, FSG_STATE_EXIT, FSG_STATE_TERMINATED };
From: Raul E Rangel rrangel@chromium.org
[ Upstream commit de23f0b757766d9fae59df97da6e8bdc5b231351 ]
The O2 controller supports 8-bit EMMC access.
JESD84-B51 section A.6.3.a defines the bus testing procedure that `mmc_select_bus_width()` implements. This is used to determine the actual bus width of the eMMC.
Signed-off-by: Raul E Rangel rrangel@chromium.org Acked-by: Adrian Hunter adrian.hunter@intel.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-pci-o2micro.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c index fa8d9da2ab7f..e248d7945c06 100644 --- a/drivers/mmc/host/sdhci-pci-o2micro.c +++ b/drivers/mmc/host/sdhci-pci-o2micro.c @@ -290,11 +290,21 @@ int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot) { struct sdhci_pci_chip *chip; struct sdhci_host *host; - u32 reg; + u32 reg, caps; int ret;
chip = slot->chip; host = slot->host; + + caps = sdhci_readl(host, SDHCI_CAPABILITIES); + + /* + * mmc_select_bus_width() will test the bus to determine the actual bus + * width. + */ + if (caps & SDHCI_CAN_DO_8BIT) + host->mmc->caps |= MMC_CAP_8_BIT_DATA; + switch (chip->pdev->device) { case PCI_DEVICE_ID_O2_SDS0: case PCI_DEVICE_ID_O2_SEABIRD0:
From: Alexey Kardashevskiy aik@ozlabs.ru
[ Upstream commit df5be5be8735ef2ae80d5ae1f2453cd81a035c4b ]
When the firmware does PCI BAR resource allocation, it passes the assigned addresses and flags (prefetch/64bit/...) via the "reg" property of a PCI device device tree node so the kernel does not need to do resource allocation.
The flags are stored in resource::flags - the lower byte stores PCI_BASE_ADDRESS_SPACE/etc bits and the other bytes are IORESOURCE_IO/etc. Some flags from PCI_BASE_ADDRESS_xxx and IORESOURCE_xxx are duplicated, such as PCI_BASE_ADDRESS_MEM_PREFETCH/PCI_BASE_ADDRESS_MEM_TYPE_64/etc. When parsing the "reg" property, we copy the prefetch flag but we skip on PCI_BASE_ADDRESS_MEM_TYPE_64 which leaves the flags out of sync.
The missing IORESOURCE_MEM_64 flag comes into play under 2 conditions: 1. we remove PCI_PROBE_ONLY for pseries (by hacking pSeries_setup_arch() or by passing "/chosen/linux,pci-probe-only"); 2. we request resource alignment (by passing pci=resource_alignment= via the kernel cmd line to request PAGE_SIZE alignment or defining ppc_md.pcibios_default_alignment which returns anything but 0). Note that the alignment requests are ignored if PCI_PROBE_ONLY is enabled.
With 1) and 2), the generic PCI code in the kernel unconditionally decides to: - reassign the BARs in pci_specified_resource_alignment() (works fine) - write new BARs to the device - this fails for 64bit BARs as the generic code looks at IORESOURCE_MEM_64 (not set) and writes only lower 32bits of the BAR and leaves the upper 32bit unmodified which breaks BAR mapping in the hypervisor.
This fixes the issue by copying the flag. This is useful if we want to enforce certain BAR alignment per platform as handling subpage sized BARs is proven to cause problems with hotplug (SLOF already aligns BARs to 64k).
Signed-off-by: Alexey Kardashevskiy aik@ozlabs.ru Reviewed-by: Sam Bobroff sbobroff@linux.ibm.com Reviewed-by: Oliver O'Halloran oohall@gmail.com Reviewed-by: Shawn Anastasio shawn@anastas.io Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/pci_of_scan.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 98f04725def7..c101b321dece 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -45,6 +45,8 @@ unsigned int pci_parse_of_flags(u32 addr0, int bridge) if (addr0 & 0x02000000) { flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY; flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64; + if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) + flags |= IORESOURCE_MEM_64; flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M; if (addr0 & 0x40000000) flags |= IORESOURCE_PREFETCH
From: Sean Paul seanpaul@chromium.org
[ Upstream commit 4368a1539c6b41ac3cddc06f5a5117952998804c ]
add_display_components() calls of_platform_populate, and we depopluate on pdev remove, but not when probe fails. So if we get a probe deferral in one of the components, we won't depopulate the platform. This causes the core to keep references to devices which should be destroyed, which causes issues when those same devices try to re-initialize on the next probe attempt.
I think this is the reason we had issues with the gmu's device-managed resources on deferral (worked around in commit 94e3a17f33a5).
Reviewed-by: Rob Clark robdclark@chromium.org Signed-off-by: Sean Paul seanpaul@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20190617201301.133275-3-sean@p... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_drv.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index c1abad8a8612..ed9a3a1e50ef 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1321,16 +1321,24 @@ static int msm_pdev_probe(struct platform_device *pdev)
ret = add_gpu_components(&pdev->dev, &match); if (ret) - return ret; + goto fail;
/* on all devices that I am aware of, iommu's which can map * any address the cpu can see are used: */ ret = dma_set_mask_and_coherent(&pdev->dev, ~0); if (ret) - return ret; + goto fail; + + ret = component_master_add_with_match(&pdev->dev, &msm_drm_ops, match); + if (ret) + goto fail;
- return component_master_add_with_match(&pdev->dev, &msm_drm_ops, match); + return 0; + +fail: + of_platform_depopulate(&pdev->dev); + return ret; }
static int msm_pdev_remove(struct platform_device *pdev)
From: Stefan Roese sr@denx.de
[ Upstream commit d99482673f950817b30caf3fcdfb31179b050ce1 ]
This patch adds a check for the GPIOs property existence, before the GPIO is requested. This fixes an issue seen when the 8250 mctrl_gpio support is added (2nd patch in this patch series) on x86 platforms using ACPI.
Here Mika's comments from 2016-08-09:
" I noticed that with v4.8-rc1 serial console of some of our Broxton systems does not work properly anymore. I'm able to see output but input does not work.
I bisected it down to commit 4ef03d328769eddbfeca1f1c958fdb181a69c341 ("tty/serial/8250: use mctrl_gpio helpers").
The reason why it fails is that in ACPI we do not have names for GPIOs (except when _DSD is used) so we use the "idx" to index into _CRS GPIO resources. Now mctrl_gpio_init_noauto() goes through a list of GPIOs calling devm_gpiod_get_index_optional() passing "idx" of 0 for each. The UART device in Broxton has following (simplified) ACPI description:
Device (URT4) { ... Name (_CRS, ResourceTemplate () { GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly, "\_SB.GPO0", 0x00, ResourceConsumer) { 0x003A } GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly, "\_SB.GPO0", 0x00, ResourceConsumer) { 0x003D } })
In this case it finds the first GPIO (0x003A which happens to be RX pin for that UART), turns it into GPIO which then breaks input for the UART device. This also breaks systems with bluetooth connected to UART (those typically have some GPIOs in their _CRS).
Any ideas how to fix this?
We cannot just drop the _CRS index lookup fallback because that would break many existing machines out there so maybe we can limit this to only DT enabled machines. Or alternatively probe if the property first exists before trying to acquire the GPIOs (using device_property_present()). "
This patch implements the fix suggested by Mika in his statement above.
Signed-off-by: Stefan Roese sr@denx.de Reviewed-by: Mika Westerberg mika.westerberg@linux.intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Tested-by: Yegor Yefremov yegorslists@googlemail.com Cc: Mika Westerberg mika.westerberg@linux.intel.com Cc: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: Yegor Yefremov yegorslists@googlemail.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Giulio Benetti giulio.benetti@micronovasrl.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/serial_mctrl_gpio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index 1c06325beaca..07f318603e74 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c @@ -12,6 +12,7 @@ #include <linux/termios.h> #include <linux/serial_core.h> #include <linux/module.h> +#include <linux/property.h>
#include "serial_mctrl_gpio.h"
@@ -115,6 +116,19 @@ struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx)
for (i = 0; i < UART_GPIO_MAX; i++) { enum gpiod_flags flags; + char *gpio_str; + bool present; + + /* Check if GPIO property exists and continue if not */ + gpio_str = kasprintf(GFP_KERNEL, "%s-gpios", + mctrl_gpios_desc[i].name); + if (!gpio_str) + continue; + + present = device_property_present(dev, gpio_str); + kfree(gpio_str); + if (!present) + continue;
if (mctrl_gpios_desc[i].dir_out) flags = GPIOD_OUT_LOW;
From: Marek Vasut marek.vasut+renesas@gmail.com
[ Upstream commit dc6b698a86fe40a50525433eb8e92a267847f6f9 ]
With CONFIG_PROVE_LOCKING=y, using sysfs to remove a bridge with a device below it causes a lockdep warning, e.g.,
# echo 1 > /sys/class/pci_bus/0000:00/device/0000:00:00.0/remove ============================================ WARNING: possible recursive locking detected ... pci_bus 0000:01: busn_res: [bus 01] is released
The remove recursively removes the subtree below the bridge. Each call uses a different lock so there's no deadlock, but the locks were all created with the same lockdep key so the lockdep checker can't tell them apart.
Mark the "remove" sysfs attribute with __ATTR_IGNORE_LOCKDEP() as it is safe to ignore the lockdep check between different "remove" kernfs instances.
There's discussion about a similar issue in USB at [1], which resulted in 356c05d58af0 ("sysfs: get rid of some lockdep false positives") and e9b526fe7048 ("i2c: suppress lockdep warning on delete_device"), which do basically the same thing for USB "remove" and i2c "delete_device" files.
[1] https://lore.kernel.org/r/Pine.LNX.4.44L0.1204251436140.1206-100000@iolanthe... Link: https://lore.kernel.org/r/20190526225151.3865-1-marek.vasut@gmail.com Signed-off-by: Marek Vasut marek.vasut+renesas@gmail.com [bhelgaas: trim commit log, details at above links] Signed-off-by: Bjorn Helgaas bhelgaas@google.com Cc: Geert Uytterhoeven geert+renesas@glider.be Cc: Phil Edworthy phil.edworthy@renesas.com Cc: Simon Horman horms+renesas@verge.net.au Cc: Tejun Heo tj@kernel.org Cc: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 9ecfe13157c0..1edf5a1836ea 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -478,7 +478,7 @@ static ssize_t remove_store(struct device *dev, struct device_attribute *attr, pci_stop_and_remove_bus_device_locked(to_pci_dev(dev)); return count; } -static struct device_attribute dev_remove_attr = __ATTR(remove, +static struct device_attribute dev_remove_attr = __ATTR_IGNORE_LOCKDEP(remove, (S_IWUSR|S_IWGRP), NULL, remove_store);
From: Fabrice Gasnier fabrice.gasnier@st.com
[ Upstream commit 79b4499524ed659fb76323efc30f3dc03967c88f ]
During probe, return the "get_irq" error value instead of -EINVAL which allows the driver to be deferred probed if needed. Fix also the case where of_irq_get() returns a negative value. Note : On failure of_irq_get() returns 0 or a negative value while platform_get_irq() returns a negative value.
Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver") Reviewed-by: Pierre-Yves MORDRET pierre-yves.mordret@st.com Signed-off-by: Fabien Dessenne fabien.dessenne@st.com Signed-off-by: Fabrice Gasnier fabrice.gasnier@st.com Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-stm32f7.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index a492da9fd0d3..ac9c9486b834 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -24,7 +24,6 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> -#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/reset.h> @@ -1782,15 +1781,14 @@ static struct i2c_algorithm stm32f7_i2c_algo = {
static int stm32f7_i2c_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; struct stm32f7_i2c_dev *i2c_dev; const struct stm32f7_i2c_setup *setup; struct resource *res; - u32 irq_error, irq_event, clk_rate, rise_time, fall_time; + u32 clk_rate, rise_time, fall_time; struct i2c_adapter *adap; struct reset_control *rst; dma_addr_t phy_addr; - int ret; + int irq_error, irq_event, ret;
i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); if (!i2c_dev) @@ -1802,16 +1800,20 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) return PTR_ERR(i2c_dev->base); phy_addr = (dma_addr_t)res->start;
- irq_event = irq_of_parse_and_map(np, 0); - if (!irq_event) { - dev_err(&pdev->dev, "IRQ event missing or invalid\n"); - return -EINVAL; + irq_event = platform_get_irq(pdev, 0); + if (irq_event <= 0) { + if (irq_event != -EPROBE_DEFER) + dev_err(&pdev->dev, "Failed to get IRQ event: %d\n", + irq_event); + return irq_event ? : -ENOENT; }
- irq_error = irq_of_parse_and_map(np, 1); - if (!irq_error) { - dev_err(&pdev->dev, "IRQ error missing or invalid\n"); - return -EINVAL; + irq_error = platform_get_irq(pdev, 1); + if (irq_error <= 0) { + if (irq_error != -EPROBE_DEFER) + dev_err(&pdev->dev, "Failed to get IRQ error: %d\n", + irq_error); + return irq_error ? : -ENOENT; }
i2c_dev->clk = devm_clk_get(&pdev->dev, NULL);
From: Alexandru Ardelean alexandru.ardelean@analog.com
[ Upstream commit 05b8bcc96278c9ef927a6f25a98e233e55de42e1 ]
The iio_triggered_buffer_{predisable,postenable} functions attach/detach the poll functions.
For the predisable hook, the disable code should occur before detaching the poll func, and for the postenable hook, the poll func should be attached before the enable code.
Signed-off-by: Alexandru Ardelean alexandru.ardelean@analog.com Acked-by: Denis Ciocca denis.ciocca@st.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/st_accel_buffer.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/iio/accel/st_accel_buffer.c b/drivers/iio/accel/st_accel_buffer.c index 7fddc137e91e..802ab7d2d93f 100644 --- a/drivers/iio/accel/st_accel_buffer.c +++ b/drivers/iio/accel/st_accel_buffer.c @@ -46,17 +46,19 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev) goto allocate_memory_error; }
- err = st_sensors_set_axis_enable(indio_dev, - (u8)indio_dev->active_scan_mask[0]); + err = iio_triggered_buffer_postenable(indio_dev); if (err < 0) goto st_accel_buffer_postenable_error;
- err = iio_triggered_buffer_postenable(indio_dev); + err = st_sensors_set_axis_enable(indio_dev, + (u8)indio_dev->active_scan_mask[0]); if (err < 0) - goto st_accel_buffer_postenable_error; + goto st_sensors_set_axis_enable_error;
return err;
+st_sensors_set_axis_enable_error: + iio_triggered_buffer_predisable(indio_dev); st_accel_buffer_postenable_error: kfree(adata->buffer_data); allocate_memory_error: @@ -65,20 +67,22 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
static int st_accel_buffer_predisable(struct iio_dev *indio_dev) { - int err; + int err, err2; struct st_sensor_data *adata = iio_priv(indio_dev);
- err = iio_triggered_buffer_predisable(indio_dev); - if (err < 0) - goto st_accel_buffer_predisable_error; - err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS); if (err < 0) goto st_accel_buffer_predisable_error;
err = st_sensors_set_enable(indio_dev, false); + if (err < 0) + goto st_accel_buffer_predisable_error;
st_accel_buffer_predisable_error: + err2 = iio_triggered_buffer_predisable(indio_dev); + if (!err) + err = err2; + kfree(adata->buffer_data); return err; }
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit 589834b3a0097a4908f4112eac0ca2feb486fa32 ]
In commit ebcc5928c5d9 ("arm64: Silence gcc warnings about arch ABI drift"), the arm64 Makefile added -Wno-psabi to KBUILD_CFLAGS, which is a GCC only option so clang rightfully complains:
warning: unknown warning option '-Wno-psabi' [-Wunknown-warning-option]
https://clang.llvm.org/docs/DiagnosticsReference.html#wunknown-warning-optio...
However, by default, this is merely a warning so the build happily goes on with a slew of these warnings in the process.
Commit c3f0d0bc5b01 ("kbuild, LLVMLinux: Add -Werror to cc-option to support clang") worked around this behavior in cc-option by adding -Werror so that unknown flags cause an error. However, this all happens silently and when an unknown flag is added to the build unconditionally like -Wno-psabi, cc-option will always fail because there is always an unknown flag in the list of flags. This manifested as link time failures in the arm64 libstub because -fno-stack-protector didn't get added to KBUILD_CFLAGS.
To avoid these weird cryptic failures in the future, make clang behave like gcc and immediately error when it encounters an unknown flag by adding -Werror=unknown-warning-option to CLANG_FLAGS. This can be added unconditionally for clang because it is supported by at least 3.0.0, according to godbolt [1] and 4.0.0, according to its documentation [2], which is far earlier than we typically support.
[1]: https://godbolt.org/z/7F7rm3 [2]: https://releases.llvm.org/4.0.0/tools/clang/docs/DiagnosticsReference.html#w...
Link: https://github.com/ClangBuiltLinux/linux/issues/511 Link: https://github.com/ClangBuiltLinux/linux/issues/517 Suggested-by: Peter Smith peter.smith@linaro.org Signed-off-by: Nathan Chancellor natechancellor@gmail.com Tested-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin sashal@kernel.org --- Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/Makefile b/Makefile index 38f2150457fd..d439ccd564ca 100644 --- a/Makefile +++ b/Makefile @@ -491,6 +491,7 @@ ifneq ($(GCC_TOOLCHAIN),) CLANG_FLAGS += --gcc-toolchain=$(GCC_TOOLCHAIN) endif CLANG_FLAGS += -no-integrated-as +CLANG_FLAGS += -Werror=unknown-warning-option KBUILD_CFLAGS += $(CLANG_FLAGS) KBUILD_AFLAGS += $(CLANG_FLAGS) export CLANG_FLAGS
From: Will Deacon will.deacon@arm.com
[ Upstream commit a222061b85234d8a44486a46bd4df7e2cda52385 ]
__uint128_t crops up in a few files that export symbols to modules, so teach genksyms about it and the other GCC built-in 128-bit integer types so that we don't end up skipping the CRC generation for some symbols due to the parser failing to spot them:
| WARNING: EXPORT symbol "kernel_neon_begin" [vmlinux] version | generation failed, symbol will not be versioned. | ld: arch/arm64/kernel/fpsimd.o: relocation R_AARCH64_ABS32 against | `__crc_kernel_neon_begin' can not be used when making a shared | object | ld: arch/arm64/kernel/fpsimd.o:(.data+0x0): dangerous relocation: | unsupported relocation
Reported-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/genksyms/keywords.c | 4 ++++ scripts/genksyms/parse.y | 2 ++ 2 files changed, 6 insertions(+)
diff --git a/scripts/genksyms/keywords.c b/scripts/genksyms/keywords.c index 9f40bcd17d07..f6956aa41366 100644 --- a/scripts/genksyms/keywords.c +++ b/scripts/genksyms/keywords.c @@ -24,6 +24,10 @@ static struct resword { { "__volatile__", VOLATILE_KEYW }, { "__builtin_va_list", VA_LIST_KEYW },
+ { "__int128", BUILTIN_INT_KEYW }, + { "__int128_t", BUILTIN_INT_KEYW }, + { "__uint128_t", BUILTIN_INT_KEYW }, + // According to rth, c99 defines "_Bool", __restrict", __restrict__", "restrict". KAO { "_Bool", BOOL_KEYW }, { "_restrict", RESTRICT_KEYW }, diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 00a6d7e54971..1ebcf52cd0f9 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -76,6 +76,7 @@ static void record_compound(struct string_list **keyw, %token ATTRIBUTE_KEYW %token AUTO_KEYW %token BOOL_KEYW +%token BUILTIN_INT_KEYW %token CHAR_KEYW %token CONST_KEYW %token DOUBLE_KEYW @@ -263,6 +264,7 @@ simple_type_specifier: | VOID_KEYW | BOOL_KEYW | VA_LIST_KEYW + | BUILTIN_INT_KEYW | TYPE { (*$1)->tag = SYM_TYPEDEF; $$ = $1; } ;
From: Bharat Kumar Gogada bharat.kumar.gogada@xilinx.com
[ Upstream commit 181fa434d0514e40ebf6e9721f2b72700287b6e2 ]
According to the PCI Local Bus specification Revision 3.0, section 6.8.1.3 (Message Control for MSI), endpoints that are Multiple Message Capable as defined by bits [3:1] in the Message Control for MSI can request a number of vectors that is power of two aligned.
As specified in section 6.8.1.6 "Message data for MSI", the Multiple Message Enable field (bits [6:4] of the Message Control register) defines the number of low order message data bits the function is permitted to modify to generate its system software allocated vectors.
The MSI controller in the Xilinx NWL PCIe controller supports a number of MSI vectors specified through a bitmap and the hwirq number for an MSI, that is the value written in the MSI data TLP is determined by the bitmap allocation.
For instance, in a situation where two endpoints sitting on the PCI bus request the following MSI configuration, with the current PCI Xilinx bitmap allocation code (that does not align MSI vector allocation on a power of two boundary):
Endpoint #1: Requesting 1 MSI vector - allocated bitmap bits 0 Endpoint #2: Requesting 2 MSI vectors - allocated bitmap bits [1,2]
The bitmap value(s) corresponds to the hwirq number that is programmed into the Message Data for MSI field in the endpoint MSI capability and is detected by the root complex to fire the corresponding MSI irqs. The value written in Message Data for MSI field corresponds to the first bit allocated in the bitmap for Multi MSI vectors.
The current Xilinx NWL MSI allocation code allows a bitmap allocation that is not a power of two boundaries, so endpoint #2, is allowed to toggle Message Data bit[0] to differentiate between its two vectors (meaning that the MSI data will be respectively 0x0 and 0x1 for the two vectors allocated to endpoint #2).
This clearly aliases with the Endpoint #1 vector allocation, resulting in a broken Multi MSI implementation.
Update the code to allocate MSI bitmap ranges with a power of two alignment, fixing the bug.
Fixes: ab597d35ef11 ("PCI: xilinx-nwl: Add support for Xilinx NWL PCIe Host Controller") Suggested-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Bharat Kumar Gogada bharat.kumar.gogada@xilinx.com [lorenzo.pieralisi@arm.com: updated commit log] Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Acked-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-xilinx-nwl.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c index fb32840ce8e6..4850a1b8eec1 100644 --- a/drivers/pci/controller/pcie-xilinx-nwl.c +++ b/drivers/pci/controller/pcie-xilinx-nwl.c @@ -483,15 +483,13 @@ static int nwl_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, int i;
mutex_lock(&msi->lock); - bit = bitmap_find_next_zero_area(msi->bitmap, INT_PCI_MSI_NR, 0, - nr_irqs, 0); - if (bit >= INT_PCI_MSI_NR) { + bit = bitmap_find_free_region(msi->bitmap, INT_PCI_MSI_NR, + get_count_order(nr_irqs)); + if (bit < 0) { mutex_unlock(&msi->lock); return -ENOSPC; }
- bitmap_set(msi->bitmap, bit, nr_irqs); - for (i = 0; i < nr_irqs; i++) { irq_domain_set_info(domain, virq + i, bit + i, &nwl_irq_chip, domain->host_data, handle_simple_irq, @@ -509,7 +507,8 @@ static void nwl_irq_domain_free(struct irq_domain *domain, unsigned int virq, struct nwl_msi *msi = &pcie->msi;
mutex_lock(&msi->lock); - bitmap_clear(msi->bitmap, data->hwirq, nr_irqs); + bitmap_release_region(msi->bitmap, data->hwirq, + get_count_order(nr_irqs)); mutex_unlock(&msi->lock); }
From: Bastien Nocera hadess@hadess.net
[ Upstream commit 208a68c8393d6041a90862992222f3d7943d44d6 ]
On some machines, iio-sensor-proxy was returning all 0's for IIO sensor values. It turns out that the bits_used for this sensor is 32, which makes the mask calculation:
*mask = (1 << 32) - 1;
If the compiler interprets the 1 literals as 32-bit ints, it generates undefined behavior depending on compiler version and optimization level. On my system, it optimizes out the shift, so the mask value becomes
*mask = (1) - 1;
With a mask value of 0, iio-sensor-proxy will always return 0 for every axis.
Avoid incorrect 0 values caused by compiler optimization.
See original fix by Brett Dutro brett.dutro@gmail.com in iio-sensor-proxy: https://github.com/hadess/iio-sensor-proxy/commit/9615ceac7c134d838660e20972...
Signed-off-by: Bastien Nocera hadess@hadess.net Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/iio/iio_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/iio/iio_utils.c b/tools/iio/iio_utils.c index 7a6d61c6c012..55272fef3b50 100644 --- a/tools/iio/iio_utils.c +++ b/tools/iio/iio_utils.c @@ -159,9 +159,9 @@ int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used, *be = (endianchar == 'b'); *bytes = padint / 8; if (*bits_used == 64) - *mask = ~0; + *mask = ~(0ULL); else - *mask = (1ULL << *bits_used) - 1; + *mask = (1ULL << *bits_used) - 1ULL;
*is_signed = (signchar == 's'); if (fclose(sysfsfp)) {
From: Qian Cai cai@lca.pw
[ Upstream commit 04db3ede40ae4fc23a5c4237254c4a53bbe4c1f2 ]
The powerpc's flush_cache_vmap() is defined as a macro and never use both of its arguments, so it will generate a compilation warning,
lib/ioremap.c: In function 'ioremap_page_range': lib/ioremap.c:203:16: warning: variable 'start' set but not used [-Wunused-but-set-variable]
Fix it by making it an inline function.
Signed-off-by: Qian Cai cai@lca.pw Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/cacheflush.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index d5a8d7bf0759..b189f7aee222 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -32,9 +32,12 @@ * not expect this type of fault. flush_cache_vmap is not exactly the right * place to put this, but it seems to work well enough. */ -#define flush_cache_vmap(start, end) do { asm volatile("ptesync" ::: "memory"); } while (0) +static inline void flush_cache_vmap(unsigned long start, unsigned long end) +{ + asm volatile("ptesync" ::: "memory"); +} #else -#define flush_cache_vmap(start, end) do { } while (0) +static inline void flush_cache_vmap(unsigned long start, unsigned long end) { } #endif
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
From: "Naveen N. Rao" naveen.n.rao@linux.vnet.ibm.com
[ Upstream commit aaf06665f7ea3ee9f9754e16c1a507a89f1de5b1 ]
Commit ed49f7fd6438d ("powerpc/xmon: Disable tracing when entering xmon") added code to disable recording trace entries while in xmon. The commit introduced a variable 'tracing_enabled' to record if tracing was enabled on xmon entry, and used this to conditionally enable tracing during exit from xmon.
However, we are not checking the value of 'fromipi' variable in xmon_core() when setting 'tracing_enabled'. Due to this, when secondary cpus enter xmon, they will see tracing as being disabled already and tracing won't be re-enabled on exit. Fix the same.
Fixes: ed49f7fd6438d ("powerpc/xmon: Disable tracing when entering xmon") Signed-off-by: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/xmon/xmon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index dd6badc31f45..74cfc1be04d6 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -466,8 +466,10 @@ static int xmon_core(struct pt_regs *regs, int fromipi) local_irq_save(flags); hard_irq_disable();
- tracing_enabled = tracing_is_on(); - tracing_off(); + if (!fromipi) { + tracing_enabled = tracing_is_on(); + tracing_off(); + }
bp = in_breakpoint_table(regs->nip, &offset); if (bp != NULL) {
From: "Naveen N. Rao" naveen.n.rao@linux.vnet.ibm.com
[ Upstream commit 80e5302e4bc85a6b685b7668c36c6487b5f90e9a ]
An impending change to enable HAVE_C_RECORDMCOUNT on powerpc leads to warnings such as the following:
# modprobe kprobe_example ftrace-powerpc: Not expected bl: opcode is 3c4c0001 WARNING: CPU: 0 PID: 227 at kernel/trace/ftrace.c:2001 ftrace_bug+0x90/0x318 Modules linked in: CPU: 0 PID: 227 Comm: modprobe Not tainted 5.2.0-rc6-00678-g1c329100b942 #2 NIP: c000000000264318 LR: c00000000025d694 CTR: c000000000f5cd30 REGS: c000000001f2b7b0 TRAP: 0700 Not tainted (5.2.0-rc6-00678-g1c329100b942) MSR: 900000010282b033 <SF,HV,VEC,VSX,EE,FP,ME,IR,DR,RI,LE,TM[E]> CR: 28228222 XER: 00000000 CFAR: c0000000002642fc IRQMASK: 0 <snip> NIP [c000000000264318] ftrace_bug+0x90/0x318 LR [c00000000025d694] ftrace_process_locs+0x4f4/0x5e0 Call Trace: [c000000001f2ba40] [0000000000000004] 0x4 (unreliable) [c000000001f2bad0] [c00000000025d694] ftrace_process_locs+0x4f4/0x5e0 [c000000001f2bb90] [c00000000020ff10] load_module+0x25b0/0x30c0 [c000000001f2bd00] [c000000000210cb0] sys_finit_module+0xc0/0x130 [c000000001f2be20] [c00000000000bda4] system_call+0x5c/0x70 Instruction dump: 419e0018 2f83ffff 419e00bc 2f83ffea 409e00cc 4800001c 0fe00000 3c62ff96 39000001 39400000 386386d0 480000c4 <0fe00000> 3ce20003 39000001 3c62ff96 ---[ end trace 4c438d5cebf78381 ]--- ftrace failed to modify [<c0080000012a0008>] 0xc0080000012a0008 actual: 01:00:4c:3c Initializing ftrace call sites ftrace record flags: 2000000 (0) expected tramp: c00000000006af4c
Looking at the relocation records in __mcount_loc shows a few spurious entries:
RELOCATION RECORDS FOR [__mcount_loc]: OFFSET TYPE VALUE 0000000000000000 R_PPC64_ADDR64 .text.unlikely+0x0000000000000008 0000000000000008 R_PPC64_ADDR64 .text.unlikely+0x0000000000000014 0000000000000010 R_PPC64_ADDR64 .text.unlikely+0x0000000000000060 0000000000000018 R_PPC64_ADDR64 .text.unlikely+0x00000000000000b4 0000000000000020 R_PPC64_ADDR64 .init.text+0x0000000000000008 0000000000000028 R_PPC64_ADDR64 .init.text+0x0000000000000014
The first entry in each section is incorrect. Looking at the relocation records, the spurious entries correspond to the R_PPC64_ENTRY records:
RELOCATION RECORDS FOR [.text.unlikely]: OFFSET TYPE VALUE 0000000000000000 R_PPC64_REL64 .TOC.-0x0000000000000008 0000000000000008 R_PPC64_ENTRY *ABS* 0000000000000014 R_PPC64_REL24 _mcount <snip>
The problem is that we are not validating the return value from get_mcountsym() in sift_rel_mcount(). With this entry, mcountsym is 0, but Elf_r_sym(relp) also ends up being 0. Fix this by ensuring mcountsym is valid before processing the entry.
Signed-off-by: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com Acked-by: Steven Rostedt (VMware) rostedt@goodmis.org Tested-by: Satheesh Rajendran sathnaga@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/recordmcount.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 2e7793735e14..ccfbfde61556 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -326,7 +326,8 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, if (!mcountsym) mcountsym = get_mcountsym(sym0, relp, str0);
- if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { + if (mcountsym && mcountsym == Elf_r_sym(relp) && + !is_fake_mcount(relp)) { uint_t const addend = _w(_w(relp->r_offset) - recval + mcount_adjust); mrelp->r_offset = _w(offbase
From: Daniel Gomez dagmcr@gmail.com
[ Upstream commit 5aa3709c0a5c026735b0ddd4ec80810a23d65f5b ]
MODULE_DEVICE_TABLE(of, <of_match_table>) should be called to complete DT OF mathing mechanism and register it.
Before this patch: modinfo ./drivers/mfd/madera.ko | grep alias
After this patch: modinfo ./drivers/mfd/madera.ko | grep alias alias: of:N*T*Ccirrus,wm1840C* alias: of:N*T*Ccirrus,wm1840 alias: of:N*T*Ccirrus,cs47l91C* alias: of:N*T*Ccirrus,cs47l91 alias: of:N*T*Ccirrus,cs47l90C* alias: of:N*T*Ccirrus,cs47l90 alias: of:N*T*Ccirrus,cs47l85C* alias: of:N*T*Ccirrus,cs47l85 alias: of:N*T*Ccirrus,cs47l35C* alias: of:N*T*Ccirrus,cs47l35
Reported-by: Javier Martinez Canillas javier@dowhile0.org Signed-off-by: Daniel Gomez dagmcr@gmail.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/madera-core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c index 8cfea969b060..45c7d8b97349 100644 --- a/drivers/mfd/madera-core.c +++ b/drivers/mfd/madera-core.c @@ -278,6 +278,7 @@ const struct of_device_id madera_of_match[] = { { .compatible = "cirrus,wm1840", .data = (void *)WM1840 }, {} }; +MODULE_DEVICE_TABLE(of, madera_of_match); EXPORT_SYMBOL_GPL(madera_of_match);
static int madera_get_reset_gpio(struct madera *madera)
From: Robert Hancock hancock@sedsystems.ca
[ Upstream commit c176c6d7e932662668bcaec2d763657096589d85 ]
The logic for setting the of_node on devices created by mfd did not set the fwnode pointer to match, which caused fwnode-based APIs to malfunction on these devices since the fwnode pointer was null. Fix this.
Signed-off-by: Robert Hancock hancock@sedsystems.ca Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/mfd-core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 94e3f32ce935..182973df1aed 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -179,6 +179,7 @@ static int mfd_add_device(struct device *parent, int id, for_each_child_of_node(parent->of_node, np) { if (of_device_is_compatible(np, cell->of_compatible)) { pdev->dev.of_node = np; + pdev->dev.fwnode = &np->fwnode; break; } }
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 5da6cbcd2f395981aa9bfc571ace99f1c786c985 ]
When the driver is used with a subdevice that is disabled in the kernel configuration, clang gets a little confused about the control flow and fails to notice that n_subdevs is only uninitialized when subdevs is NULL, and we check for that, leading to a false-positive warning:
drivers/mfd/arizona-core.c:1423:19: error: variable 'n_subdevs' is uninitialized when used here [-Werror,-Wuninitialized] subdevs, n_subdevs, NULL, 0, NULL); ^~~~~~~~~ drivers/mfd/arizona-core.c:999:15: note: initialize the variable 'n_subdevs' to silence this warning int n_subdevs, ret, i; ^ = 0
Ideally, we would rearrange the code to avoid all those early initializations and have an explicit exit in each disabled case, but it's much easier to chicken out and add one more initialization here to shut up the warning.
Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/arizona-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 5f1e37d23943..47d6d40f41cd 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -996,7 +996,7 @@ int arizona_dev_init(struct arizona *arizona) unsigned int reg, val; int (*apply_patch)(struct arizona *) = NULL; const struct mfd_cell *subdevs = NULL; - int n_subdevs, ret, i; + int n_subdevs = 0, ret, i;
dev_set_drvdata(arizona->dev, arizona); mutex_init(&arizona->clk_lock);
From: Axel Lin axel.lin@ingics.com
[ Upstream commit 7efd105c27fd2323789b41b64763a0e33ed79c08 ]
Since devm_regmap_init_mmio_clk can fail, add return value checking.
Signed-off-by: Axel Lin axel.lin@ingics.com Acked-by: Chen Feng puck.chen@hisilicon.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/hi655x-pmic.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/mfd/hi655x-pmic.c b/drivers/mfd/hi655x-pmic.c index 96c07fa1802a..6693f74aa6ab 100644 --- a/drivers/mfd/hi655x-pmic.c +++ b/drivers/mfd/hi655x-pmic.c @@ -112,6 +112,8 @@ static int hi655x_pmic_probe(struct platform_device *pdev)
pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base, &hi655x_regmap_config); + if (IS_ERR(pmic->regmap)) + return PTR_ERR(pmic->regmap);
regmap_read(pmic->regmap, HI655X_BUS_ADDR(HI655X_VER_REG), &pmic->ver); if ((pmic->ver < PMU_VER_START) || (pmic->ver > PMU_VER_END)) {
From: Ira Weiny ira.weiny@intel.com
[ Upstream commit c5d6c45e90c49150670346967971e14576afd7f1 ]
release_pages() is an optimized version of a loop around put_page(). Unfortunately for devmap pages the logic is not entirely correct in release_pages(). This is because device pages can be more than type MEMORY_DEVICE_PUBLIC. There are in fact 4 types, private, public, FS DAX, and PCI P2PDMA. Some of these have specific needs to "put" the page while others do not.
This logic to handle any special needs is contained in put_devmap_managed_page(). Therefore all devmap pages should be processed by this function where we can contain the correct logic for a page put.
Handle all device type pages within release_pages() by calling put_devmap_managed_page() on all devmap pages. If put_devmap_managed_page() returns true the page has been put and we continue with the next page. A false return of put_devmap_managed_page() means the page did not require special processing and should fall to "normal" processing.
This was found via code inspection while determining if release_pages() and the new put_user_pages() could be interchangeable.[1]
[1] https://lkml.kernel.org/r/20190523172852.GA27175@iweiny-DESK2.sc.intel.com
Link: https://lkml.kernel.org/r/20190605214922.17684-1-ira.weiny@intel.com Cc: Jérôme Glisse jglisse@redhat.com Cc: Michal Hocko mhocko@suse.com Reviewed-by: Dan Williams dan.j.williams@intel.com Reviewed-by: John Hubbard jhubbard@nvidia.com Signed-off-by: Ira Weiny ira.weiny@intel.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- mm/swap.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/mm/swap.c b/mm/swap.c index a3fc028e338e..45fdbfb6b2a6 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -740,15 +740,20 @@ void release_pages(struct page **pages, int nr) if (is_huge_zero_page(page)) continue;
- /* Device public page can not be huge page */ - if (is_device_public_page(page)) { + if (is_zone_device_page(page)) { if (locked_pgdat) { spin_unlock_irqrestore(&locked_pgdat->lru_lock, flags); locked_pgdat = NULL; } - put_devmap_managed_page(page); - continue; + /* + * ZONE_DEVICE pages that return 'false' from + * put_devmap_managed_page() do not require special + * processing, and instead, expect a call to + * put_page_testzero(). + */ + if (put_devmap_managed_page(page)) + continue; }
page = compound_head(page);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 80bf6ceaf9310b3f61934c69b382d4912deee049 ]
When we get into activate_mm(), lockdep complains that we're doing something strange:
WARNING: possible circular locking dependency detected 5.1.0-10252-gb00152307319-dirty #121 Not tainted ------------------------------------------------------ inside.sh/366 is trying to acquire lock: (____ptrval____) (&(&p->alloc_lock)->rlock){+.+.}, at: flush_old_exec+0x703/0x8d7
but task is already holding lock: (____ptrval____) (&mm->mmap_sem){++++}, at: flush_old_exec+0x6c5/0x8d7
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&mm->mmap_sem){++++}: [...] __lock_acquire+0x12ab/0x139f lock_acquire+0x155/0x18e down_write+0x3f/0x98 flush_old_exec+0x748/0x8d7 load_elf_binary+0x2ca/0xddb [...]
-> #0 (&(&p->alloc_lock)->rlock){+.+.}: [...] __lock_acquire+0x12ab/0x139f lock_acquire+0x155/0x18e _raw_spin_lock+0x30/0x83 flush_old_exec+0x703/0x8d7 load_elf_binary+0x2ca/0xddb [...]
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(&mm->mmap_sem); lock(&(&p->alloc_lock)->rlock); lock(&mm->mmap_sem); lock(&(&p->alloc_lock)->rlock);
*** DEADLOCK ***
2 locks held by inside.sh/366: #0: (____ptrval____) (&sig->cred_guard_mutex){+.+.}, at: __do_execve_file+0x12d/0x869 #1: (____ptrval____) (&mm->mmap_sem){++++}, at: flush_old_exec+0x6c5/0x8d7
stack backtrace: CPU: 0 PID: 366 Comm: inside.sh Not tainted 5.1.0-10252-gb00152307319-dirty #121 Stack: [...] Call Trace: [<600420de>] show_stack+0x13b/0x155 [<6048906b>] dump_stack+0x2a/0x2c [<6009ae64>] print_circular_bug+0x332/0x343 [<6009c5c6>] check_prev_add+0x669/0xdad [<600a06b4>] __lock_acquire+0x12ab/0x139f [<6009f3d0>] lock_acquire+0x155/0x18e [<604a07e0>] _raw_spin_lock+0x30/0x83 [<60151e6a>] flush_old_exec+0x703/0x8d7 [<601a8eb8>] load_elf_binary+0x2ca/0xddb [...]
I think it's because in exec_mmap() we have
down_read(&old_mm->mmap_sem); ... task_lock(tsk); ... activate_mm(active_mm, mm); (which does down_write(&mm->mmap_sem))
I'm not really sure why lockdep throws in the whole knowledge about the task lock, but it seems that old_mm and mm shouldn't ever be the same (and it doesn't deadlock) so tell lockdep that they're different.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/include/asm/mmu_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h index fca34b2177e2..129fb1d1f1c5 100644 --- a/arch/um/include/asm/mmu_context.h +++ b/arch/um/include/asm/mmu_context.h @@ -53,7 +53,7 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new) * when the new ->mm is used for the first time. */ __switch_mm(&new->context.id); - down_write(&new->mmap_sem); + down_write_nested(&new->mmap_sem, 1); uml_setup_stubs(new); up_write(&new->mmap_sem); }
From: Christian Lamparter chunkeey@gmail.com
[ Upstream commit 3ab3a0689e74e6aa5b41360bc18861040ddef5b1 ]
When testing out gpio-keys with a button, a spurious interrupt (and therefore a key press or release event) gets triggered as soon as the driver enables the irq line for the first time.
This patch clears any potential bogus generated interrupt that was caused by the switching of the associated irq's type and polarity.
Signed-off-by: Christian Lamparter chunkeey@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/4xx/uic.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/platforms/4xx/uic.c b/arch/powerpc/platforms/4xx/uic.c index 8b4dd0da0839..9e27cfe27026 100644 --- a/arch/powerpc/platforms/4xx/uic.c +++ b/arch/powerpc/platforms/4xx/uic.c @@ -158,6 +158,7 @@ static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type)
mtdcr(uic->dcrbase + UIC_PR, pr); mtdcr(uic->dcrbase + UIC_TR, tr); + mtdcr(uic->dcrbase + UIC_SR, ~mask);
raw_spin_unlock_irqrestore(&uic->lock, flags);
From: "Liu, Changcheng" changcheng.liu@intel.com
[ Upstream commit 2e67e775845373905d2c2aecb9062c2c4352a535 ]
The API for ib_query_qp requires the driver to set qp_state and cur_qp_state on return, add the missing sets.
Fixes: d37498417947 ("i40iw: add files for iwarp interface") Signed-off-by: Changcheng Liu changcheng.liu@aliyun.com Acked-by: Shiraz Saleem shiraz.saleem@intel.com Reviewed-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/i40iw/i40iw_verbs.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c index e2e6c74a7452..a5e3349b8a7c 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c +++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c @@ -806,6 +806,8 @@ static int i40iw_query_qp(struct ib_qp *ibqp, struct i40iw_qp *iwqp = to_iwqp(ibqp); struct i40iw_sc_qp *qp = &iwqp->sc_qp;
+ attr->qp_state = iwqp->ibqp_state; + attr->cur_qp_state = attr->qp_state; attr->qp_access_flags = 0; attr->cap.max_send_wr = qp->qp_uk.sq_size; attr->cap.max_recv_wr = qp->qp_uk.rq_size;
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 775b7ffd7d6d5db320d99b0a485c51e04dfcf9f1 ]
While the .flush_buffer() callback clears sci_port.tx_dma_len since commit 1cf4a7efdc71cab8 ("serial: sh-sci: Fix race condition causing garbage during shutdown"), it does not terminate a transmit DMA operation that may be in progress.
Fix this by terminating any pending DMA operations, and resetting the corresponding cookie.
Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Eugeniu Rosca erosca@de.adit-jv.com Tested-by: Eugeniu Rosca erosca@de.adit-jv.com
Link: https://lore.kernel.org/r/20190624123540.20629-3-geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/sh-sci.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 040832635a64..71f12601e693 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1633,11 +1633,18 @@ static void sci_free_dma(struct uart_port *port)
static void sci_flush_buffer(struct uart_port *port) { + struct sci_port *s = to_sci_port(port); + /* * In uart_flush_buffer(), the xmit circular buffer has just been - * cleared, so we have to reset tx_dma_len accordingly. + * cleared, so we have to reset tx_dma_len accordingly, and stop any + * pending transfers */ - to_sci_port(port)->tx_dma_len = 0; + s->tx_dma_len = 0; + if (s->chan_tx) { + dmaengine_terminate_async(s->chan_tx); + s->cookie_tx = -EINVAL; + } } #else /* !CONFIG_SERIAL_SH_SCI_DMA */ static inline void sci_request_dma(struct uart_port *port)
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 8493eab02608b0e82f67b892aa72882e510c31d0 ]
When uart_flush_buffer() is called, the .flush_buffer() callback zeroes the tx_dma_len field. This may race with the work queue function handling transmit DMA requests:
1. If the buffer is flushed before the first DMA API call, dmaengine_prep_slave_single() may be called with a zero length, causing the DMA request to never complete, leading to messages like:
rcar-dmac e7300000.dma-controller: Channel Address Error happen
and, with debug enabled:
sh-sci e6e88000.serial: sci_dma_tx_work_fn: ffff800639b55000: 0...0, cookie 126
and DMA timeouts.
2. If the buffer is flushed after the first DMA API call, but before the second, dma_sync_single_for_device() may be called with a zero length, causing the transmit data not to be flushed to RAM, and leading to stale data being output.
Fix this by: 1. Letting sci_dma_tx_work_fn() return immediately if the transmit buffer is empty, 2. Extending the critical section to cover all DMA preparational work, so tx_dma_len stays consistent for all of it, 3. Using local copies of circ_buf.head and circ_buf.tail, to make sure they match the actual operation above.
Reported-by: Eugeniu Rosca erosca@de.adit-jv.com Suggested-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Eugeniu Rosca erosca@de.adit-jv.com Tested-by: Eugeniu Rosca erosca@de.adit-jv.com Link: https://lore.kernel.org/r/20190624123540.20629-2-geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/sh-sci.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 71f12601e693..5550289e6678 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1376,6 +1376,7 @@ static void work_fn_tx(struct work_struct *work) struct circ_buf *xmit = &port->state->xmit; unsigned long flags; dma_addr_t buf; + int head, tail;
/* * DMA is idle now. @@ -1385,16 +1386,23 @@ static void work_fn_tx(struct work_struct *work) * consistent xmit buffer state. */ spin_lock_irq(&port->lock); - buf = s->tx_dma_addr + (xmit->tail & (UART_XMIT_SIZE - 1)); + head = xmit->head; + tail = xmit->tail; + buf = s->tx_dma_addr + (tail & (UART_XMIT_SIZE - 1)); s->tx_dma_len = min_t(unsigned int, - CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), - CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); - spin_unlock_irq(&port->lock); + CIRC_CNT(head, tail, UART_XMIT_SIZE), + CIRC_CNT_TO_END(head, tail, UART_XMIT_SIZE)); + if (!s->tx_dma_len) { + /* Transmit buffer has been flushed */ + spin_unlock_irq(&port->lock); + return; + }
desc = dmaengine_prep_slave_single(chan, buf, s->tx_dma_len, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { + spin_unlock_irq(&port->lock); dev_warn(port->dev, "Failed preparing Tx DMA descriptor\n"); goto switch_to_pio; } @@ -1402,18 +1410,18 @@ static void work_fn_tx(struct work_struct *work) dma_sync_single_for_device(chan->device->dev, buf, s->tx_dma_len, DMA_TO_DEVICE);
- spin_lock_irq(&port->lock); desc->callback = sci_dma_tx_complete; desc->callback_param = s; - spin_unlock_irq(&port->lock); s->cookie_tx = dmaengine_submit(desc); if (dma_submit_error(s->cookie_tx)) { + spin_unlock_irq(&port->lock); dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n"); goto switch_to_pio; }
+ spin_unlock_irq(&port->lock); dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", - __func__, xmit->buf, xmit->tail, xmit->head, s->cookie_tx); + __func__, xmit->buf, tail, head, s->cookie_tx);
dma_async_issue_pending(chan); return;
From: Parav Pandit parav@mellanox.com
[ Upstream commit 2f40cf30c8644360d37287861d5288f00eab35e5 ]
Currently during dual port IB device registration in below code flow,
ib_register_device() ib_device_register_sysfs() ib_setup_port_attrs() add_port() get_counter_table() get_perf_mad() process_mad() mlx5_ib_process_mad()
mlx5_ib_process_mad() fails on 2nd port when both the ports are not fully setup at the device level (because 2nd port is unaffiliated).
As a result, get_perf_mad() registers different PMA counter group for 1st and 2nd port, namely pma_counter_ext and pma_counter. However both ports have the same capability and counter offsets.
Due to this when counters are read by the user via sysfs in below code flow, counters are queried from wrong location from the device mainly from PPCNT instead of VPORT counters.
show_pma_counter() get_perf_mad() process_mad() mlx5_ib_process_mad() process_pma_cmd()
This shows all zero counters for 2nd port.
To overcome this, process_pma_cmd() is invoked, and when unaffiliated port is not yet setup during device registration phase, make the query on the first port. while at it, only process_pma_cmd() needs to work on the native port number and underlying mdev, so shift the get, put calls to where its needed inside process_pma_cmd().
Fixes: 212f2a87b74f ("IB/mlx5: Route MADs for dual port RoCE") Signed-off-by: Parav Pandit parav@mellanox.com Reviewed-by: Daniel Jurgens danielj@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx5/mad.c | 60 +++++++++++++++++++------------- 1 file changed, 36 insertions(+), 24 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/mad.c b/drivers/infiniband/hw/mlx5/mad.c index 32a9e9228b13..cdf6e26ebc87 100644 --- a/drivers/infiniband/hw/mlx5/mad.c +++ b/drivers/infiniband/hw/mlx5/mad.c @@ -197,19 +197,33 @@ static void pma_cnt_assign(struct ib_pma_portcounters *pma_cnt, vl_15_dropped); }
-static int process_pma_cmd(struct mlx5_core_dev *mdev, u8 port_num, +static int process_pma_cmd(struct mlx5_ib_dev *dev, u8 port_num, const struct ib_mad *in_mad, struct ib_mad *out_mad) { - int err; + struct mlx5_core_dev *mdev; + bool native_port = true; + u8 mdev_port_num; void *out_cnt; + int err;
+ mdev = mlx5_ib_get_native_port_mdev(dev, port_num, &mdev_port_num); + if (!mdev) { + /* Fail to get the native port, likely due to 2nd port is still + * unaffiliated. In such case default to 1st port and attached + * PF device. + */ + native_port = false; + mdev = dev->mdev; + mdev_port_num = 1; + } /* Declaring support of extended counters */ if (in_mad->mad_hdr.attr_id == IB_PMA_CLASS_PORT_INFO) { struct ib_class_port_info cpi = {};
cpi.capability_mask = IB_PMA_CLASS_CAP_EXT_WIDTH; memcpy((out_mad->data + 40), &cpi, sizeof(cpi)); - return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; + err = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; + goto done; }
if (in_mad->mad_hdr.attr_id == IB_PMA_PORT_COUNTERS_EXT) { @@ -218,11 +232,13 @@ static int process_pma_cmd(struct mlx5_core_dev *mdev, u8 port_num, int sz = MLX5_ST_SZ_BYTES(query_vport_counter_out);
out_cnt = kvzalloc(sz, GFP_KERNEL); - if (!out_cnt) - return IB_MAD_RESULT_FAILURE; + if (!out_cnt) { + err = IB_MAD_RESULT_FAILURE; + goto done; + }
err = mlx5_core_query_vport_counter(mdev, 0, 0, - port_num, out_cnt, sz); + mdev_port_num, out_cnt, sz); if (!err) pma_cnt_ext_assign(pma_cnt_ext, out_cnt); } else { @@ -231,20 +247,23 @@ static int process_pma_cmd(struct mlx5_core_dev *mdev, u8 port_num, int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
out_cnt = kvzalloc(sz, GFP_KERNEL); - if (!out_cnt) - return IB_MAD_RESULT_FAILURE; + if (!out_cnt) { + err = IB_MAD_RESULT_FAILURE; + goto done; + }
- err = mlx5_core_query_ib_ppcnt(mdev, port_num, + err = mlx5_core_query_ib_ppcnt(mdev, mdev_port_num, out_cnt, sz); if (!err) pma_cnt_assign(pma_cnt, out_cnt); - } - + } kvfree(out_cnt); - if (err) - return IB_MAD_RESULT_FAILURE; - - return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; + err = err ? IB_MAD_RESULT_FAILURE : + IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; +done: + if (native_port) + mlx5_ib_put_native_port_mdev(dev, port_num); + return err; }
int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, @@ -256,8 +275,6 @@ int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, struct mlx5_ib_dev *dev = to_mdev(ibdev); const struct ib_mad *in_mad = (const struct ib_mad *)in; struct ib_mad *out_mad = (struct ib_mad *)out; - struct mlx5_core_dev *mdev; - u8 mdev_port_num; int ret;
if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || @@ -266,19 +283,14 @@ int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
memset(out_mad->data, 0, sizeof(out_mad->data));
- mdev = mlx5_ib_get_native_port_mdev(dev, port_num, &mdev_port_num); - if (!mdev) - return IB_MAD_RESULT_FAILURE; - - if (MLX5_CAP_GEN(mdev, vport_counters) && + if (MLX5_CAP_GEN(dev->mdev, vport_counters) && in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT && in_mad->mad_hdr.method == IB_MGMT_METHOD_GET) { - ret = process_pma_cmd(mdev, mdev_port_num, in_mad, out_mad); + ret = process_pma_cmd(dev, port_num, in_mad, out_mad); } else { ret = process_mad(ibdev, mad_flags, port_num, in_wc, in_grh, in_mad, out_mad); } - mlx5_ib_put_native_port_mdev(dev, port_num); return ret; }
From: "Aneesh Kumar K.V" aneesh.kumar@linux.ibm.com
[ Upstream commit 2230ebf6e6dd0b7751e2921b40f6cfe34f09bb16 ]
This fixes kernel crash that arises due to not handling page table allocation failures while allocating hugetlb page table.
Fixes: e2b3d202d1db ("powerpc: Switch 16GB and 16MB explicit hugepages to a different page table format") Signed-off-by: Aneesh Kumar K.V aneesh.kumar@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/hugetlbpage.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 7296a42eb62e..cef0b7ee1024 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -150,6 +150,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz } else { pdshift = PUD_SHIFT; pu = pud_alloc(mm, pg, addr); + if (!pu) + return NULL; if (pshift == PUD_SHIFT) return (pte_t *)pu; else if (pshift > PMD_SHIFT) { @@ -158,6 +160,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz } else { pdshift = PMD_SHIFT; pm = pmd_alloc(mm, pu, addr); + if (!pm) + return NULL; if (pshift == PMD_SHIFT) /* 16MB hugepage */ return (pte_t *)pm; @@ -174,12 +178,16 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz } else { pdshift = PUD_SHIFT; pu = pud_alloc(mm, pg, addr); + if (!pu) + return NULL; if (pshift >= PUD_SHIFT) { ptl = pud_lockptr(mm, pu); hpdp = (hugepd_t *)pu; } else { pdshift = PMD_SHIFT; pm = pmd_alloc(mm, pu, addr); + if (!pm) + return NULL; ptl = pmd_lockptr(mm, pm); hpdp = (hugepd_t *)pm; }
From: Valentine Fatiev valentinef@mellanox.com
[ Upstream commit 91b01061fef9c57d2f5b712a6322ef51061f4efd ]
Despite failure in ipoib_dev_init() we continue with initialization flow and creation of child device. It causes to the situation where this child device is added too early to parent device list.
Change the logic, so in case of failure we properly return error from ipoib_dev_init() and add child only in success path.
Fixes: eaeb39842508 ("IB/ipoib: Move init code to ndo_init") Signed-off-by: Valentine Fatiev valentinef@mellanox.com Reviewed-by: Feras Daoud ferasda@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Reviewed-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 34 +++++++++++++---------- 1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 30f840f874b3..453695f7d457 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -1892,12 +1892,6 @@ static void ipoib_child_init(struct net_device *ndev) struct ipoib_dev_priv *priv = ipoib_priv(ndev); struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent);
- dev_hold(priv->parent); - - down_write(&ppriv->vlan_rwsem); - list_add_tail(&priv->list, &ppriv->child_intfs); - up_write(&ppriv->vlan_rwsem); - priv->max_ib_mtu = ppriv->max_ib_mtu; set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN); @@ -1940,6 +1934,17 @@ static int ipoib_ndo_init(struct net_device *ndev) if (rc) { pr_warn("%s: failed to initialize device: %s port %d (ret = %d)\n", priv->ca->name, priv->dev->name, priv->port, rc); + return rc; + } + + if (priv->parent) { + struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent); + + dev_hold(priv->parent); + + down_write(&ppriv->vlan_rwsem); + list_add_tail(&priv->list, &ppriv->child_intfs); + up_write(&ppriv->vlan_rwsem); }
return 0; @@ -1957,6 +1962,14 @@ static void ipoib_ndo_uninit(struct net_device *dev) */ WARN_ON(!list_empty(&priv->child_intfs));
+ if (priv->parent) { + struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent); + + down_write(&ppriv->vlan_rwsem); + list_del(&priv->list); + up_write(&ppriv->vlan_rwsem); + } + ipoib_neigh_hash_uninit(dev);
ipoib_ib_dev_cleanup(dev); @@ -1968,15 +1981,8 @@ static void ipoib_ndo_uninit(struct net_device *dev) priv->wq = NULL; }
- if (priv->parent) { - struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent); - - down_write(&ppriv->vlan_rwsem); - list_del(&priv->list); - up_write(&ppriv->vlan_rwsem); - + if (priv->parent) dev_put(priv->parent); - } }
static int ipoib_set_vf_link_state(struct net_device *dev, int vf, int link_state)
From: James Morse james.morse@arm.com
[ Upstream commit 2b68a2a963a157f024c67c0697b16f5f792c8a35 ]
The ESB-instruction is a nop on CPUs that don't implement the RAS extensions. This lets us use it in places like the vectors without having to use alternatives.
If someone disables CONFIG_ARM64_RAS_EXTN, this instruction still has its RAS extensions behaviour, but we no longer read DISR_EL1 as this register does depend on alternatives.
This could go wrong if we want to synchronize an SError from a KVM guest. On a CPU that has the RAS extensions, but the KConfig option was disabled, we consume the pending SError with no chance of ever reading it.
Hide the ESB-instruction behind the CONFIG_ARM64_RAS_EXTN option, outputting a regular nop if the feature has been disabled.
Reported-by: Julien Thierry julien.thierry@arm.com Signed-off-by: James Morse james.morse@arm.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/include/asm/assembler.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index f90f5d83b228..5a97ac853168 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -112,7 +112,11 @@ * RAS Error Synchronization barrier */ .macro esb +#ifdef CONFIG_ARM64_RAS_EXTN hint #16 +#else + nop +#endif .endm
/*
From: Vidya Sagar vidyas@nvidia.com
[ Upstream commit 7be142caabc4780b13a522c485abc806de5c4114 ]
The PCI Tegra controller conversion to a device tree configurable driver in commit d1523b52bff3 ("PCI: tegra: Move PCIe driver to drivers/pci/host") implied that code for the driver can be compiled in for a kernel supporting multiple platforms.
Unfortunately, a blind move of the code did not check that some of the quirks that were applied in arch/arm (eg enabling Relaxed Ordering on all PCI devices - since the quirk hook erroneously matches PCI_ANY_ID for both Vendor-ID and Device-ID) are now applied in all kernels that compile the PCI Tegra controlled driver, DT and ACPI alike.
This is completely wrong, in that enablement of Relaxed Ordering is only required by default in Tegra20 platforms as described in the Tegra20 Technical Reference Manual (available at https://developer.nvidia.com/embedded/downloads#?search=tegra%202 in Section 34.1, where it is mentioned that Relaxed Ordering bit needs to be enabled in its root ports to avoid deadlock in hardware) and in the Tegra30 platforms for the same reasons (unfortunately not documented in the TRM).
There is no other strict requirement on PCI devices Relaxed Ordering enablement on any other Tegra platforms or PCI host bridge driver.
Fix this quite upsetting situation by limiting the vendor and device IDs to which the Relaxed Ordering quirk applies to the root ports in question, reported above.
Signed-off-by: Vidya Sagar vidyas@nvidia.com [lorenzo.pieralisi@arm.com: completely rewrote the commit log/fixes tag] Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Acked-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pci-tegra.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index f4f53d092e00..2e1fd0c07cf1 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -545,12 +545,15 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_fixup_class); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_fixup_class);
-/* Tegra PCIE requires relaxed ordering */ +/* Tegra20 and Tegra30 PCIE requires relaxed ordering */ static void tegra_pcie_relax_enable(struct pci_dev *dev) { pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN); } -DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_relax_enable); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
static int tegra_pcie_request_resources(struct tegra_pcie *pcie) {
From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
[ Upstream commit f99536e9d2f55996038158a6559d4254a7cc1693 ]
The outbound memory windows PCI base addresses should be taken from the 'ranges' property of DT node to setup MEM/IO outbound windows decoding correctly instead of being hardcoded to zero.
Update the code to retrieve the PCI base address for each range and use it to program the outbound windows address decoders
Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP driver") Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Minghuan Lian Minghuan.Lian@nxp.com Reviewed-by: Subrahmanya Lingappa l.subrahmanya@mobiveil.co.in Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mobiveil.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c index a939e8d31735..d9f2d0f2d602 100644 --- a/drivers/pci/controller/pcie-mobiveil.c +++ b/drivers/pci/controller/pcie-mobiveil.c @@ -559,8 +559,9 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie) if (type) { /* configure outbound translation window */ program_ob_windows(pcie, pcie->ob_wins_configured, - win->res->start, 0, type, - resource_size(win->res)); + win->res->start, + win->res->start - win->offset, + type, resource_size(win->res)); } }
From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
[ Upstream commit 0122af0a08243f344a438f924e5c2486486555b3 ]
Fix up the Class Code field in PCI configuration space and set it to PCI_CLASS_BRIDGE_PCI.
Move the Class Code fixup to function mobiveil_host_init() where it belongs.
Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP driver") Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Minghuan Lian Minghuan.Lian@nxp.com Reviewed-by: Subrahmanya Lingappa l.subrahmanya@mobiveil.co.in Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mobiveil.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c index d9f2d0f2d602..3e81e68b5ce0 100644 --- a/drivers/pci/controller/pcie-mobiveil.c +++ b/drivers/pci/controller/pcie-mobiveil.c @@ -565,6 +565,12 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie) } }
+ /* fixup for PCIe class register */ + value = csr_readl(pcie, PAB_INTP_AXI_PIO_CLASS); + value &= 0xff; + value |= (PCI_CLASS_BRIDGE_PCI << 16); + csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS); + /* setup MSI hardware registers */ mobiveil_pcie_enable_msi(pcie);
@@ -805,9 +811,6 @@ static int mobiveil_pcie_probe(struct platform_device *pdev) goto error; }
- /* fixup for PCIe class register */ - csr_writel(pcie, 0x060402ab, PAB_INTP_AXI_PIO_CLASS); - /* initialize the IRQ domains */ ret = mobiveil_pcie_init_irq_domain(pcie); if (ret) {
From: Vasily Gorbik gor@linux.ibm.com
[ Upstream commit 33177f01ca3fe550146bb9001bec2fd806b2f40c ]
gcc asan instrumentation emits the following sequence to store frame pc when the kernel is built with CONFIG_RELOCATABLE: debug/vsprintf.s: .section .data.rel.ro.local,"aw" .align 8 .LC3: .quad .LASANPC4826@GOTOFF .text .align 8 .type number, @function number: .LASANPC4826:
and in case reloc is issued for LASANPC label it also gets into .symtab with the same address as actual function symbol: $ nm -n vmlinux | grep 0000000001397150 0000000001397150 t .LASANPC4826 0000000001397150 t number
In the end kernel backtraces are almost unreadable: [ 143.748476] Call Trace: [ 143.748484] ([<000000002da3e62c>] .LASANPC2671+0x114/0x190) [ 143.748492] [<000000002eca1a58>] .LASANPC2612+0x110/0x160 [ 143.748502] [<000000002de9d830>] print_address_description+0x80/0x3b0 [ 143.748511] [<000000002de9dd64>] __kasan_report+0x15c/0x1c8 [ 143.748521] [<000000002ecb56d4>] strrchr+0x34/0x60 [ 143.748534] [<000003ff800a9a40>] kasan_strings+0xb0/0x148 [test_kasan] [ 143.748547] [<000003ff800a9bba>] kmalloc_tests_init+0xe2/0x528 [test_kasan] [ 143.748555] [<000000002da2117c>] .LASANPC4069+0x354/0x748 [ 143.748563] [<000000002dbfbb16>] do_init_module+0x136/0x3b0 [ 143.748571] [<000000002dbff3f4>] .LASANPC3191+0x2164/0x25d0 [ 143.748580] [<000000002dbffc4c>] .LASANPC3196+0x184/0x1b8 [ 143.748587] [<000000002ecdf2ec>] system_call+0xd8/0x2d8
Since LASANPC labels are not even unique and get into .symtab only due to relocs filter them out in kallsyms.
Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/kallsyms.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 0c9c54b57515..31ed7f3f0e15 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -152,6 +152,9 @@ static int read_symbol(FILE *in, struct sym_entry *s) /* exclude debugging symbols */ else if (stype == 'N' || stype == 'n') return -1; + /* exclude s390 kasan local symbols */ + else if (!strncmp(sym, ".LASANPC", 8)) + return -1;
/* include the type field in the symbol name, so that it gets * compressed together */
From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
[ Upstream commit 6f3ab451aa5c2cbff33197d82fe8489cbd55ad91 ]
The reset value of Primary, Secondary and Subordinate bus numbers is zero which is a broken setup.
Program a sensible default value for Primary/Secondary/Subordinate bus numbers.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Minghuan Lian Minghuan.Lian@nxp.com Reviewed-by: Subrahmanya Lingappa l.subrahmanya@mobiveil.co.in Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mobiveil.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c index 3e81e68b5ce0..2fe7ebdad2d2 100644 --- a/drivers/pci/controller/pcie-mobiveil.c +++ b/drivers/pci/controller/pcie-mobiveil.c @@ -508,6 +508,12 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie) return err; }
+ /* setup bus numbers */ + value = csr_readl(pcie, PCI_PRIMARY_BUS); + value &= 0xff000000; + value |= 0x00ff0100; + csr_writel(pcie, value, PCI_PRIMARY_BUS); + /* * program Bus Master Enable Bit in Command Register in PAB Config * Space
From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
[ Upstream commit f7fee1b42fe4f8171a4b1cad05c61907c33c53f6 ]
The inbound and outbound windows have completely separate control registers sets in the host controller MMIO space. Windows control register are accessed through an MMIO base address and an offset that depends on the window index.
Since inbound and outbound windows control registers are completely separate there is no real need to use different window indexes in the inbound/outbound windows initialization routines to prevent clashing.
To fix this inconsistency, change the MEM inbound window index to 0, mirroring the outbound window set-up.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com [lorenzo.pieralisi@arm.com: update commit log] Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Minghuan Lian Minghuan.Lian@nxp.com Reviewed-by: Subrahmanya Lingappa l.subrahmanya@mobiveil.co.in Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mobiveil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c index 2fe7ebdad2d2..a2d1e89d4867 100644 --- a/drivers/pci/controller/pcie-mobiveil.c +++ b/drivers/pci/controller/pcie-mobiveil.c @@ -553,7 +553,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie) resource_size(pcie->ob_io_res));
/* memory inbound translation window */ - program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE); + program_ib_windows(pcie, WIN_NUM_0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
/* Get the I/O and memory ranges from DT */ resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
From: Numfor Mbiziwo-Tiapo nums@google.com
[ Upstream commit 4e4cf62b37da5ff45c904a3acf242ab29ed5881d ]
Running the 'perf test' command after building perf with a memory sanitizer causes a warning that says:
WARNING: MemorySanitizer: use-of-uninitialized-value... in mmap-thread-lookup.c
Initializing the go variable to 0 silences this harmless warning.
Committer warning:
This was harmless, just a simple test writing whatever was at that sizeof(int) memory area just to signal another thread blocked reading that file created with pipe(). Initialize it tho so that we don't get this warning.
Signed-off-by: Numfor Mbiziwo-Tiapo nums@google.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@redhat.com Cc: Mark Drayton mbd@fb.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Song Liu songliubraving@fb.com Cc: Stephane Eranian eranian@google.com Link: http://lkml.kernel.org/r/20190702173716.181223-1-nums@google.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/tests/mmap-thread-lookup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index b1af2499a3c9..7a9b123c7bfc 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -52,7 +52,7 @@ static void *thread_fn(void *arg) { struct thread_data *td = arg; ssize_t ret; - int go; + int go = 0;
if (thread_init(td)) return NULL;
From: Leo Yan leo.yan@linaro.org
[ Upstream commit c74b05030edb3b52f4208d8415b8c933bc509a29 ]
Based on the following report from Smatch, fix the use-after-freed pointer.
tools/perf/builtin-stat.c:1353 add_default_attributes() warn: passing freed memory 'str'.
The pointer 'str' has been freed but later it is still passed into the function parse_events_print_error(). This patch fixes this use-after-freed issue.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: Alexios Zavras alexios.zavras@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Changbin Du changbin.du@intel.com Cc: Davidlohr Bueso dave@stgolabs.net Cc: David S. Miller davem@davemloft.net Cc: Eric Saint-Etienne eric.saint.etienne@oracle.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Konstantin Khlebnikov khlebnikov@yandex-team.ru Cc: linux-arm-kernel@lists.infradead.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Song Liu songliubraving@fb.com Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Thomas Richter tmricht@linux.ibm.com Link: http://lkml.kernel.org/r/20190702103420.27540-3-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 40720150ccd8..789962565c9c 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2497,8 +2497,8 @@ static int add_default_attributes(void) fprintf(stderr, "Cannot set up top down events %s: %d\n", str, err); - free(str); parse_events_print_error(&errinfo, str); + free(str); return -1; } } else {
From: Leo Yan leo.yan@linaro.org
[ Upstream commit 111442cfc8abdeaa7ec1407f07ef7b3e5f76654e ]
Based on the following report from Smatch, fix the potential NULL pointer dereference check.
tools/perf/builtin-top.c:109 perf_top__parse_source() warn: variable dereferenced before check 'he' (see line 103)
tools/perf/builtin-top.c:233 perf_top__show_details() warn: variable dereferenced before check 'he' (see line 228)
tools/perf/builtin-top.c 101 static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) 102 { 103 struct perf_evsel *evsel = hists_to_evsel(he->hists); ^^^^ 104 struct symbol *sym; 105 struct annotation *notes; 106 struct map *map; 107 int err = -1; 108 109 if (!he || !he->ms.sym) 110 return -1;
This patch moves the values assignment after validating pointer 'he'.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: Alexios Zavras alexios.zavras@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Changbin Du changbin.du@intel.com Cc: David S. Miller davem@davemloft.net Cc: Davidlohr Bueso dave@stgolabs.net Cc: Eric Saint-Etienne eric.saint.etienne@oracle.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Konstantin Khlebnikov khlebnikov@yandex-team.ru Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Song Liu songliubraving@fb.com Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Thomas Richter tmricht@linux.ibm.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190702103420.27540-4-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-top.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 33eefc33e0ea..d0733251a386 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -99,7 +99,7 @@ static void perf_top__resize(struct perf_top *top)
static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) { - struct perf_evsel *evsel = hists_to_evsel(he->hists); + struct perf_evsel *evsel; struct symbol *sym; struct annotation *notes; struct map *map; @@ -108,6 +108,8 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) if (!he || !he->ms.sym) return -1;
+ evsel = hists_to_evsel(he->hists); + sym = he->ms.sym; map = he->ms.map;
@@ -224,7 +226,7 @@ static void perf_top__record_precise_ip(struct perf_top *top, static void perf_top__show_details(struct perf_top *top) { struct hist_entry *he = top->sym_filter_entry; - struct perf_evsel *evsel = hists_to_evsel(he->hists); + struct perf_evsel *evsel; struct annotation *notes; struct symbol *symbol; int more; @@ -232,6 +234,8 @@ static void perf_top__show_details(struct perf_top *top) if (!he) return;
+ evsel = hists_to_evsel(he->hists); + symbol = he->ms.sym; notes = symbol__annotation(symbol);
From: Leo Yan leo.yan@linaro.org
[ Upstream commit f3c8d90757724982e5f07cd77d315eb64ca145ac ]
Based on the following report from Smatch, fix the potential NULL pointer dereference check.
tools/perf/util/session.c:1252 dump_read() error: we previously assumed 'evsel' could be null (see line 1249)
tools/perf/util/session.c 1240 static void dump_read(struct perf_evsel *evsel, union perf_event *event) 1241 { 1242 struct read_event *read_event = &event->read; 1243 u64 read_format; 1244 1245 if (!dump_trace) 1246 return; 1247 1248 printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, 1249 evsel ? perf_evsel__name(evsel) : "FAIL", 1250 event->read.value); 1251 1252 read_format = evsel->attr.read_format; ^^^^^^^
'evsel' could be NULL pointer, for this case this patch directly bails out without dumping read_event.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: Alexios Zavras alexios.zavras@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Changbin Du changbin.du@intel.com Cc: David S. Miller davem@davemloft.net Cc: Davidlohr Bueso dave@stgolabs.net Cc: Eric Saint-Etienne eric.saint.etienne@oracle.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Konstantin Khlebnikov khlebnikov@yandex-team.ru Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Song Liu songliubraving@fb.com Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Thomas Richter tmricht@linux.ibm.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190702103420.27540-9-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/session.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 11086097fc9f..f016d1b330e5 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1141,6 +1141,9 @@ static void dump_read(struct perf_evsel *evsel, union perf_event *event) evsel ? perf_evsel__name(evsel) : "FAIL", event->read.value);
+ if (!evsel) + return; + read_format = evsel->attr.read_format;
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
From: Leo Yan leo.yan@linaro.org
[ Upstream commit 600c787dbf6521d8d07ee717ab7606d5070103ea ]
Based on the following report from Smatch, fix the potential dereferencing freed memory check.
tools/perf/util/annotate.c:1125 disasm_line__parse() error: dereferencing freed memory 'namep'
tools/perf/util/annotate.c 1100 static int disasm_line__parse(char *line, const char **namep, char **rawp) 1101 { 1102 char tmp, *name = ltrim(line);
[...]
1114 *namep = strdup(name); 1115 1116 if (*namep == NULL) 1117 goto out_free_name;
[...]
1124 out_free_name: 1125 free((void *)namep); ^^^^^ 1126 *namep = NULL; ^^^^^^ 1127 return -1; 1128 }
If strdup() fails to allocate memory space for *namep, we don't need to free memory with pointer 'namep', which is resident in data structure disasm_line::ins::name; and *namep is NULL pointer for this failure, so it's pointless to assign NULL to *namep again.
Committer note:
Freeing namep, which is the address of the first entry of the 'struct ins' that is the first member of struct disasm_line would in fact free that disasm_line instance, if it was allocated via malloc/calloc, which, later, would a dereference of freed memory.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: Alexios Zavras alexios.zavras@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Changbin Du changbin.du@intel.com Cc: David S. Miller davem@davemloft.net Cc: Davidlohr Bueso dave@stgolabs.net Cc: Eric Saint-Etienne eric.saint.etienne@oracle.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Konstantin Khlebnikov khlebnikov@yandex-team.ru Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Song Liu songliubraving@fb.com Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Thomas Richter tmricht@linux.ibm.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190702103420.27540-5-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/annotate.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index dfee110b3a58..63e2b4efe817 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1080,16 +1080,14 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp) *namep = strdup(name);
if (*namep == NULL) - goto out_free_name; + goto out;
(*rawp)[0] = tmp; *rawp = ltrim(*rawp);
return 0;
-out_free_name: - free((void *)namep); - *namep = NULL; +out: return -1; }
From: Leo Yan leo.yan@linaro.org
[ Upstream commit ceb75476db1617a88cc29b09839acacb69aa076e ]
Based on the following report from Smatch, fix the potential NULL pointer dereference check.
tools/perf/ui/browsers/hists.c:641 hist_browser__run() error: we previously assumed 'hbt' could be null (see line 625)
tools/perf/ui/browsers/hists.c:3088 perf_evsel__hists_browse() error: we previously assumed 'browser->he_selection' could be null (see line 2902)
tools/perf/ui/browsers/hists.c:3272 perf_evsel_menu__run() error: we previously assumed 'hbt' could be null (see line 3260)
This patch firstly validating the pointers before access them, so can fix potential NULL pointer dereference.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190708143937.7722-2-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/ui/browsers/hists.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index a96f62ca984a..692d2fa31c35 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -633,7 +633,11 @@ int hist_browser__run(struct hist_browser *browser, const char *help, switch (key) { case K_TIMER: { u64 nr_entries; - hbt->timer(hbt->arg); + + WARN_ON_ONCE(!hbt); + + if (hbt) + hbt->timer(hbt->arg);
if (hist_browser__has_filter(browser) || symbol_conf.report_hierarchy) @@ -2707,7 +2711,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, { struct hists *hists = evsel__hists(evsel); struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env, annotation_opts); - struct branch_info *bi; + struct branch_info *bi = NULL; #define MAX_OPTIONS 16 char *options[MAX_OPTIONS]; struct popup_action actions[MAX_OPTIONS]; @@ -2973,7 +2977,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, goto skip_annotation;
if (sort__mode == SORT_MODE__BRANCH) { - bi = browser->he_selection->branch_info; + + if (browser->he_selection) + bi = browser->he_selection->branch_info;
if (bi == NULL) goto skip_annotation; @@ -3144,7 +3150,8 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
switch (key) { case K_TIMER: - hbt->timer(hbt->arg); + if (hbt) + hbt->timer(hbt->arg);
if (!menu->lost_events_warned && menu->lost_events &&
From: Konstantin Taranov konstantin.taranov@inf.ethz.ch
[ Upstream commit bdce1290493caa3f8119f24b5dacc3fb7ca27389 ]
Calculate the correct byte_len on the receiving side when a work completion is generated with IB_WC_RECV_RDMA_WITH_IMM opcode.
According to the IBA byte_len must indicate the number of written bytes, whereas it was always equal to zero for the IB_WC_RECV_RDMA_WITH_IMM opcode, even though data was transferred.
Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Konstantin Taranov konstantin.taranov@inf.ethz.ch Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_resp.c | 5 ++++- drivers/infiniband/sw/rxe/rxe_verbs.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index 4111b798fd3c..681d8e0913d0 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c @@ -435,6 +435,7 @@ static enum resp_states check_rkey(struct rxe_qp *qp, qp->resp.va = reth_va(pkt); qp->resp.rkey = reth_rkey(pkt); qp->resp.resid = reth_len(pkt); + qp->resp.length = reth_len(pkt); } access = (pkt->mask & RXE_READ_MASK) ? IB_ACCESS_REMOTE_READ : IB_ACCESS_REMOTE_WRITE; @@ -859,7 +860,9 @@ static enum resp_states do_complete(struct rxe_qp *qp, pkt->mask & RXE_WRITE_MASK) ? IB_WC_RECV_RDMA_WITH_IMM : IB_WC_RECV; wc->vendor_err = 0; - wc->byte_len = wqe->dma.length - wqe->dma.resid; + wc->byte_len = (pkt->mask & RXE_IMMDT_MASK && + pkt->mask & RXE_WRITE_MASK) ? + qp->resp.length : wqe->dma.length - wqe->dma.resid;
/* fields after byte_len are different between kernel and user * space diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index 332a16dad2a7..3b731c7682e5 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -212,6 +212,7 @@ struct rxe_resp_info { struct rxe_mem *mr; u32 resid; u32 rkey; + u32 length; u64 atomic_orig;
/* SRQ only */
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit 381ed79c8655a40268ee7391f716edd90c5c3a97 ]
If CONFIG_GPIOLIB is not selected the compilation results in the following build errors:
drivers/pci/controller/dwc/pci-dra7xx.c: In function dra7xx_pcie_probe: drivers/pci/controller/dwc/pci-dra7xx.c:777:10: error: implicit declaration of function devm_gpiod_get_optional; did you mean devm_regulator_get_optional? [-Werror=implicit-function-declaration]
reset = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
drivers/pci/controller/dwc/pci-dra7xx.c:778:45: error: ‘GPIOD_OUT_HIGH’ undeclared (first use in this function); did you mean ‘GPIOF_INIT_HIGH’? reset = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH); ^~~~~~~~~~~~~~ GPIOF_INIT_HIGH
Fix them by including the appropriate header file.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: YueHaibing yuehaibing@huawei.com [lorenzo.pieralisi@arm.com: commit log] Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Acked-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pci-dra7xx.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index a32d6dde7a57..412524aa1fde 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c @@ -26,6 +26,7 @@ #include <linux/types.h> #include <linux/mfd/syscon.h> #include <linux/regmap.h> +#include <linux/gpio/consumer.h>
#include "../../pci.h" #include "pcie-designware.h"
From: Masahiro Yamada yamada.masahiro@socionext.com
[ Upstream commit 9e005b761e7ad153dcf40a6cba1d681fe0830ac6 ]
The next commit will make the way of passing CONFIG options more robust. Unfortunately, it would uncover another hidden issue; without this commit, skiroot_defconfig would be broken like this:
| WRAP arch/powerpc/boot/zImage.pseries | arch/powerpc/boot/wrapper.a(decompress.o): In function `bcj_powerpc.isra.10': | decompress.c:(.text+0x720): undefined reference to `get_unaligned_be32' | decompress.c:(.text+0x7a8): undefined reference to `put_unaligned_be32' | make[1]: *** [arch/powerpc/boot/Makefile;383: arch/powerpc/boot/zImage.pseries] Error 1 | make: *** [arch/powerpc/Makefile;295: zImage] Error 2
skiroot_defconfig is the only defconfig that enables CONFIG_KERNEL_XZ for ppc, which has never been correctly built before.
I figured out the root cause in lib/decompress_unxz.c:
| #ifdef CONFIG_PPC | # define XZ_DEC_POWERPC | #endif
CONFIG_PPC is undefined here in the ppc bootwrapper because autoconf.h is not included except by arch/powerpc/boot/serial.c
XZ_DEC_POWERPC is not defined, therefore, bcj_powerpc() is not compiled for the bootwrapper.
With the next commit passing CONFIG_PPC correctly, we would realize that {get,put}_unaligned_be32 was missing.
Unlike the other decompressors, the ppc bootwrapper duplicates all the necessary helpers in arch/powerpc/boot/.
The other architectures define __KERNEL__ and pull in helpers for building the decompressors.
If ppc bootwrapper had defined __KERNEL__, lib/xz/xz_private.h would have included <asm/unaligned.h>:
| #ifdef __KERNEL__ | # include <linux/xz.h> | # include <linux/kernel.h> | # include <asm/unaligned.h>
However, doing so would cause tons of definition conflicts since the bootwrapper has duplicated everything.
I just added copies of {get,put}_unaligned_be32, following the bootwrapper coding convention.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190705100144.28785-1-yamada.masahiro@socionext.c... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/boot/xz_config.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/arch/powerpc/boot/xz_config.h b/arch/powerpc/boot/xz_config.h index e22e5b3770dd..ebfadd39e192 100644 --- a/arch/powerpc/boot/xz_config.h +++ b/arch/powerpc/boot/xz_config.h @@ -20,10 +20,30 @@ static inline uint32_t swab32p(void *p)
#ifdef __LITTLE_ENDIAN__ #define get_le32(p) (*((uint32_t *) (p))) +#define cpu_to_be32(x) swab32(x) +static inline u32 be32_to_cpup(const u32 *p) +{ + return swab32p((u32 *)p); +} #else #define get_le32(p) swab32p(p) +#define cpu_to_be32(x) (x) +static inline u32 be32_to_cpup(const u32 *p) +{ + return *p; +} #endif
+static inline uint32_t get_unaligned_be32(const void *p) +{ + return be32_to_cpup(p); +} + +static inline void put_unaligned_be32(u32 val, void *p) +{ + *((u32 *)p) = cpu_to_be32(val); +} + #define memeq(a, b, size) (memcmp(a, b, size) == 0) #define memzero(buf, size) memset(buf, 0, size)
From: Josef Bacik josef@toxicpanda.com
[ Upstream commit b554db147feea39617b533ab6bca247c91c6198a ]
We discovered a problem in newer kernels where a disconnect of a NBD device while the flush request was pending would result in a hang. This is because the blk mq timeout handler does
if (!refcount_inc_not_zero(&rq->ref)) return true;
to determine if it's ok to run the timeout handler for the request. Flush_rq's don't have a ref count set, so we'd skip running the timeout handler for this request and it would just sit there in limbo forever.
Fix this by always setting the refcount of any request going through blk_init_rq() to 1. I tested this with a nbd-server that dropped flush requests to verify that it hung, and then tested with this patch to verify I got the timeout as expected and the error handling kicked in. Thanks,
Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/block/blk-core.c b/block/blk-core.c index 682bc561b77b..9ca703bcfe3b 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -198,6 +198,7 @@ void blk_rq_init(struct request_queue *q, struct request *rq) rq->internal_tag = -1; rq->start_time_ns = ktime_get_ns(); rq->part = NULL; + refcount_set(&rq->ref, 1); } EXPORT_SYMBOL(blk_rq_init);
From: Ocean Chen oceanchen@google.com
[ Upstream commit 56f3ce675103e3fb9e631cfb4131fc768bc23e9a ]
blkoff_off might over 512 due to fs corrupt or security vulnerability. That should be checked before being using.
Use ENTRIES_IN_SUM to protect invalid value in cur_data_blkoff.
Signed-off-by: Ocean Chen oceanchen@google.com Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/segment.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 8fc3edb6760c..92f72bb5aff4 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -3261,6 +3261,11 @@ static int read_compacted_summaries(struct f2fs_sb_info *sbi) seg_i = CURSEG_I(sbi, i); segno = le32_to_cpu(ckpt->cur_data_segno[i]); blk_off = le16_to_cpu(ckpt->cur_data_blkoff[i]); + if (blk_off > ENTRIES_IN_SUM) { + f2fs_bug_on(sbi, 1); + f2fs_put_page(page, 1); + return -EFAULT; + } seg_i->next_segno = segno; reset_curseg(sbi, i, 0); seg_i->alloc_type = ckpt->alloc_type[i];
From: morten petersen morten_bp@live.dk
[ Upstream commit 25777e5784a7b417967460d4fcf9660d05a0c320 ]
Previously, if mbox_request_channel_byname was used with a name which did not exist in the "mbox-names" property of a mailbox client, the mailbox corresponding to the last entry in the "mbox-names" list would be incorrectly selected. With this patch, -EINVAL is returned if the named mailbox is not found.
Signed-off-by: Morten Borup Petersen morten_bp@live.dk Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/mailbox.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index 674b35f402f5..055c90b8253c 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -391,11 +391,13 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
of_property_for_each_string(np, "mbox-names", prop, mbox_name) { if (!strncmp(name, mbox_name, strlen(name))) - break; + return mbox_request_channel(cl, index); index++; }
- return mbox_request_channel(cl, index); + dev_err(cl->dev, "%s() could not locate channel named "%s"\n", + __func__, name); + return ERR_PTR(-EINVAL); } EXPORT_SYMBOL_GPL(mbox_request_channel_byname);
From: David Windsor dwindsor@redhat.com
[ Upstream commit b355516f450703c9015316e429b66a93dfff0e6f ]
If the DLM lowcomms stack is shut down before any DLM traffic can be generated, flush_workqueue() and destroy_workqueue() can be called on empty send and/or recv workqueues.
Insert guard conditionals to only call flush_workqueue() and destroy_workqueue() on workqueues that are not NULL.
Signed-off-by: David Windsor dwindsor@redhat.com Signed-off-by: David Teigland teigland@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/dlm/lowcomms.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index a5e4a221435c..a93ebffe84b3 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -1630,8 +1630,10 @@ static void clean_writequeues(void)
static void work_stop(void) { - destroy_workqueue(recv_workqueue); - destroy_workqueue(send_workqueue); + if (recv_workqueue) + destroy_workqueue(recv_workqueue); + if (send_workqueue) + destroy_workqueue(send_workqueue); }
static int work_start(void) @@ -1691,13 +1693,17 @@ static void work_flush(void) struct hlist_node *n; struct connection *con;
- flush_workqueue(recv_workqueue); - flush_workqueue(send_workqueue); + if (recv_workqueue) + flush_workqueue(recv_workqueue); + if (send_workqueue) + flush_workqueue(send_workqueue); do { ok = 1; foreach_conn(stop_conn); - flush_workqueue(recv_workqueue); - flush_workqueue(send_workqueue); + if (recv_workqueue) + flush_workqueue(recv_workqueue); + if (send_workqueue) + flush_workqueue(send_workqueue); for (i = 0; i < CONN_HASH_SIZE && ok; i++) { hlist_for_each_entry_safe(con, n, &connection_hash[i], list) {
From: Oliver O'Halloran oohall@gmail.com
[ Upstream commit 33439620680be5225c1b8806579a291e0d761ca0 ]
In commit 4a7b06c157a2 ("powerpc/eeh: Handle hugepages in ioremap space") support for using hugepages in the vmalloc and ioremap areas was enabled for radix. Unfortunately this broke EEH MMIO error checking.
Detection works by inserting a hook which checks the results of the ioreadXX() set of functions. When a read returns a 0xFFs response we need to check for an error which we do by mapping the (virtual) MMIO address back to a physical address, then mapping physical address to a PCI device via an interval tree.
When translating virt -> phys we currently assume the ioremap space is only populated by PAGE_SIZE mappings. If a hugepage mapping is found we emit a WARN_ON(), but otherwise handles the check as though a normal page was found. In pathalogical cases such as copying a buffer containing a lot of 0xFFs from BAR memory this can result in the system not booting because it's too busy printing WARN_ON()s.
There's no real reason to assume huge pages can't be present and we're prefectly capable of handling them, so do that.
Fixes: 4a7b06c157a2 ("powerpc/eeh: Handle hugepages in ioremap space") Reported-by: Sachin Sant sachinp@linux.vnet.ibm.com Signed-off-by: Oliver O'Halloran oohall@gmail.com Tested-by: Sachin Sant sachinp@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190710150517.27114-1-oohall@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/eeh.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index c72767a5327a..fe3c6f3bd3b6 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -360,10 +360,19 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) ptep = find_init_mm_pte(token, &hugepage_shift); if (!ptep) return token; - WARN_ON(hugepage_shift); - pa = pte_pfn(*ptep) << PAGE_SHIFT;
- return pa | (token & (PAGE_SIZE-1)); + pa = pte_pfn(*ptep); + + /* On radix we can do hugepage mappings for io, so handle that */ + if (hugepage_shift) { + pa <<= hugepage_shift; + pa |= token & ((1ul << hugepage_shift) - 1); + } else { + pa <<= PAGE_SHIFT; + pa |= token & (PAGE_SIZE - 1); + } + + return pa; }
/*
From: Jan Höppner hoeppner@linux.ibm.com
[ Upstream commit ce6915f5343f5f2a2a937b683d8ffbf12dab3ad4 ]
The disk layout and volume information of a DASD reside in the first two tracks of cylinder 0. When a DASD is set online, currently the first three tracks are read and analysed to confirm an expected layout.
For CDL (Compatible Disk Layout) only count area data of the first track is evaluated and checked against expected key and data lengths. For LDL (Linux Disk Layout) the first and third track is evaluated. However, an LDL formatted volume is expected to be in the same format across all tracks. Checking the third track therefore doesn't have any more value than checking any other track at random.
Now, an Extent Space Efficient (ESE) DASD is initialised by only formatting the first two tracks, as those tracks always contain all information necessarry.
Checking the third track on an ESE volume will therefore most likely fail with a record not found error, as the third track will be empty. This in turn leads to the device being recognised with a volume size of 0. Attempts to write volume information on the first two tracks then fail with "no space left on device" errors.
Initialising the first three tracks for an ESE volume is not a viable solution, because the third track is already a regular track and could contain user data. With that there is potential for data corruption.
Instead, always only analyse the first two tracks, as it is sufficiant for both CDL and LDL, and allow ESE volumes to be recognised as well.
Signed-off-by: Jan Höppner hoeppner@linux.ibm.com Reviewed-by: Stefan Haberland sth@linux.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/block/dasd_eckd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index f89f9d02e788..fccdf9812c1f 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -157,7 +157,7 @@ static const int sizes_trk0[] = { 28, 148, 84 }; #define LABEL_SIZE 140
/* head and record addresses of count_area read in analysis ccw */ -static const int count_area_head[] = { 0, 0, 0, 0, 2 }; +static const int count_area_head[] = { 0, 0, 0, 0, 1 }; static const int count_area_rec[] = { 1, 2, 3, 4, 1 };
static inline unsigned int @@ -1823,8 +1823,8 @@ dasd_eckd_analysis_ccw(struct dasd_device *device) if (IS_ERR(cqr)) return cqr; ccw = cqr->cpaddr; - /* Define extent for the first 3 tracks. */ - define_extent(ccw++, cqr->data, 0, 2, + /* Define extent for the first 2 tracks. */ + define_extent(ccw++, cqr->data, 0, 1, DASD_ECKD_CCW_READ_COUNT, device, 0); LO_data = cqr->data + sizeof(struct DE_eckd_data); /* Locate record for the first 4 records on track 0. */ @@ -1843,9 +1843,9 @@ dasd_eckd_analysis_ccw(struct dasd_device *device) count_data++; }
- /* Locate record for the first record on track 2. */ + /* Locate record for the first record on track 1. */ ccw[-1].flags |= CCW_FLAG_CC; - locate_record(ccw++, LO_data++, 2, 0, 1, + locate_record(ccw++, LO_data++, 1, 0, 1, DASD_ECKD_CCW_READ_COUNT, device, 0); /* Read count ccw. */ ccw[-1].flags |= CCW_FLAG_CC; @@ -1967,7 +1967,7 @@ static int dasd_eckd_end_analysis(struct dasd_block *block) } } if (i == 3) - count_area = &private->count_area[4]; + count_area = &private->count_area[3];
if (private->uses_cdl == 0) { for (i = 0; i < 5; i++) {
From: Wenwen Wang wenwen@cs.uga.edu
[ Upstream commit e7bf90e5afe3aa1d1282c1635a49e17a32c4ecec ]
In bio_integrity_prep(), a kernel buffer is allocated through kmalloc() to hold integrity metadata. Later on, the buffer will be attached to the bio structure through bio_integrity_add_page(), which returns the number of bytes of integrity metadata attached. Due to unexpected situations, bio_integrity_add_page() may return 0. As a result, bio_integrity_prep() needs to be terminated with 'false' returned to indicate this error. However, the allocated kernel buffer is not freed on this execution path, leading to a memory leak.
To fix this issue, free the allocated buffer before returning from bio_integrity_prep().
Reviewed-by: Ming Lei ming.lei@redhat.com Acked-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Wenwen Wang wenwen@cs.uga.edu Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bio-integrity.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 67b5fb861a51..5bd90cd4b51e 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -291,8 +291,12 @@ bool bio_integrity_prep(struct bio *bio) ret = bio_integrity_add_page(bio, virt_to_page(buf), bytes, offset);
- if (ret == 0) - return false; + if (ret == 0) { + printk(KERN_ERR "could not attach integrity payload\n"); + kfree(buf); + status = BLK_STS_RESOURCE; + goto err_end_io; + }
if (ret < bytes) break;
From: Sam Ravnborg sam@ravnborg.org
[ Upstream commit 733f0025f0fb43e382b84db0930ae502099b7e62 ]
When building drm/exynos for sh, as part of an allmodconfig build, the following warning triggered:
exynos7_drm_decon.c: In function `decon_remove': exynos7_drm_decon.c:769:24: warning: unused variable `ctx' struct decon_context *ctx = dev_get_drvdata(&pdev->dev);
The ctx variable is only used as argument to iounmap().
In sh - allmodconfig CONFIG_MMU is not defined so it ended up in:
#define __iounmap(addr) do { } while (0) #define iounmap __iounmap
Fix the warning by introducing a static inline function for iounmap.
This is similar to several other architectures.
Link: http://lkml.kernel.org/r/20190622114208.24427-1-sam@ravnborg.org Signed-off-by: Sam Ravnborg sam@ravnborg.org Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: Rich Felker dalias@libc.org Cc: Will Deacon will.deacon@arm.com Cc: Mark Brown broonie@kernel.org Cc: Inki Dae inki.dae@samsung.com Cc: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sh/include/asm/io.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 98cb8c802b1a..0ae60d680000 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -371,7 +371,11 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
#define ioremap_nocache ioremap #define ioremap_uc ioremap -#define iounmap __iounmap + +static inline void iounmap(void __iomem *addr) +{ + __iounmap(addr); +}
/* * Convert a physical pointer to a virtual kernel pointer for /dev/mem
From: Dmitry Vyukov dvyukov@google.com
[ Upstream commit 6ef9056952532c3b746de46aa10d45b4d7797bd8 ]
in_softirq() is a wrong predicate to check if we are in a softirq context. It also returns true if we have BH disabled, so objects are falsely stamped with "softirq" comm. The correct predicate is in_serving_softirq().
If user does cat from /sys/kernel/debug/kmemleak previously they would see this, which is clearly wrong, this is system call context (see the comm):
unreferenced object 0xffff88805bd661c0 (size 64): comm "softirq", pid 0, jiffies 4294942959 (age 12.400s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 ................ 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................ backtrace: [<0000000007dcb30c>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline] [<0000000007dcb30c>] slab_post_alloc_hook mm/slab.h:439 [inline] [<0000000007dcb30c>] slab_alloc mm/slab.c:3326 [inline] [<0000000007dcb30c>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553 [<00000000969722b7>] kmalloc include/linux/slab.h:547 [inline] [<00000000969722b7>] kzalloc include/linux/slab.h:742 [inline] [<00000000969722b7>] ip_mc_add1_src net/ipv4/igmp.c:1961 [inline] [<00000000969722b7>] ip_mc_add_src+0x36b/0x400 net/ipv4/igmp.c:2085 [<00000000a4134b5f>] ip_mc_msfilter+0x22d/0x310 net/ipv4/igmp.c:2475 [<00000000d20248ad>] do_ip_setsockopt.isra.0+0x19fe/0x1c00 net/ipv4/ip_sockglue.c:957 [<000000003d367be7>] ip_setsockopt+0x3b/0xb0 net/ipv4/ip_sockglue.c:1246 [<000000003c7c76af>] udp_setsockopt+0x4e/0x90 net/ipv4/udp.c:2616 [<000000000c1aeb23>] sock_common_setsockopt+0x3e/0x50 net/core/sock.c:3130 [<000000000157b92b>] __sys_setsockopt+0x9e/0x120 net/socket.c:2078 [<00000000a9f3d058>] __do_sys_setsockopt net/socket.c:2089 [inline] [<00000000a9f3d058>] __se_sys_setsockopt net/socket.c:2086 [inline] [<00000000a9f3d058>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2086 [<000000001b8da885>] do_syscall_64+0x7c/0x1a0 arch/x86/entry/common.c:301 [<00000000ba770c62>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
now they will see this:
unreferenced object 0xffff88805413c800 (size 64): comm "syz-executor.4", pid 8960, jiffies 4294994003 (age 14.350s) hex dump (first 32 bytes): 00 7a 8a 57 80 88 ff ff e0 00 00 01 00 00 00 00 .z.W............ 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................ backtrace: [<00000000c5d3be64>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline] [<00000000c5d3be64>] slab_post_alloc_hook mm/slab.h:439 [inline] [<00000000c5d3be64>] slab_alloc mm/slab.c:3326 [inline] [<00000000c5d3be64>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553 [<0000000023865be2>] kmalloc include/linux/slab.h:547 [inline] [<0000000023865be2>] kzalloc include/linux/slab.h:742 [inline] [<0000000023865be2>] ip_mc_add1_src net/ipv4/igmp.c:1961 [inline] [<0000000023865be2>] ip_mc_add_src+0x36b/0x400 net/ipv4/igmp.c:2085 [<000000003029a9d4>] ip_mc_msfilter+0x22d/0x310 net/ipv4/igmp.c:2475 [<00000000ccd0a87c>] do_ip_setsockopt.isra.0+0x19fe/0x1c00 net/ipv4/ip_sockglue.c:957 [<00000000a85a3785>] ip_setsockopt+0x3b/0xb0 net/ipv4/ip_sockglue.c:1246 [<00000000ec13c18d>] udp_setsockopt+0x4e/0x90 net/ipv4/udp.c:2616 [<0000000052d748e3>] sock_common_setsockopt+0x3e/0x50 net/core/sock.c:3130 [<00000000512f1014>] __sys_setsockopt+0x9e/0x120 net/socket.c:2078 [<00000000181758bc>] __do_sys_setsockopt net/socket.c:2089 [inline] [<00000000181758bc>] __se_sys_setsockopt net/socket.c:2086 [inline] [<00000000181758bc>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2086 [<00000000d4b73623>] do_syscall_64+0x7c/0x1a0 arch/x86/entry/common.c:301 [<00000000c1098bec>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
Link: http://lkml.kernel.org/r/20190517171507.96046-1-dvyukov@gmail.com Signed-off-by: Dmitry Vyukov dvyukov@google.com Acked-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/kmemleak.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 72e3fb3bb037..6c94b6865ac2 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -576,7 +576,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, if (in_irq()) { object->pid = 0; strncpy(object->comm, "hardirq", sizeof(object->comm)); - } else if (in_softirq()) { + } else if (in_serving_softirq()) { object->pid = 0; strncpy(object->comm, "softirq", sizeof(object->comm)); } else {
From: Christoph Hellwig hch@lst.de
[ Upstream commit f053cbd4366051d7eb6ba1b8d529d20f719c2963 ]
Fix the callback 9p passes to read_cache_page to actually have the proper type expected. Casting around function pointers can easily hide typing bugs, and defeats control flow protection.
Link: http://lkml.kernel.org/r/20190520055731.24538-5-hch@lst.de Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Kees Cook keescook@chromium.org Cc: Sami Tolvanen samitolvanen@google.com Cc: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/9p/vfs_addr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index e1cbdfdb7c68..197069303510 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -50,8 +50,9 @@ * @page: structure to page * */ -static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page) +static int v9fs_fid_readpage(void *data, struct page *page) { + struct p9_fid *fid = data; struct inode *inode = page->mapping->host; struct bio_vec bvec = {.bv_page = page, .bv_len = PAGE_SIZE}; struct iov_iter to; @@ -122,7 +123,8 @@ static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping, if (ret == 0) return ret;
- ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp); + ret = read_cache_pages(mapping, pages, v9fs_fid_readpage, + filp->private_data); p9_debug(P9_DEBUG_VFS, " = %d\n", ret); return ret; }
From: Guenter Roeck linux@roeck-us.net
[ Upstream commit 790c73690c2bbecb3f6f8becbdb11ddc9bcff8cc ]
Several mips builds generate the following build warning.
mm/gup.c:1788:13: warning: 'undo_dev_pagemap' defined but not used
The function is declared unconditionally but only called from behind various ifdefs. Mark it __maybe_unused.
Link: http://lkml.kernel.org/r/1562072523-22311-1-git-send-email-linux@roeck-us.ne... Signed-off-by: Guenter Roeck linux@roeck-us.net Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Stephen Rothwell sfr@canb.auug.org.au Cc: Robin Murphy robin.murphy@arm.com Cc: Kirill A. Shutemov kirill.shutemov@linux.intel.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/gup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/gup.c b/mm/gup.c index caadd31714a5..43c71397c7ca 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1367,7 +1367,8 @@ static inline pte_t gup_get_pte(pte_t *ptep) } #endif
-static void undo_dev_pagemap(int *nr, int nr_start, struct page **pages) +static void __maybe_unused undo_dev_pagemap(int *nr, int nr_start, + struct page **pages) { while ((*nr) - nr_start) { struct page *page = pages[--(*nr)];
From: Andy Lutomirski luto@kernel.org
[ Upstream commit b5d1c39f34d1c9bca0c4b9ae2e339fbbe264a9c7 ]
If we end up without a PGD or PUD entry backing the gate area, don't BUG -- just fail gracefully.
It's not entirely implausible that this could happen some day on x86. It doesn't right now even with an execute-only emulated vsyscall page because the fixmap shares the PUD, but the core mm code shouldn't rely on that particular detail to avoid OOPSing.
Link: http://lkml.kernel.org/r/a1d9f4efb75b9d464e59fd6af00104b21c58f6f7.1561610798... Signed-off-by: Andy Lutomirski luto@kernel.org Reviewed-by: Kees Cook keescook@chromium.org Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Florian Weimer fweimer@redhat.com Cc: Jann Horn jannh@google.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/gup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/mm/gup.c b/mm/gup.c index 43c71397c7ca..f3088d25bd92 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -458,11 +458,14 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address, pgd = pgd_offset_k(address); else pgd = pgd_offset_gate(mm, address); - BUG_ON(pgd_none(*pgd)); + if (pgd_none(*pgd)) + return -EFAULT; p4d = p4d_offset(pgd, address); - BUG_ON(p4d_none(*p4d)); + if (p4d_none(*p4d)) + return -EFAULT; pud = pud_offset(p4d, address); - BUG_ON(pud_none(*pud)); + if (pud_none(*pud)) + return -EFAULT; pmd = pmd_offset(pud, address); if (!pmd_present(*pmd)) return -EFAULT;
From: Shakeel Butt shakeelb@google.com
[ Upstream commit ec165450968b26298bd1c373de37b0ab6d826b33 ]
Commit d46eb14b735b ("fs: fsnotify: account fsnotify metadata to kmemcg") added remote memcg charging for fanotify and inotify event objects. The aim was to charge the memory to the listener who is interested in the events but without triggering the OOM killer. Otherwise there would be security concerns for the listener.
At the time, oom-kill trigger was not in the charging path. A parallel work added the oom-kill back to charging path i.e. commit 29ef680ae7c2 ("memcg, oom: move out_of_memory back to the charge path"). So to not trigger oom-killer in the remote memcg, explicitly add __GFP_RETRY_MAYFAIL to the fanotigy and inotify event allocations.
Link: http://lkml.kernel.org/r/20190514212259.156585-2-shakeelb@google.com Signed-off-by: Shakeel Butt shakeelb@google.com Reviewed-by: Roman Gushchin guro@fb.com Acked-by: Jan Kara jack@suse.cz Cc: Johannes Weiner hannes@cmpxchg.org Cc: Vladimir Davydov vdavydov.dev@gmail.com Cc: Michal Hocko mhocko@suse.com Cc: Amir Goldstein amir73il@gmail.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/notify/fanotify/fanotify.c | 5 ++++- fs/notify/inotify/inotify_fsnotify.c | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 29dee9630eec..a18b8d7a3075 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -148,10 +148,13 @@ struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group, /* * For queues with unlimited length lost events are not expected and * can possibly have security implications. Avoid losing events when - * memory is short. + * memory is short. For the limited size queues, avoid OOM killer in the + * target monitoring memcg as it may have security repercussion. */ if (group->max_events == UINT_MAX) gfp |= __GFP_NOFAIL; + else + gfp |= __GFP_RETRY_MAYFAIL;
/* Whoever is interested in the event, pays for the allocation. */ memalloc_use_memcg(group->memcg); diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index f4184b4f3815..16b8702af0e7 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -99,9 +99,13 @@ int inotify_handle_event(struct fsnotify_group *group, i_mark = container_of(inode_mark, struct inotify_inode_mark, fsn_mark);
- /* Whoever is interested in the event, pays for the allocation. */ + /* + * Whoever is interested in the event, pays for the allocation. Do not + * trigger OOM killer in the target monitoring memcg as it may have + * security repercussion. + */ memalloc_use_memcg(group->memcg); - event = kmalloc(alloc_len, GFP_KERNEL_ACCOUNT); + event = kmalloc(alloc_len, GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL); memalloc_unuse_memcg();
if (unlikely(!event)) {
From: Jean-Philippe Brucker jean-philippe.brucker@arm.com
[ Upstream commit 543bdb2d825fe2400d6e951f1786d92139a16931 ]
Make mmu_notifier_register() safer by issuing a memory barrier before registering a new notifier. This fixes a theoretical bug on weakly ordered CPUs. For example, take this simplified use of notifiers by a driver:
my_struct->mn.ops = &my_ops; /* (1) */ mmu_notifier_register(&my_struct->mn, mm) ... hlist_add_head(&mn->hlist, &mm->mmu_notifiers); /* (2) */ ...
Once mmu_notifier_register() releases the mm locks, another thread can invalidate a range:
mmu_notifier_invalidate_range() ... hlist_for_each_entry_rcu(mn, &mm->mmu_notifiers, hlist) { if (mn->ops->invalidate_range)
The read side relies on the data dependency between mn and ops to ensure that the pointer is properly initialized. But the write side doesn't have any dependency between (1) and (2), so they could be reordered and the readers could dereference an invalid mn->ops. mmu_notifier_register() does take all the mm locks before adding to the hlist, but those have acquire semantics which isn't sufficient.
By calling hlist_add_head_rcu() instead of hlist_add_head() we update the hlist using a store-release, ensuring that readers see prior initialization of my_struct. This situation is better illustated by litmus test MP+onceassign+derefonce.
Link: http://lkml.kernel.org/r/20190502133532.24981-1-jean-philippe.brucker@arm.co... Fixes: cddb8a5c14aa ("mmu-notifiers: core") Signed-off-by: Jean-Philippe Brucker jean-philippe.brucker@arm.com Cc: Jérôme Glisse jglisse@redhat.com Cc: Michal Hocko mhocko@suse.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/mmu_notifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index 82bb1a939c0e..06dedb175572 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c @@ -316,7 +316,7 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn, * thanks to mm_take_all_locks(). */ spin_lock(&mm->mmu_notifier_mm->lock); - hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list); + hlist_add_head_rcu(&mn->hlist, &mm->mmu_notifier_mm->list); spin_unlock(&mm->mmu_notifier_mm->lock);
mm_drop_all_locks(mm);
From: Konstantin Khlebnikov khlebnikov@yandex-team.ru
[ Upstream commit a26a97815548574213fd37f29b4b78ccc6d9ed20 ]
Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
Link: http://lkml.kernel.org/r/156007493429.3335.14666825072272692455.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Roman Gushchin guro@fb.com Reviewed-by: Cyrill Gorcunov gorcunov@gmail.com Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Matthew Wilcox willy@infradead.org Cc: Michal Koutný mkoutny@suse.com Cc: Oleg Nesterov oleg@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/task_mmu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index c5819baee35c..b2010055180e 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -826,7 +826,10 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
memset(&mss, 0, sizeof(mss));
- down_read(&mm->mmap_sem); + ret = down_read_killable(&mm->mmap_sem); + if (ret) + goto out_put_mm; + hold_task_mempolicy(priv);
for (vma = priv->mm->mmap; vma; vma = vma->vm_next) { @@ -843,8 +846,9 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
release_task_mempolicy(priv); up_read(&mm->mmap_sem); - mmput(mm);
+out_put_mm: + mmput(mm); out_put_task: put_task_struct(priv->task); priv->task = NULL;
From: Konstantin Khlebnikov khlebnikov@yandex-team.ru
[ Upstream commit ad80b932c57d85fd6377f97f359b025baf179a87 ]
Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
Link: http://lkml.kernel.org/r/156007493638.3335.4872164955523928492.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Roman Gushchin guro@fb.com Reviewed-by: Cyrill Gorcunov gorcunov@gmail.com Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Matthew Wilcox willy@infradead.org Cc: Michal Koutný mkoutny@suse.com Cc: Oleg Nesterov oleg@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/task_mmu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index b2010055180e..74965e17ffd5 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1535,7 +1535,9 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, /* overflow ? */ if (end < start_vaddr || end > end_vaddr) end = end_vaddr; - down_read(&mm->mmap_sem); + ret = down_read_killable(&mm->mmap_sem); + if (ret) + goto out_free; ret = walk_page_range(start_vaddr, end, &pagemap_walk); up_read(&mm->mmap_sem); start_vaddr = end;
From: Konstantin Khlebnikov khlebnikov@yandex-team.ru
[ Upstream commit c46038017fbdcac627b670c9d4176f1d0c2f5fa3 ]
Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
Replace the only unkillable mmap_sem lock in clear_refs_write().
Link: http://lkml.kernel.org/r/156007493826.3335.5424884725467456239.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Roman Gushchin guro@fb.com Reviewed-by: Cyrill Gorcunov gorcunov@gmail.com Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Matthew Wilcox willy@infradead.org Cc: Michal Koutný mkoutny@suse.com Cc: Oleg Nesterov oleg@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/task_mmu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 74965e17ffd5..195fbbaf77d4 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1131,7 +1131,10 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, goto out_mm; }
- down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) { + count = -EINTR; + goto out_mm; + } tlb_gather_mmu(&tlb, mm, 0, -1); if (type == CLEAR_REFS_SOFT_DIRTY) { for (vma = mm->mmap; vma; vma = vma->vm_next) {
From: Konstantin Khlebnikov khlebnikov@yandex-team.ru
[ Upstream commit cd9e2bb8271c971d9f37c722be2616c7f8ba0664 ]
Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
It seems ->d_revalidate() could return any error (except ECHILD) to abort validation and pass error as result of lookup sequence.
[akpm@linux-foundation.org: fix proc_map_files_lookup() return value, per Andrei] Link: http://lkml.kernel.org/r/156007493995.3335.9595044802115356911.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Roman Gushchin guro@fb.com Reviewed-by: Cyrill Gorcunov gorcunov@gmail.com Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Matthew Wilcox willy@infradead.org Cc: Michal Koutný mkoutny@suse.com Cc: Oleg Nesterov oleg@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/base.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c index f999e8bd3771..a7fbda72afeb 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1960,9 +1960,12 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags) goto out;
if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) { - down_read(&mm->mmap_sem); - exact_vma_exists = !!find_exact_vma(mm, vm_start, vm_end); - up_read(&mm->mmap_sem); + status = down_read_killable(&mm->mmap_sem); + if (!status) { + exact_vma_exists = !!find_exact_vma(mm, vm_start, + vm_end); + up_read(&mm->mmap_sem); + } }
mmput(mm); @@ -2008,8 +2011,11 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) if (rc) goto out_mmput;
+ rc = down_read_killable(&mm->mmap_sem); + if (rc) + goto out_mmput; + rc = -ENOENT; - down_read(&mm->mmap_sem); vma = find_exact_vma(mm, vm_start, vm_end); if (vma && vma->vm_file) { *path = vma->vm_file->f_path; @@ -2105,7 +2111,11 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, if (!mm) goto out_put_task;
- down_read(&mm->mmap_sem); + result = ERR_PTR(-EINTR); + if (down_read_killable(&mm->mmap_sem)) + goto out_put_mm; + + result = ERR_PTR(-ENOENT); vma = find_exact_vma(mm, vm_start, vm_end); if (!vma) goto out_no_vma; @@ -2116,6 +2126,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
out_no_vma: up_read(&mm->mmap_sem); +out_put_mm: mmput(mm); out_put_task: put_task_struct(task); @@ -2157,7 +2168,12 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx) mm = get_task_mm(task); if (!mm) goto out_put_task; - down_read(&mm->mmap_sem); + + ret = down_read_killable(&mm->mmap_sem); + if (ret) { + mmput(mm); + goto out_put_task; + }
nr_files = 0;
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 752c2ea2d8e7c23b0f64e2e7d4337f3604d44c9f ]
The cudbg_collect_mem_region() and cudbg_read_fw_mem() both use several hundred kilobytes of kernel stack space. One gets inlined into the other, which causes the stack usage to be combined beyond the warning limit when building with clang:
drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c:1057:12: error: stack frame size of 1244 bytes in function 'cudbg_collect_mem_region' [-Werror,-Wframe-larger-than=]
Restructuring cudbg_collect_mem_region() lets clang do the same optimization that gcc does and reuse the stack slots as it can see that the large variables are never used together.
A better fix might be to avoid using cudbg_meminfo on the stack altogether, but that requires a larger rewrite.
Fixes: a1c69520f785 ("cxgb4: collect MC memory dump") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/chelsio/cxgb4/cudbg_lib.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c index d97e0d7e541a..b766362031c3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c @@ -1065,14 +1065,12 @@ static void cudbg_t4_fwcache(struct cudbg_init *pdbg_init, } }
-static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init, - struct cudbg_buffer *dbg_buff, - struct cudbg_error *cudbg_err, - u8 mem_type) +static unsigned long cudbg_mem_region_size(struct cudbg_init *pdbg_init, + struct cudbg_error *cudbg_err, + u8 mem_type) { struct adapter *padap = pdbg_init->adap; struct cudbg_meminfo mem_info; - unsigned long size; u8 mc_idx; int rc;
@@ -1086,7 +1084,16 @@ static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init, if (rc) return rc;
- size = mem_info.avail[mc_idx].limit - mem_info.avail[mc_idx].base; + return mem_info.avail[mc_idx].limit - mem_info.avail[mc_idx].base; +} + +static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init, + struct cudbg_buffer *dbg_buff, + struct cudbg_error *cudbg_err, + u8 mem_type) +{ + unsigned long size = cudbg_mem_region_size(pdbg_init, cudbg_err, mem_type); + return cudbg_read_fw_mem(pdbg_init, dbg_buff, mem_type, size, cudbg_err); }
From: Konstantin Khlebnikov khlebnikov@yandex-team.ru
[ Upstream commit 8a713e7df3352b8d9392476e9cf29e4e185dac32 ]
Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
This function is also used for /proc/pid/smaps.
Link: http://lkml.kernel.org/r/156007493160.3335.14447544314127417266.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Roman Gushchin guro@fb.com Reviewed-by: Cyrill Gorcunov gorcunov@gmail.com Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Matthew Wilcox willy@infradead.org Cc: Michal Koutný mkoutny@suse.com Cc: Oleg Nesterov oleg@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/task_mmu.c | 6 +++++- fs/proc/task_nommu.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 195fbbaf77d4..71aba44c4fa6 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -166,7 +166,11 @@ static void *m_start(struct seq_file *m, loff_t *ppos) if (!mm || !mmget_not_zero(mm)) return NULL;
- down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) { + mmput(mm); + return ERR_PTR(-EINTR); + } + hold_task_mempolicy(priv); priv->tail_vma = get_gate_vma(mm);
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 0b63d68dedb2..5161894a6d62 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c @@ -211,7 +211,11 @@ static void *m_start(struct seq_file *m, loff_t *pos) if (!mm || !mmget_not_zero(mm)) return NULL;
- down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) { + mmput(mm); + return ERR_PTR(-EINTR); + } + /* start from the Nth VMA */ for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) if (n-- == 0)
From: Yuyang Du duyuyang@gmail.com
[ Upstream commit 68d41d8c94a31dfb8233ab90b9baf41a2ed2da68 ]
The stats variable nr_unused_locks is incremented every time a new lock class is register and decremented when the lock is first used in __lock_acquire(). And after all, it is shown and checked in lockdep_stats.
However, under configurations that either CONFIG_TRACE_IRQFLAGS or CONFIG_PROVE_LOCKING is not defined:
The commit:
091806515124b20 ("locking/lockdep: Consolidate lock usage bit initialization")
missed marking the LOCK_USED flag at IRQ usage initialization because as mark_usage() is not called. And the commit:
886532aee3cd42d ("locking/lockdep: Move mark_lock() inside CONFIG_TRACE_IRQFLAGS && CONFIG_PROVE_LOCKING")
further made mark_lock() not defined such that the LOCK_USED cannot be marked at all when the lock is first acquired.
As a result, we fix this by not showing and checking the stats under such configurations for lockdep_stats.
Reported-by: Qian Cai cai@lca.pw Signed-off-by: Yuyang Du duyuyang@gmail.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Andrew Morton akpm@linux-foundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Paul E. McKenney paulmck@linux.vnet.ibm.com Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Will Deacon will.deacon@arm.com Cc: arnd@arndb.de Cc: frederic@kernel.org Link: https://lkml.kernel.org/r/20190709101522.9117-1-duyuyang@gmail.com Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/locking/lockdep_proc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c index 3dd980dfba2d..6cf288eef670 100644 --- a/kernel/locking/lockdep_proc.c +++ b/kernel/locking/lockdep_proc.c @@ -210,6 +210,7 @@ static int lockdep_stats_show(struct seq_file *m, void *v) nr_hardirq_read_safe = 0, nr_hardirq_read_unsafe = 0, sum_forward_deps = 0;
+#ifdef CONFIG_PROVE_LOCKING list_for_each_entry(class, &all_lock_classes, lock_entry) {
if (class->usage_mask == 0) @@ -241,12 +242,12 @@ static int lockdep_stats_show(struct seq_file *m, void *v) if (class->usage_mask & LOCKF_ENABLED_HARDIRQ_READ) nr_hardirq_read_unsafe++;
-#ifdef CONFIG_PROVE_LOCKING sum_forward_deps += lockdep_count_forward_deps(class); -#endif } #ifdef CONFIG_DEBUG_LOCKDEP DEBUG_LOCKS_WARN_ON(debug_atomic_read(nr_unused_locks) != nr_unused); +#endif + #endif seq_printf(m, " lock-classes: %11lu [max: %lu]\n", nr_lock_classes, MAX_LOCKDEP_KEYS);
From: Konstantin Khlebnikov khlebnikov@yandex-team.ru
[ Upstream commit 1e426fe28261b03f297992e89da3320b42816f4e ]
This function is used by ptrace and proc files like /proc/pid/cmdline and /proc/pid/environ.
Access_remote_vm never returns error codes, all errors are ignored and only size of successfully read data is returned. So, if current task was killed we'll simply return 0 (bytes read).
Mmap_sem could be locked for a long time or forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
Link: http://lkml.kernel.org/r/156007494202.3335.16782303099589302087.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Michal Koutný mkoutny@suse.com Acked-by: Oleg Nesterov oleg@redhat.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Matthew Wilcox willy@infradead.org Cc: Cyrill Gorcunov gorcunov@gmail.com Cc: Kirill Tkhai ktkhai@virtuozzo.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Roman Gushchin guro@fb.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/memory.c | 4 +++- mm/nommu.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c index e0010cb870e0..fb5655b518c9 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4491,7 +4491,9 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, void *old_buf = buf; int write = gup_flags & FOLL_WRITE;
- down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) + return 0; + /* ignore errors, just check how much was successfully transferred */ while (len) { int bytes, ret, offset; diff --git a/mm/nommu.c b/mm/nommu.c index e4aac33216ae..1d63ecfc98c5 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1779,7 +1779,8 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, struct vm_area_struct *vma; int write = gup_flags & FOLL_WRITE;
- down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) + return 0;
/* the access must start within one of the target process's mappings */ vma = find_vma(mm, addr);
linux-stable-mirror@lists.linaro.org