From af82800cd2d9cfcae2de1b47a35c26c147b9cdd1 Mon Sep 17 00:00:00 2001 From: wangbo Date: Thu, 12 Apr 2018 16:58:08 +0800 Subject: spi: imx: Update MODULE_DESCRIPTION to "SPI Controller driver" Now i.MX SPI controller can work in Slave mode. Update MODULE_DESCRIPTION to "SPI Controller driver". Signed-off-by: wangbo Signed-off-by: Mark Brown --- drivers/spi/spi-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 6f57592a7f95..a056ee88a960 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1701,7 +1701,7 @@ static struct platform_driver spi_imx_driver = { }; module_platform_driver(spi_imx_driver); -MODULE_DESCRIPTION("SPI Master Controller driver"); +MODULE_DESCRIPTION("SPI Controller driver"); MODULE_AUTHOR("Sascha Hauer, Pengutronix"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRIVER_NAME); -- cgit v1.2.3-59-g8ed1b From 10b4640833e95eeacaef8060bc1b35e636df3218 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Fri, 13 Apr 2018 15:44:16 +0300 Subject: spi: sh-msiof: Fix bit field overflow writes to TSCR/RSCR The change fixes a bit field overflow which allows to write to higher bits while calculating SPI transfer clock and setting BRPS and BRDV bit fields, the problem is reproduced if 'parent_rate' to 'spi_hz' ratio is greater than 1024, for instance p->min_div = 2, MSO rate = 33333333, SPI device rate = 10000 results in k = 5, i.e. BRDV = 0b100 or 1/32 prescaler output, BRPS = 105, TSCR value = 0x6804, thus MSSEL and MSIMM bit fields are non-zero. Fixes: 65d5665bb260 ("spi: sh-msiof: Update calculation of frequency dividing") Signed-off-by: Vladimir Zapolskiy Signed-off-by: Mark Brown --- drivers/spi/spi-sh-msiof.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index ae086aab57d5..8171eedbfc90 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -283,6 +283,7 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, } k = min_t(int, k, ARRAY_SIZE(sh_msiof_spi_div_table) - 1); + brps = min_t(int, brps, 32); scr = sh_msiof_spi_div_table[k].brdv | SCR_BRPS(brps); sh_msiof_write(p, TSCR, scr); -- cgit v1.2.3-59-g8ed1b From 49530e6411789c1b9ea3ebc58e520c19d1c3752f Mon Sep 17 00:00:00 2001 From: sxauwsk Date: Tue, 17 Apr 2018 04:01:27 +0800 Subject: spi: cadence: Add usleep_range() for cdns_spi_fill_tx_fifo() In case of xspi work in busy condition, may send bytes failed. once something wrong, spi controller did't work any more My test found this situation appear in both of read/write process. so when TX FIFO is full, add one byte delay before send data; Signed-off-by: sxauwsk Signed-off-by: Mark Brown --- drivers/spi/spi-cadence.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 5c9516ae4942..4a001634023e 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -313,6 +313,14 @@ static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi) while ((trans_cnt < CDNS_SPI_FIFO_DEPTH) && (xspi->tx_bytes > 0)) { + + /* When xspi in busy condition, bytes may send failed, + * then spi control did't work thoroughly, add one byte delay + */ + if (cdns_spi_read(xspi, CDNS_SPI_ISR) & + CDNS_SPI_IXR_TXFULL) + usleep_range(10, 20); + if (xspi->txbuf) cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++); else -- cgit v1.2.3-59-g8ed1b From 13b86f50eaaddaea4bdd2fe476fd12e6a0951add Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 22 Apr 2018 19:56:17 +0200 Subject: thermal: int3403_thermal: Fix NULL pointer deref on module load / probe Starting with kernel 4.17 thermal_cooling_device_register() will call the get_max_state() op during register. Since we deref priv->priv in int3403_get_max_state() this means we must set priv->priv before calling thermal_cooling_device_register(). Signed-off-by: Hans de Goede Signed-off-by: Zhang Rui --- drivers/thermal/int340x_thermal/int3403_thermal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/int340x_thermal/int3403_thermal.c b/drivers/thermal/int340x_thermal/int3403_thermal.c index 8a7f24dd9315..0c19fcd56a0d 100644 --- a/drivers/thermal/int340x_thermal/int3403_thermal.c +++ b/drivers/thermal/int340x_thermal/int3403_thermal.c @@ -194,6 +194,7 @@ static int int3403_cdev_add(struct int3403_priv *priv) return -EFAULT; } + priv->priv = obj; obj->max_state = p->package.count - 1; obj->cdev = thermal_cooling_device_register(acpi_device_bid(priv->adev), @@ -201,8 +202,6 @@ static int int3403_cdev_add(struct int3403_priv *priv) if (IS_ERR(obj->cdev)) result = PTR_ERR(obj->cdev); - priv->priv = obj; - kfree(buf.pointer); /* TODO: add ACPI notification support */ -- cgit v1.2.3-59-g8ed1b From efc4a13724b852ddaa3358402a8dec024ffbcb17 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 19 Apr 2018 19:53:32 +0300 Subject: spi: pxa2xx: Allow 64-bit DMA Currently the 32-bit device address only is supported for DMA. However, starting from Intel Sunrisepoint PCH the DMA address of the device FIFO can be 64-bit. Change the respective variable to be compatible with DMA engine expectations, i.e. to phys_addr_t. Fixes: 34cadd9c1bcb ("spi: pxa2xx: Add support for Intel Sunrisepoint") Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-pxa2xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h index 513ec6c6e25b..0ae7defd3492 100644 --- a/drivers/spi/spi-pxa2xx.h +++ b/drivers/spi/spi-pxa2xx.h @@ -38,7 +38,7 @@ struct driver_data { /* SSP register addresses */ void __iomem *ioaddr; - u32 ssdr_physical; + phys_addr_t ssdr_physical; /* SSP masks*/ u32 dma_cr1; -- cgit v1.2.3-59-g8ed1b From d66a7355717ec903d455277a550d930ba13df4a8 Mon Sep 17 00:00:00 2001 From: Halil Pasic Date: Tue, 24 Apr 2018 13:26:56 +0200 Subject: vfio: ccw: fix cleanup if cp_prefetch fails If the translation of a channel program fails, we may end up attempting to clean up (free, unpin) stuff that never got translated (and allocated, pinned) in the first place. By adjusting the lengths of the chains accordingly (so the element that failed, and all subsequent elements are excluded) cleanup activities based on false assumptions can be avoided. Let's make sure cp_free works properly after cp_prefetch returns with an error by setting ch_len of a ccw chain to the number of the translated CCWs on that chain. Cc: stable@vger.kernel.org #v4.12+ Acked-by: Pierre Morel Reviewed-by: Dong Jia Shi Signed-off-by: Halil Pasic Signed-off-by: Dong Jia Shi Message-Id: <20180423110113.59385-2-bjsdjshi@linux.vnet.ibm.com> [CH: fixed typos] Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/vfio_ccw_cp.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c index 2c7550797ec2..dce92b2a895d 100644 --- a/drivers/s390/cio/vfio_ccw_cp.c +++ b/drivers/s390/cio/vfio_ccw_cp.c @@ -715,6 +715,10 @@ void cp_free(struct channel_program *cp) * and stores the result to ccwchain list. @cp must have been * initialized by a previous call with cp_init(). Otherwise, undefined * behavior occurs. + * For each chain composing the channel program: + * - On entry ch_len holds the count of CCWs to be translated. + * - On exit ch_len is adjusted to the count of successfully translated CCWs. + * This allows cp_free to find in ch_len the count of CCWs to free in a chain. * * The S/390 CCW Translation APIS (prefixed by 'cp_') are introduced * as helpers to do ccw chain translation inside the kernel. Basically @@ -749,11 +753,18 @@ int cp_prefetch(struct channel_program *cp) for (idx = 0; idx < len; idx++) { ret = ccwchain_fetch_one(chain, idx, cp); if (ret) - return ret; + goto out_err; } } return 0; +out_err: + /* Only cleanup the chain elements that were actually translated. */ + chain->ch_len = idx; + list_for_each_entry_continue(chain, &cp->ccwchain_list, next) { + chain->ch_len = 0; + } + return ret; } /** -- cgit v1.2.3-59-g8ed1b From e6914365fd280fce303a89b8a8d4529af5a2e0f9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 12 Apr 2018 11:16:10 +0900 Subject: reset: uniphier: fix USB clock line for LD20 For LD20, the bit 5 of the offset 0x200c turned out to be a USB3 reset. The hardware document says it is the GIO reset despite LD20 has no GIO bus, confusingly. Also, fix confusing comments for PXs3. Signed-off-by: Masahiro Yamada Signed-off-by: Philipp Zabel --- drivers/reset/reset-uniphier.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c index 360e06b20c53..ac18f2f27881 100644 --- a/drivers/reset/reset-uniphier.c +++ b/drivers/reset/reset-uniphier.c @@ -110,7 +110,7 @@ static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = { UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */ UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC) */ - UNIPHIER_RESETX(12, 0x200c, 5), /* GIO (PCIe, USB3) */ + UNIPHIER_RESETX(14, 0x200c, 5), /* USB30 */ UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */ UNIPHIER_RESETX(17, 0x200c, 13), /* USB30-PHY1 */ UNIPHIER_RESETX(18, 0x200c, 14), /* USB30-PHY2 */ @@ -127,8 +127,8 @@ static const struct uniphier_reset_data uniphier_pxs3_sys_reset_data[] = { UNIPHIER_RESETX(6, 0x200c, 9), /* Ether0 */ UNIPHIER_RESETX(7, 0x200c, 10), /* Ether1 */ UNIPHIER_RESETX(8, 0x200c, 12), /* STDMAC */ - UNIPHIER_RESETX(12, 0x200c, 4), /* USB30 link (GIO0) */ - UNIPHIER_RESETX(13, 0x200c, 5), /* USB31 link (GIO1) */ + UNIPHIER_RESETX(12, 0x200c, 4), /* USB30 link */ + UNIPHIER_RESETX(13, 0x200c, 5), /* USB31 link */ UNIPHIER_RESETX(16, 0x200c, 16), /* USB30-PHY0 */ UNIPHIER_RESETX(17, 0x200c, 18), /* USB30-PHY1 */ UNIPHIER_RESETX(18, 0x200c, 20), /* USB30-PHY2 */ -- cgit v1.2.3-59-g8ed1b From 88fc6f73fddf64eb507b04f7b2bd01d7291db514 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 16 Apr 2018 12:11:52 +0200 Subject: thermal: exynos: Reading temperature makes sense only when TMU is turned on When thermal sensor is not yet enabled, reading temperature might return random value. This might even result in stopping system booting when such temperature is higher than the critical value. Fix this by checking if TMU has been actually enabled before reading the temperature. This change fixes booting of Exynos4210-based board with TMU enabled (for example Samsung Trats board), which was broken since v4.4 kernel release. Signed-off-by: Marek Szyprowski Fixes: 9e4249b40340 ("thermal: exynos: Fix first temperature read after registering sensor") CC: stable@vger.kernel.org # v4.6+ Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index ed805c7c5ace..986cbd01aaaa 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -185,6 +185,7 @@ * @regulator: pointer to the TMU regulator structure. * @reg_conf: pointer to structure to register with core thermal. * @ntrip: number of supported trip points. + * @enabled: current status of TMU device * @tmu_initialize: SoC specific TMU initialization method * @tmu_control: SoC specific TMU control method * @tmu_read: SoC specific TMU temperature read method @@ -205,6 +206,7 @@ struct exynos_tmu_data { struct regulator *regulator; struct thermal_zone_device *tzd; unsigned int ntrip; + bool enabled; int (*tmu_initialize)(struct platform_device *pdev); void (*tmu_control)(struct platform_device *pdev, bool on); @@ -398,6 +400,7 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on) mutex_lock(&data->lock); clk_enable(data->clk); data->tmu_control(pdev, on); + data->enabled = on; clk_disable(data->clk); mutex_unlock(&data->lock); } @@ -890,7 +893,7 @@ static int exynos_get_temp(void *p, int *temp) { struct exynos_tmu_data *data = p; - if (!data || !data->tmu_read) + if (!data || !data->tmu_read || !data->enabled) return -EINVAL; mutex_lock(&data->lock); -- cgit v1.2.3-59-g8ed1b From c8da6cdef57b459ac0fd5d9d348f8460a575ae90 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 16 Apr 2018 12:11:53 +0200 Subject: thermal: exynos: Propagate error value from tmu_read() tmu_read() in case of Exynos4210 might return error for out of bound values. Current code ignores such value, what leads to reporting critical temperature value. Add proper error code propagation to exynos_get_temp() function. Signed-off-by: Marek Szyprowski CC: stable@vger.kernel.org # v4.6+ Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 986cbd01aaaa..ac83f721db24 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -892,6 +892,7 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on) static int exynos_get_temp(void *p, int *temp) { struct exynos_tmu_data *data = p; + int value, ret = 0; if (!data || !data->tmu_read || !data->enabled) return -EINVAL; @@ -899,12 +900,16 @@ static int exynos_get_temp(void *p, int *temp) mutex_lock(&data->lock); clk_enable(data->clk); - *temp = code_to_temp(data, data->tmu_read(data)) * MCELSIUS; + value = data->tmu_read(data); + if (value < 0) + ret = value; + else + *temp = code_to_temp(data, value) * MCELSIUS; clk_disable(data->clk); mutex_unlock(&data->lock); - return 0; + return ret; } #ifdef CONFIG_THERMAL_EMULATION -- cgit v1.2.3-59-g8ed1b From 40626a1bf657eef557fcee9e1b8ef5b4f5b56dcd Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 29 Apr 2018 08:08:24 -0700 Subject: hwmon: (k10temp) Fix reading critical temperature register The HTC (Hardware Temperature Control) register has moved for recent chips. Cc: stable@vger.kernel.org # v4.16+ Tested-by: Gabriel Craciunescu Signed-off-by: Guenter Roeck --- drivers/hwmon/k10temp.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index d2cc55e21374..34b5448b00be 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -63,10 +63,12 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); #define NB_CAP_HTC 0x00000400 /* - * For F15h M60h, functionality of REG_REPORTED_TEMPERATURE - * has been moved to D0F0xBC_xD820_0CA4 [Reported Temperature - * Control] + * For F15h M60h and M70h, REG_HARDWARE_THERMAL_CONTROL + * and REG_REPORTED_TEMPERATURE have been moved to + * D0F0xBC_xD820_0C64 [Hardware Temperature Control] + * D0F0xBC_xD820_0CA4 [Reported Temperature Control] */ +#define F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET 0xd8200c64 #define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET 0xd8200ca4 /* F17h M01h Access througn SMN */ @@ -74,6 +76,7 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); struct k10temp_data { struct pci_dev *pdev; + void (*read_htcreg)(struct pci_dev *pdev, u32 *regval); void (*read_tempreg)(struct pci_dev *pdev, u32 *regval); int temp_offset; u32 temp_adjust_mask; @@ -98,6 +101,11 @@ static const struct tctl_offset tctl_offset_table[] = { { 0x17, "AMD Ryzen Threadripper 1910", 10000 }, }; +static void read_htcreg_pci(struct pci_dev *pdev, u32 *regval) +{ + pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, regval); +} + static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval) { pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval); @@ -114,6 +122,12 @@ static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn, mutex_unlock(&nb_smu_ind_mutex); } +static void read_htcreg_nb_f15(struct pci_dev *pdev, u32 *regval) +{ + amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8, + F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET, regval); +} + static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval) { amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8, @@ -160,8 +174,7 @@ static ssize_t show_temp_crit(struct device *dev, u32 regval; int value; - pci_read_config_dword(data->pdev, - REG_HARDWARE_THERMAL_CONTROL, ®val); + data->read_htcreg(data->pdev, ®val); value = ((regval >> 16) & 0x7f) * 500 + 52000; if (show_hyst) value -= ((regval >> 24) & 0xf) * 500; @@ -181,13 +194,18 @@ static umode_t k10temp_is_visible(struct kobject *kobj, struct pci_dev *pdev = data->pdev; if (index >= 2) { - u32 reg_caps, reg_htc; + u32 reg; + + if (!data->read_htcreg) + return 0; pci_read_config_dword(pdev, REG_NORTHBRIDGE_CAPABILITIES, - ®_caps); - pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, - ®_htc); - if (!(reg_caps & NB_CAP_HTC) || !(reg_htc & HTC_ENABLE)) + ®); + if (!(reg & NB_CAP_HTC)) + return 0; + + data->read_htcreg(data->pdev, ®); + if (!(reg & HTC_ENABLE)) return 0; } return attr->mode; @@ -268,11 +286,13 @@ static int k10temp_probe(struct pci_dev *pdev, if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 || boot_cpu_data.x86_model == 0x70)) { + data->read_htcreg = read_htcreg_nb_f15; data->read_tempreg = read_tempreg_nb_f15; } else if (boot_cpu_data.x86 == 0x17) { data->temp_adjust_mask = 0x80000; data->read_tempreg = read_tempreg_nb_f17; } else { + data->read_htcreg = read_htcreg_pci; data->read_tempreg = read_tempreg_pci; } -- cgit v1.2.3-59-g8ed1b From c8016fa215d2d50920a58de07da2d00f7cb982f3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 22 Apr 2018 19:57:59 +0200 Subject: i2c: core: ACPI: Improve OpRegion read errors When we get an error doing an ACPI SerialBus I2C OpRegion read log some useful details, like the client address and which register is being read. Signed-off-by: Hans de Goede Reviewed-by: Mika Westerberg Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-acpi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index a9126b3cda61..3dc43a009f5d 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -446,7 +446,8 @@ static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); if (ret < 0) - dev_err(&client->adapter->dev, "i2c read failed\n"); + dev_err(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n", + data_len, client->addr, cmd, ret); else memcpy(data, buffer, data_len); -- cgit v1.2.3-59-g8ed1b From 7781edaed63e9396fc913e0899cb197562e6f1a0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 22 Apr 2018 19:58:00 +0200 Subject: i2c: core: ACPI: Log device not acking errors at dbg loglevel Unfortunately some DSDTs issue bogus i2c reads to non existing devices resulting in -EREMOTEIO errors because the non existing device of course does not ack. This happens e.g. from the The Asus T100TA's _BIX method, the DSDT on the T100TA defines 2 resources on the I2C1 bus: Name (EHID, ResourceTemplate () { I2cSerialBusV2 (0x005B, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\\_SB.I2C1", 0x00, ResourceConsumer, , Exclusive, ) }) OperationRegion (EHOR, GenericSerialBus, Zero, 0x0100) Field (EHOR, BufferAcc, NoLock, Preserve) { Connection (EHID), Offset (0x01), AccessAs (BufferAcc, AttribBytes (0x10)), ABCD, 8 } Name (UMPC, ResourceTemplate () { I2cSerialBusV2 (0x0066, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\\_SB.I2C1", 0x00, ResourceConsumer, , Exclusive, ) }) The _BIX method does a single read (on each BIX() call) from the EHID device through the ABCD Field, only to completely ignore the result. This read always fails as there is no i2c client at address 0x5b. The _BIX method also does several reads from the UMPC device and actually uses the results of those to provide battery information. IIRC I've also seen some DSTDs which do an i2c read to detect if a device is present, also leading to false positive errors being logged. Esp. the _BIX use is problematic as the _BIX method gets called periodically to monitor battery status. This commit stops the logs from filling up with errors like these: [ 57.327858] i2c i2c-0: i2c read 16 bytes from client@0x5b starting at reg 0x1 failed, error: -121 Signed-off-by: Hans de Goede Reviewed-by: Mika Westerberg Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-acpi.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index 3dc43a009f5d..7c3b4740b94b 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -445,11 +445,17 @@ static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, msgs[1].buf = buffer; ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (ret < 0) - dev_err(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n", - data_len, client->addr, cmd, ret); - else + if (ret < 0) { + /* Getting a NACK is unfortunately normal with some DSTDs */ + if (ret == -EREMOTEIO) + dev_dbg(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n", + data_len, client->addr, cmd, ret); + else + dev_err(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n", + data_len, client->addr, cmd, ret); + } else { memcpy(data, buffer, data_len); + } kfree(buffer); return ret; -- cgit v1.2.3-59-g8ed1b From 5eb9a07a4ae1008b67d8bcd47bddb3dae97456b7 Mon Sep 17 00:00:00 2001 From: Kamal Dasu Date: Thu, 26 Apr 2018 14:48:00 -0400 Subject: spi: bcm-qspi: Avoid setting MSPI_CDRAM_PCS for spi-nor master Added fix for probing of spi-nor device non-zero chip selects. Set MSPI_CDRAM_PCS (peripheral chip select) with spi master for MSPI controller and not for MSPI/BSPI spi-nor master controller. Ensure setting of cs bit in chip select register on chip select change. Fixes: fa236a7ef24048 ("spi: bcm-qspi: Add Broadcom MSPI driver") Signed-off-by: Kamal Dasu Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-bcm-qspi.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 1596d35498c5..2946989c61a2 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -519,16 +519,19 @@ static void bcm_qspi_disable_bspi(struct bcm_qspi *qspi) static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs) { - u32 data = 0; + u32 rd = 0; + u32 wr = 0; - if (qspi->curr_cs == cs) - return; if (qspi->base[CHIP_SELECT]) { - data = bcm_qspi_read(qspi, CHIP_SELECT, 0); - data = (data & ~0xff) | (1 << cs); - bcm_qspi_write(qspi, CHIP_SELECT, 0, data); + rd = bcm_qspi_read(qspi, CHIP_SELECT, 0); + wr = (rd & ~0xff) | (1 << cs); + if (rd == wr) + return; + bcm_qspi_write(qspi, CHIP_SELECT, 0, wr); usleep_range(10, 20); } + + dev_dbg(&qspi->pdev->dev, "using cs:%d\n", cs); qspi->curr_cs = cs; } @@ -755,8 +758,13 @@ static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi) dev_dbg(&qspi->pdev->dev, "WR %04x\n", val); } mspi_cdram = MSPI_CDRAM_CONT_BIT; - mspi_cdram |= (~(1 << spi->chip_select) & - MSPI_CDRAM_PCS); + + if (has_bspi(qspi)) + mspi_cdram &= ~1; + else + mspi_cdram |= (~(1 << spi->chip_select) & + MSPI_CDRAM_PCS); + mspi_cdram |= ((tp.trans->bits_per_word <= 8) ? 0 : MSPI_CDRAM_BITSE_BIT); -- cgit v1.2.3-59-g8ed1b From 602805fb618b018b7a41fbb3f93c1992b078b1ae Mon Sep 17 00:00:00 2001 From: Kamal Dasu Date: Thu, 26 Apr 2018 14:48:01 -0400 Subject: spi: bcm-qspi: Always read and set BSPI_MAST_N_BOOT_CTRL Always confirm the BSPI_MAST_N_BOOT_CTRL bit when enabling or disabling BSPI transfers. Fixes: 4e3b2d236fe00 ("spi: bcm-qspi: Add BSPI spi-nor flash controller driver") Signed-off-by: Kamal Dasu Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-bcm-qspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 2946989c61a2..6573152ce893 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -490,7 +490,7 @@ static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi, static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi) { - if (!has_bspi(qspi) || (qspi->bspi_enabled)) + if (!has_bspi(qspi)) return; qspi->bspi_enabled = 1; @@ -505,7 +505,7 @@ static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi) static void bcm_qspi_disable_bspi(struct bcm_qspi *qspi) { - if (!has_bspi(qspi) || (!qspi->bspi_enabled)) + if (!has_bspi(qspi)) return; qspi->bspi_enabled = 0; -- cgit v1.2.3-59-g8ed1b From f4b024271ae3e9786e5d6f1c05b01b57a74e1d6d Mon Sep 17 00:00:00 2001 From: Jim Gill Date: Fri, 20 Apr 2018 19:04:47 -0700 Subject: scsi: vmw-pvscsi: return DID_BUS_BUSY for adapter-initated aborts The vmw_pvscsi driver returns DID_ABORT for commands aborted internally by the adapter, leading to the filesystem going read-only. Change the result to DID_BUS_BUSY, causing the kernel to retry the command. Signed-off-by: Jim Gill Signed-off-by: Martin K. Petersen --- drivers/scsi/vmw_pvscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index c374e3b5c678..777e5f1e52d1 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -609,7 +609,7 @@ static void pvscsi_complete_request(struct pvscsi_adapter *adapter, break; case BTSTAT_ABORTQUEUE: - cmd->result = (DID_ABORT << 16); + cmd->result = (DID_BUS_BUSY << 16); break; case BTSTAT_SCSIPARITY: -- cgit v1.2.3-59-g8ed1b From 7d3af7d96af7b9f51e1ef67b6f4725f545737da2 Mon Sep 17 00:00:00 2001 From: Dave Carroll Date: Wed, 25 Apr 2018 10:24:20 -0600 Subject: scsi: aacraid: Correct hba_send to include iu_type commit b60710ec7d7a ("scsi: aacraid: enable sending of TMFs from aac_hba_send()") allows aac_hba_send() to send scsi commands, and TMF requests, but the existing code only updates the iu_type for scsi commands. For TMF requests we are sending an unknown iu_type to firmware, which causes a fault. Include iu_type prior to determining the validity of the command Reported-by: Noah Misner Fixes: b60710ec7d7ab ("aacraid: enable sending of TMFs from aac_hba_send()") Fixes: 423400e64d377 ("aacraid: Include HBA direct interface") Tested-by: Noah Misner cc: stable@vger.kernel.org Signed-off-by: Dave Carroll Reviewed-by: Raghava Aditya Renukunta Reviewed-by: Brian King Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/commsup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 0156c9623c35..d62ddd63f4fe 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -724,6 +724,8 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback, int wait; unsigned long flags = 0; unsigned long mflags = 0; + struct aac_hba_cmd_req *hbacmd = (struct aac_hba_cmd_req *) + fibptr->hw_fib_va; fibptr->flags = (FIB_CONTEXT_FLAG | FIB_CONTEXT_FLAG_NATIVE_HBA); if (callback) { @@ -734,11 +736,9 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback, wait = 1; - if (command == HBA_IU_TYPE_SCSI_CMD_REQ) { - struct aac_hba_cmd_req *hbacmd = - (struct aac_hba_cmd_req *)fibptr->hw_fib_va; + hbacmd->iu_type = command; - hbacmd->iu_type = command; + if (command == HBA_IU_TYPE_SCSI_CMD_REQ) { /* bit1 of request_id must be 0 */ hbacmd->request_id = cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1); -- cgit v1.2.3-59-g8ed1b From bc519d9574618e47a0c788000fb78da95e18d953 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 3 May 2018 13:09:44 -0500 Subject: spi: bcm2835aux: ensure interrupts are enabled for shared handler The BCM2835 AUX SPI has a shared interrupt line (with AUX UART). Downstream fixes this with an AUX irqchip to demux the IRQ sources and a DT change which breaks compatibility with older kernels. The AUX irqchip was already rejected for upstream[1] and the DT change would break working systems if the DTB is updated to a newer one. The latter issue was brought to my attention by Alex Graf. The root cause however is a bug in the shared handler. Shared handlers must check that interrupts are actually enabled before servicing the interrupt. Add a check that the TXEMPTY or IDLE interrupts are enabled. [1] https://patchwork.kernel.org/patch/9781221/ Cc: Alexander Graf Cc: Marc Zyngier Cc: Mark Brown Cc: Eric Anholt Cc: Stefan Wahren Cc: Florian Fainelli Cc: Ray Jui Cc: Scott Branden Cc: bcm-kernel-feedback-list@broadcom.com Cc: linux-spi@vger.kernel.org Cc: linux-rpi-kernel@lists.infradead.org Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Rob Herring Reviewed-by: Eric Anholt Signed-off-by: Mark Brown --- drivers/spi/spi-bcm2835aux.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c index 1431cb98fe40..3094d818cf06 100644 --- a/drivers/spi/spi-bcm2835aux.c +++ b/drivers/spi/spi-bcm2835aux.c @@ -184,6 +184,11 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) struct bcm2835aux_spi *bs = spi_master_get_devdata(master); irqreturn_t ret = IRQ_NONE; + /* IRQ may be shared, so return if our interrupts are disabled */ + if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) & + (BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE))) + return ret; + /* check if we have data to read */ while (bs->rx_len && (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & -- cgit v1.2.3-59-g8ed1b From bb765d1c331f62b59049d35607ed2e365802bef9 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Wed, 4 Apr 2018 21:03:21 +0200 Subject: tee: shm: fix use-after-free via temporarily dropped reference Bump the file's refcount before moving the reference into the fd table, not afterwards. The old code could drop the file's refcount to zero for a short moment before calling get_file() via get_dma_buf(). This code can only be triggered on ARM systems that use Linaro's OP-TEE. Fixes: 967c9cca2cc5 ("tee: generic TEE subsystem") Signed-off-by: Jann Horn Signed-off-by: Jens Wiklander --- drivers/tee/tee_shm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 556960a1bab3..07d3be6f0780 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -360,9 +360,10 @@ int tee_shm_get_fd(struct tee_shm *shm) if (!(shm->flags & TEE_SHM_DMA_BUF)) return -EINVAL; + get_dma_buf(shm->dmabuf); fd = dma_buf_fd(shm->dmabuf, O_CLOEXEC); - if (fd >= 0) - get_dma_buf(shm->dmabuf); + if (fd < 0) + dma_buf_put(shm->dmabuf); return fd; } -- cgit v1.2.3-59-g8ed1b From ab9d3db5b320a052452b9cd035599ee3c84bbee9 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Sun, 29 Apr 2018 14:22:29 +0200 Subject: tee: check shm references are consistent in offset/size This change prevents userland from referencing TEE shared memory outside the area initially allocated by its owner. Prior this change an application could not reference or access memory it did not own but it could reference memory not explicitly allocated by owner but still allocated to the owner due to the memory allocation granule. Reported-by: Alexandre Jutras Signed-off-by: Etienne Carriere Signed-off-by: Jens Wiklander --- drivers/tee/tee_core.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 0124a91c8d71..dd46b758852a 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -238,6 +238,17 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params, if (IS_ERR(shm)) return PTR_ERR(shm); + /* + * Ensure offset + size does not overflow offset + * and does not overflow the size of the referred + * shared memory object. + */ + if ((ip.a + ip.b) < ip.a || + (ip.a + ip.b) > shm->size) { + tee_shm_put(shm); + return -EINVAL; + } + params[n].u.memref.shm_offs = ip.a; params[n].u.memref.size = ip.b; params[n].u.memref.shm = shm; -- cgit v1.2.3-59-g8ed1b From 12d9f07022dcde261ad16e9a11f45096dc68b03c Mon Sep 17 00:00:00 2001 From: Jianchao Wang Date: Fri, 4 May 2018 16:01:57 +0800 Subject: nvme: fix use-after-free in nvme_free_ns_head Currently only nvme_ctrl will take a reference counter of nvme_subsystem, nvme_ns_head also needs it. Otherwise nvme_free_ns_head will access the nvme_subsystem.ns_ida which has been freed by __nvme_release_subsystem after all the reference of nvme_subsystem have been released by nvme_free_ctrl. This could cause memory corruption. BUG: KASAN: use-after-free in radix_tree_next_chunk+0x9f/0x4b0 Read of size 8 at addr ffff88036494d2e8 by task fio/1815 CPU: 1 PID: 1815 Comm: fio Kdump: loaded Tainted: G W 4.17.0-rc1+ #18 Hardware name: LENOVO 10MLS0E339/3106, BIOS M1AKT22A 06/27/2017 Call Trace: dump_stack+0x91/0xeb print_address_description+0x6b/0x290 kasan_report+0x261/0x360 radix_tree_next_chunk+0x9f/0x4b0 ida_remove+0x8b/0x180 ida_simple_remove+0x26/0x40 nvme_free_ns_head+0x58/0xc0 __blkdev_put+0x30a/0x3a0 blkdev_close+0x44/0x50 __fput+0x184/0x380 task_work_run+0xaf/0xe0 do_exit+0x501/0x1440 do_group_exit+0x89/0x140 __x64_sys_exit_group+0x28/0x30 do_syscall_64+0x72/0x230 Signed-off-by: Jianchao Wang Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/host/core.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index a3771c5729f5..2cbc378bc0d6 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -99,6 +99,7 @@ static struct class *nvme_subsys_class; static void nvme_ns_remove(struct nvme_ns *ns); static int nvme_revalidate_disk(struct gendisk *disk); +static void nvme_put_subsystem(struct nvme_subsystem *subsys); int nvme_reset_ctrl(struct nvme_ctrl *ctrl) { @@ -350,6 +351,7 @@ static void nvme_free_ns_head(struct kref *ref) ida_simple_remove(&head->subsys->ns_ida, head->instance); list_del_init(&head->entry); cleanup_srcu_struct(&head->srcu); + nvme_put_subsystem(head->subsys); kfree(head); } @@ -2861,6 +2863,9 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl, goto out_cleanup_srcu; list_add_tail(&head->entry, &ctrl->subsys->nsheads); + + kref_get(&ctrl->subsys->ref); + return head; out_cleanup_srcu: cleanup_srcu_struct(&head->srcu); -- cgit v1.2.3-59-g8ed1b From 31c6085562a03124d3f6a5c43dd9888ac44495a5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 27 Apr 2018 17:06:49 +0300 Subject: firmware: arm_scmi: Use after free in scmi_create_protocol_device() We need to return here instead of setting up the freed sdev device as a transport. Fixes: 907b6d14911d ("firmware: arm_scmi: add per-protocol channels support using idr objects") Signed-off-by: Dan Carpenter Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/driver.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 14b147135a0c..2455be8cbc4f 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -778,6 +778,7 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info, if (scmi_mbox_chan_setup(info, &sdev->dev, prot_id)) { dev_err(&sdev->dev, "failed to setup transport\n"); scmi_device_destroy(sdev); + return; } /* setup handle now as the transport is ready */ -- cgit v1.2.3-59-g8ed1b From 76aa3de7095f15af7300012cb29ea8ab93eec348 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 7 May 2018 12:08:37 +0200 Subject: eeprom: at24: fix retrieving the at24_chip_data structure Commit feb2f19b1e8f ("eeprom: at24: move platform data processing into a separate routine") introduced a bug where we incorrectly retireve the at24_chip_data structure. Remove the unnecessary ampersand operator. Fixes: feb2f19b1e8f ("eeprom: at24: move platform data processing into a separate routine") Reported-by: Vadim Pasternak Signed-off-by: Bartosz Golaszewski --- drivers/misc/eeprom/at24.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 0c125f207aea..33053b0d1fdf 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -518,7 +518,7 @@ static int at24_get_pdata(struct device *dev, struct at24_platform_data *pdata) if (of_node && of_match_device(at24_of_match, dev)) cdata = of_device_get_match_data(dev); else if (id) - cdata = (void *)&id->driver_data; + cdata = (void *)id->driver_data; else cdata = acpi_device_get_match_data(dev); -- cgit v1.2.3-59-g8ed1b From 26aeb9daa02cd37178321cf915efd3d5eb8b0511 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 8 May 2018 19:42:40 -0700 Subject: nfp: bpf: allow zero-length capabilities Some BPF capabilities carry no value, they simply indicate feature is present. Our capability parsing loop will exit early if last capability is zero-length because it's looking for more than 8 bytes of data (8B is our TLV header length). Allow the last capability to be zero-length. This bug would lead to driver failing to probe with the following error if the last capability FW advertises is zero-length: nfp: BPF capabilities left after parsing, parsed:92 total length:100 nfp: invalid BPF capabilities at offset:92 Note the "parsed" and "length" values are 8 apart. No shipping FW runs into this issue, but we can't guarantee that will remain the case. Fixes: 77a844ee650c ("nfp: bpf: prepare for parsing BPF FW capabilities") Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet Signed-off-by: Daniel Borkmann --- drivers/net/ethernet/netronome/nfp/bpf/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c index 1dc424685f4e..35fb31f682af 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c @@ -335,7 +335,7 @@ static int nfp_bpf_parse_capabilities(struct nfp_app *app) return PTR_ERR(mem) == -ENOENT ? 0 : PTR_ERR(mem); start = mem; - while (mem - start + 8 < nfp_cpp_area_size(area)) { + while (mem - start + 8 <= nfp_cpp_area_size(area)) { u8 __iomem *value; u32 type, length; -- cgit v1.2.3-59-g8ed1b From 06cb616b1bca7080824acfedb3d4c898e7a64836 Mon Sep 17 00:00:00 2001 From: Alexander Monakov Date: Sat, 28 Apr 2018 16:56:06 +0300 Subject: i2c: designware: fix poll-after-enable regression Not all revisions of DW I2C controller implement the enable status register. On platforms where that's the case (e.g. BG2CD and SPEAr ARM SoCs), waiting for enable will time out as reading the unimplemented register yields zero. It was observed that reading the IC_ENABLE_STATUS register once suffices to avoid getting it stuck on Bay Trail hardware, so replace polling with one dummy read of the register. Fixes: fba4adbbf670 ("i2c: designware: must wait for enable") Signed-off-by: Alexander Monakov Tested-by: Ben Gardner Acked-by: Jarkko Nikula Signed-off-by: Wolfram Sang Cc: stable@kernel.org --- drivers/i2c/busses/i2c-designware-master.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index fd36c39ddf4e..0cdba29ae0a9 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -209,7 +209,10 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) i2c_dw_disable_int(dev); /* Enable the adapter */ - __i2c_dw_enable_and_wait(dev, true); + __i2c_dw_enable(dev, true); + + /* Dummy read to avoid the register getting stuck on Bay Trail */ + dw_readl(dev, DW_IC_ENABLE_STATUS); /* Clear and enable interrupts */ dw_readl(dev, DW_IC_CLR_INTR); -- cgit v1.2.3-59-g8ed1b From 7f6df440b8623c441c42d070bf592e2d2c1fa9bb Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 11 May 2018 07:15:42 +0300 Subject: drm: Match sysfs name in link removal to link creation This patch matches the sysfs name used in the unlinking with the linking function. Otherwise, remove_compat_control_link() fails to remove sysfs created by create_compat_control_link() in drm_dev_register(). Fixes: 6449b088dd51 ("drm: Add fake controlD* symlinks for backwards compat") Cc: Dave Airlie Cc: Alex Deucher Cc: Emil Velikov Cc: David Herrmann Cc: Greg Kroah-Hartman Cc: Daniel Vetter Cc: Gustavo Padovan Cc: Maarten Lankhorst Cc: Sean Paul Cc: David Airlie Cc: dri-devel@lists.freedesktop.org Cc: # v4.10+ Signed-off-by: Haneen Mohammed [seanpaul added Fixes and Cc tags] Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20180511041542.GA4253@haneen-vb --- drivers/gpu/drm/drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index a1b9338736e3..c2c21d839727 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -716,7 +716,7 @@ static void remove_compat_control_link(struct drm_device *dev) if (!minor) return; - name = kasprintf(GFP_KERNEL, "controlD%d", minor->index); + name = kasprintf(GFP_KERNEL, "controlD%d", minor->index + 64); if (!name) return; -- cgit v1.2.3-59-g8ed1b From 4e50d9ebaeaa3c6761d2b513ef7039510c8cf213 Mon Sep 17 00:00:00 2001 From: Charles Machalow Date: Thu, 10 May 2018 16:01:38 -0700 Subject: nvme: Fix sync controller reset return If a controller reset is requested while the device has no namespaces, we were incorrectly returning ENETRESET. This patch adds the check for ADMIN_ONLY controller state to indicate a successful reset. Fixes: 8000d1fdb0 ("nvme-rdma: fix sysfs invoked reset_ctrl error flow ") Cc: Signed-off-by: Charles Machalow [changelog] Signed-off-by: Keith Busch --- drivers/nvme/host/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 2cbc378bc0d6..99b857e5a7a9 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -118,7 +118,8 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl) ret = nvme_reset_ctrl(ctrl); if (!ret) { flush_work(&ctrl->reset_work); - if (ctrl->state != NVME_CTRL_LIVE) + if (ctrl->state != NVME_CTRL_LIVE && + ctrl->state != NVME_CTRL_ADMIN_ONLY) ret = -ENETRESET; } -- cgit v1.2.3-59-g8ed1b From 9abd68ef454c824bfd18629033367b4382b5f390 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 8 May 2018 10:25:15 -0600 Subject: nvme: add quirk to force medium priority for SQ creation Some P3100 drives have a bug where they think WRRU (weighted round robin) is always enabled, even though the host doesn't set it. Since they think it's enabled, they also look at the submission queue creation priority. We used to set that to MEDIUM by default, but that was removed in commit 81c1cd98351b. This causes various issues on that drive. Add a quirk to still set MEDIUM priority for that controller. Fixes: 81c1cd98351b ("nvme/pci: Don't set reserved SQ create flags") Cc: stable@vger.kernel.org Signed-off-by: Jens Axboe Signed-off-by: Keith Busch --- drivers/nvme/host/nvme.h | 5 +++++ drivers/nvme/host/pci.c | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 7ded7a51c430..17d2f7cf3fed 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -84,6 +84,11 @@ enum nvme_quirks { * Supports the LighNVM command set if indicated in vs[1]. */ NVME_QUIRK_LIGHTNVM = (1 << 6), + + /* + * Set MEDIUM priority on SQ creation + */ + NVME_QUIRK_MEDIUM_PRIO_SQ = (1 << 7), }; /* diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index fbc71fac6f1e..17a0190bd88f 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1093,9 +1093,18 @@ static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid, static int adapter_alloc_sq(struct nvme_dev *dev, u16 qid, struct nvme_queue *nvmeq) { + struct nvme_ctrl *ctrl = &dev->ctrl; struct nvme_command c; int flags = NVME_QUEUE_PHYS_CONTIG; + /* + * Some drives have a bug that auto-enables WRRU if MEDIUM isn't + * set. Since URGENT priority is zeroes, it makes all queues + * URGENT. + */ + if (ctrl->quirks & NVME_QUIRK_MEDIUM_PRIO_SQ) + flags |= NVME_SQ_PRIO_MEDIUM; + /* * Note: we (ab)use the fact that the prp fields survive if no data * is attached to the request. @@ -2701,7 +2710,8 @@ static const struct pci_device_id nvme_id_table[] = { .driver_data = NVME_QUIRK_STRIPE_SIZE | NVME_QUIRK_DEALLOCATE_ZEROES, }, { PCI_VDEVICE(INTEL, 0xf1a5), /* Intel 600P/P3100 */ - .driver_data = NVME_QUIRK_NO_DEEPEST_PS }, + .driver_data = NVME_QUIRK_NO_DEEPEST_PS | + NVME_QUIRK_MEDIUM_PRIO_SQ }, { PCI_VDEVICE(INTEL, 0x5845), /* Qemu emulated controller */ .driver_data = NVME_QUIRK_IDENTIFY_CNS, }, { PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */ -- cgit v1.2.3-59-g8ed1b From 3b031622f598481970400519bd5abc2a16708282 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 4 May 2018 13:01:33 -0700 Subject: hwmon: (k10temp) Use API function to access System Management Network The SMN (System Management Network) on Family 17h AMD CPUs is also accessed from other drivers, specifically EDAC. Accessing it directly is racy. On top of that, accessing the SMN through root bridge 00:00 is wrong on multi-die CPUs and may result in reading the temperature from the wrong die. Use available API functions to fix the problem. For this to work, add dependency on AMD_NB. Also change the Raven Ridge PCI device ID to point to Data Fabric Function 3, since this ID is used by the API functions to find the CPU node. Cc: stable@vger.kernel.org # v4.16+ Tested-by: Gabriel Craciunescu Signed-off-by: Guenter Roeck --- drivers/hwmon/Kconfig | 2 +- drivers/hwmon/k10temp.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index f249a4428458..6ec307c93ece 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -272,7 +272,7 @@ config SENSORS_K8TEMP config SENSORS_K10TEMP tristate "AMD Family 10h+ temperature sensor" - depends on X86 && PCI + depends on X86 && PCI && AMD_NB help If you say yes here you get support for the temperature sensor(s) inside your CPU. Supported are later revisions of diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 34b5448b00be..3b73dee6fdc6 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor"); @@ -40,8 +41,8 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); #define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463 #endif -#ifndef PCI_DEVICE_ID_AMD_17H_RR_NB -#define PCI_DEVICE_ID_AMD_17H_RR_NB 0x15d0 +#ifndef PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 +#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb #endif /* CPUID function 0x80000001, ebx */ @@ -136,8 +137,8 @@ static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval) static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval) { - amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0x60, - F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval); + amd_smn_read(amd_pci_dev_to_node_id(pdev), + F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval); } static ssize_t temp1_input_show(struct device *dev, @@ -322,7 +323,7 @@ static const struct pci_device_id k10temp_id_table[] = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_RR_NB) }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) }, {} }; MODULE_DEVICE_TABLE(pci, k10temp_id_table); -- cgit v1.2.3-59-g8ed1b From 55c82617c3e82210b7471e9334e8fc5df6a9961f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 12 May 2018 12:16:50 +0200 Subject: 3c59x: convert to generic DMA API This driver supports EISA devices in addition to PCI devices, and relied on the legacy behavior of the pci_dma* shims to pass on a NULL pointer to the DMA API, and the DMA API being able to handle that. When the NULL forwarding broke the EISA support got broken. Fix this by converting to the DMA API instead of the legacy PCI shims. Fixes: 4167b2ad ("PCI: Remove NULL device handling from PCI DMA API") Reported-by: tedheadster Tested-by: tedheadster Signed-off-by: Christoph Hellwig Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c59x.c | 104 +++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 36c8950dbd2d..176861bd2252 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -1212,9 +1212,9 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, vp->mii.reg_num_mask = 0x1f; /* Makes sure rings are at least 16 byte aligned. */ - vp->rx_ring = pci_alloc_consistent(pdev, sizeof(struct boom_rx_desc) * RX_RING_SIZE + vp->rx_ring = dma_alloc_coherent(gendev, sizeof(struct boom_rx_desc) * RX_RING_SIZE + sizeof(struct boom_tx_desc) * TX_RING_SIZE, - &vp->rx_ring_dma); + &vp->rx_ring_dma, GFP_KERNEL); retval = -ENOMEM; if (!vp->rx_ring) goto free_device; @@ -1476,11 +1476,10 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, return 0; free_ring: - pci_free_consistent(pdev, - sizeof(struct boom_rx_desc) * RX_RING_SIZE - + sizeof(struct boom_tx_desc) * TX_RING_SIZE, - vp->rx_ring, - vp->rx_ring_dma); + dma_free_coherent(&pdev->dev, + sizeof(struct boom_rx_desc) * RX_RING_SIZE + + sizeof(struct boom_tx_desc) * TX_RING_SIZE, + vp->rx_ring, vp->rx_ring_dma); free_device: free_netdev(dev); pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval); @@ -1751,9 +1750,9 @@ vortex_open(struct net_device *dev) break; /* Bad news! */ skb_reserve(skb, NET_IP_ALIGN); /* Align IP on 16 byte boundaries */ - dma = pci_map_single(VORTEX_PCI(vp), skb->data, - PKT_BUF_SZ, PCI_DMA_FROMDEVICE); - if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma)) + dma = dma_map_single(vp->gendev, skb->data, + PKT_BUF_SZ, DMA_FROM_DEVICE); + if (dma_mapping_error(vp->gendev, dma)) break; vp->rx_ring[i].addr = cpu_to_le32(dma); } @@ -2067,9 +2066,9 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) if (vp->bus_master) { /* Set the bus-master controller to transfer the packet. */ int len = (skb->len + 3) & ~3; - vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, - PCI_DMA_TODEVICE); - if (dma_mapping_error(&VORTEX_PCI(vp)->dev, vp->tx_skb_dma)) { + vp->tx_skb_dma = dma_map_single(vp->gendev, skb->data, len, + DMA_TO_DEVICE); + if (dma_mapping_error(vp->gendev, vp->tx_skb_dma)) { dev_kfree_skb_any(skb); dev->stats.tx_dropped++; return NETDEV_TX_OK; @@ -2168,9 +2167,9 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded | AddTCPChksum | AddUDPChksum); if (!skb_shinfo(skb)->nr_frags) { - dma_addr = pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, - PCI_DMA_TODEVICE); - if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr)) + dma_addr = dma_map_single(vp->gendev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(vp->gendev, dma_addr)) goto out_dma_err; vp->tx_ring[entry].frag[0].addr = cpu_to_le32(dma_addr); @@ -2178,9 +2177,9 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) } else { int i; - dma_addr = pci_map_single(VORTEX_PCI(vp), skb->data, - skb_headlen(skb), PCI_DMA_TODEVICE); - if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr)) + dma_addr = dma_map_single(vp->gendev, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + if (dma_mapping_error(vp->gendev, dma_addr)) goto out_dma_err; vp->tx_ring[entry].frag[0].addr = cpu_to_le32(dma_addr); @@ -2189,21 +2188,21 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - dma_addr = skb_frag_dma_map(&VORTEX_PCI(vp)->dev, frag, + dma_addr = skb_frag_dma_map(vp->gendev, frag, 0, frag->size, DMA_TO_DEVICE); - if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr)) { + if (dma_mapping_error(vp->gendev, dma_addr)) { for(i = i-1; i >= 0; i--) - dma_unmap_page(&VORTEX_PCI(vp)->dev, + dma_unmap_page(vp->gendev, le32_to_cpu(vp->tx_ring[entry].frag[i+1].addr), le32_to_cpu(vp->tx_ring[entry].frag[i+1].length), DMA_TO_DEVICE); - pci_unmap_single(VORTEX_PCI(vp), + dma_unmap_single(vp->gendev, le32_to_cpu(vp->tx_ring[entry].frag[0].addr), le32_to_cpu(vp->tx_ring[entry].frag[0].length), - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); goto out_dma_err; } @@ -2218,8 +2217,8 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) } } #else - dma_addr = pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE); - if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr)) + dma_addr = dma_map_single(vp->gendev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(vp->gendev, dma_addr)) goto out_dma_err; vp->tx_ring[entry].addr = cpu_to_le32(dma_addr); vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG); @@ -2254,7 +2253,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) out: return NETDEV_TX_OK; out_dma_err: - dev_err(&VORTEX_PCI(vp)->dev, "Error mapping dma buffer\n"); + dev_err(vp->gendev, "Error mapping dma buffer\n"); goto out; } @@ -2322,7 +2321,7 @@ vortex_interrupt(int irq, void *dev_id) if (status & DMADone) { if (ioread16(ioaddr + Wn7_MasterStatus) & 0x1000) { iowrite16(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */ - pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE); + dma_unmap_single(vp->gendev, vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, DMA_TO_DEVICE); pkts_compl++; bytes_compl += vp->tx_skb->len; dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */ @@ -2459,19 +2458,19 @@ boomerang_interrupt(int irq, void *dev_id) struct sk_buff *skb = vp->tx_skbuff[entry]; #if DO_ZEROCOPY int i; - pci_unmap_single(VORTEX_PCI(vp), + dma_unmap_single(vp->gendev, le32_to_cpu(vp->tx_ring[entry].frag[0].addr), le32_to_cpu(vp->tx_ring[entry].frag[0].length)&0xFFF, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); for (i=1; i<=skb_shinfo(skb)->nr_frags; i++) - pci_unmap_page(VORTEX_PCI(vp), + dma_unmap_page(vp->gendev, le32_to_cpu(vp->tx_ring[entry].frag[i].addr), le32_to_cpu(vp->tx_ring[entry].frag[i].length)&0xFFF, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); #else - pci_unmap_single(VORTEX_PCI(vp), - le32_to_cpu(vp->tx_ring[entry].addr), skb->len, PCI_DMA_TODEVICE); + dma_unmap_single(vp->gendev, + le32_to_cpu(vp->tx_ring[entry].addr), skb->len, DMA_TO_DEVICE); #endif pkts_compl++; bytes_compl += skb->len; @@ -2561,14 +2560,14 @@ static int vortex_rx(struct net_device *dev) /* 'skb_put()' points to the start of sk_buff data area. */ if (vp->bus_master && ! (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)) { - dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len), - pkt_len, PCI_DMA_FROMDEVICE); + dma_addr_t dma = dma_map_single(vp->gendev, skb_put(skb, pkt_len), + pkt_len, DMA_FROM_DEVICE); iowrite32(dma, ioaddr + Wn7_MasterAddr); iowrite16((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen); iowrite16(StartDMAUp, ioaddr + EL3_CMD); while (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000) ; - pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE); + dma_unmap_single(vp->gendev, dma, pkt_len, DMA_FROM_DEVICE); } else { ioread32_rep(ioaddr + RX_FIFO, skb_put(skb, pkt_len), @@ -2635,11 +2634,11 @@ boomerang_rx(struct net_device *dev) if (pkt_len < rx_copybreak && (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + dma_sync_single_for_cpu(vp->gendev, dma, PKT_BUF_SZ, DMA_FROM_DEVICE); /* 'skb_put()' points to the start of sk_buff data area. */ skb_put_data(skb, vp->rx_skbuff[entry]->data, pkt_len); - pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + dma_sync_single_for_device(vp->gendev, dma, PKT_BUF_SZ, DMA_FROM_DEVICE); vp->rx_copy++; } else { /* Pre-allocate the replacement skb. If it or its @@ -2651,9 +2650,9 @@ boomerang_rx(struct net_device *dev) dev->stats.rx_dropped++; goto clear_complete; } - newdma = pci_map_single(VORTEX_PCI(vp), newskb->data, - PKT_BUF_SZ, PCI_DMA_FROMDEVICE); - if (dma_mapping_error(&VORTEX_PCI(vp)->dev, newdma)) { + newdma = dma_map_single(vp->gendev, newskb->data, + PKT_BUF_SZ, DMA_FROM_DEVICE); + if (dma_mapping_error(vp->gendev, newdma)) { dev->stats.rx_dropped++; consume_skb(newskb); goto clear_complete; @@ -2664,7 +2663,7 @@ boomerang_rx(struct net_device *dev) vp->rx_skbuff[entry] = newskb; vp->rx_ring[entry].addr = cpu_to_le32(newdma); skb_put(skb, pkt_len); - pci_unmap_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + dma_unmap_single(vp->gendev, dma, PKT_BUF_SZ, DMA_FROM_DEVICE); vp->rx_nocopy++; } skb->protocol = eth_type_trans(skb, dev); @@ -2761,8 +2760,8 @@ vortex_close(struct net_device *dev) if (vp->full_bus_master_rx) { /* Free Boomerang bus master Rx buffers. */ for (i = 0; i < RX_RING_SIZE; i++) if (vp->rx_skbuff[i]) { - pci_unmap_single( VORTEX_PCI(vp), le32_to_cpu(vp->rx_ring[i].addr), - PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + dma_unmap_single(vp->gendev, le32_to_cpu(vp->rx_ring[i].addr), + PKT_BUF_SZ, DMA_FROM_DEVICE); dev_kfree_skb(vp->rx_skbuff[i]); vp->rx_skbuff[i] = NULL; } @@ -2775,12 +2774,12 @@ vortex_close(struct net_device *dev) int k; for (k=0; k<=skb_shinfo(skb)->nr_frags; k++) - pci_unmap_single(VORTEX_PCI(vp), + dma_unmap_single(vp->gendev, le32_to_cpu(vp->tx_ring[i].frag[k].addr), le32_to_cpu(vp->tx_ring[i].frag[k].length)&0xFFF, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); #else - pci_unmap_single(VORTEX_PCI(vp), le32_to_cpu(vp->tx_ring[i].addr), skb->len, PCI_DMA_TODEVICE); + dma_unmap_single(vp->gendev, le32_to_cpu(vp->tx_ring[i].addr), skb->len, DMA_TO_DEVICE); #endif dev_kfree_skb(skb); vp->tx_skbuff[i] = NULL; @@ -3288,11 +3287,10 @@ static void vortex_remove_one(struct pci_dev *pdev) pci_iounmap(pdev, vp->ioaddr); - pci_free_consistent(pdev, - sizeof(struct boom_rx_desc) * RX_RING_SIZE - + sizeof(struct boom_tx_desc) * TX_RING_SIZE, - vp->rx_ring, - vp->rx_ring_dma); + dma_free_coherent(&pdev->dev, + sizeof(struct boom_rx_desc) * RX_RING_SIZE + + sizeof(struct boom_tx_desc) * TX_RING_SIZE, + vp->rx_ring, vp->rx_ring_dma); pci_release_regions(pdev); -- cgit v1.2.3-59-g8ed1b From 91dfd02b23006e7cc557bcb3a40aeb740f66fb52 Mon Sep 17 00:00:00 2001 From: Michal Kalderon Date: Sun, 13 May 2018 20:54:06 +0300 Subject: qede: Fix ref-cnt usage count Rebooting while qedr is loaded with a VLAN interface present results in unregister_netdevice waiting for the usage count to become free. The fix is that rdma devices should be removed before unregistering the netdevice, to assure all references to ndev are decreased. Fixes: cee9fbd8e2e9 ("qede: Add qedr framework") Signed-off-by: Ariel Elior Signed-off-by: Michal Kalderon Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qede/qede_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index a01e7d6e5442..f6655e251bbd 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -1066,13 +1066,12 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode) DP_INFO(edev, "Starting qede_remove\n"); + qede_rdma_dev_remove(edev); unregister_netdev(ndev); cancel_delayed_work_sync(&edev->sp_task); qede_ptp_disable(edev); - qede_rdma_dev_remove(edev); - edev->ops->common->set_power_state(cdev, PCI_D0); pci_set_drvdata(pdev, NULL); -- cgit v1.2.3-59-g8ed1b From 2278446e2b7cd33ad894b32e7eb63afc7db6c86e Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 14 May 2018 11:57:23 +0300 Subject: xhci: Fix USB3 NULL pointer dereference at logical disconnect. Hub driver will try to disable a USB3 device twice at logical disconnect, racing with xhci_free_dev() callback from the first port disable. This can be triggered with "udisksctl power-off --block-device " or by writing "1" to the "remove" sysfs file for a USB3 device in 4.17-rc4. USB3 devices don't have a similar disabled link state as USB2 devices, and use a U3 suspended link state instead. In this state the port is still enabled and connected. hub_port_connect() first disconnects the device, then later it notices that device is still enabled (due to U3 states) it will try to disable the port again (set to U3). The xhci_free_dev() called during device disable is async, so checking for existing xhci->devs[i] when setting link state to U3 the second time was successful, even if device was being freed. The regression was caused by, and whole thing revealed by, Commit 44a182b9d177 ("xhci: Fix use-after-free in xhci_free_virt_device") which sets xhci->devs[i]->udev to NULL before xhci_virt_dev() returned. and causes a NULL pointer dereference the second time we try to set U3. Fix this by checking xhci->devs[i]->udev exists before setting link state. The original patch went to stable so this fix needs to be applied there as well. Fixes: 44a182b9d177 ("xhci: Fix use-after-free in xhci_free_virt_device") Cc: Reported-by: Jordan Glover Tested-by: Jordan Glover Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 72ebbc908e19..32cd52ca8318 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -354,7 +354,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, slot_id = 0; for (i = 0; i < MAX_HC_SLOTS; i++) { - if (!xhci->devs[i]) + if (!xhci->devs[i] || !xhci->devs[i]->udev) continue; speed = xhci->devs[i]->udev->speed; if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3)) -- cgit v1.2.3-59-g8ed1b From 20943f984967477c906522112d2b6b5a29f94684 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Wed, 2 May 2018 20:50:21 +0100 Subject: drm/i915/userptr: reject zero user_size Operating on a zero sized GEM userptr object will lead to explosions. Fixes: 5cc9ed4b9a7a ("drm/i915: Introduce mapping of user pages into video memory (userptr) ioctl") Testcase: igt/gem_userptr_blits/input-checking Signed-off-by: Matthew Auld Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20180502195021.30900-1-matthew.auld@intel.com (cherry picked from commit c11c7bfd213495784b22ef82a69b6489f8d0092f) Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem_userptr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index d596a8302ca3..854bd51b9478 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -778,6 +778,9 @@ i915_gem_userptr_ioctl(struct drm_device *dev, I915_USERPTR_UNSYNCHRONIZED)) return -EINVAL; + if (!args->user_size) + return -EINVAL; + if (offset_in_page(args->user_ptr | args->user_size)) return -EINVAL; -- cgit v1.2.3-59-g8ed1b From cd078bf95df29d827daca0274a9a13821c11eedb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 11 May 2018 13:11:45 +0100 Subject: drm/i915/execlists: Use rmb() to order CSB reads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We assume that the CSB is written using the normal ringbuffer coherency protocols, as outlined in kernel/events/ring_buffer.c: * (HW) (DRIVER) * * if (LOAD ->data_tail) { LOAD ->data_head * (A) smp_rmb() (C) * STORE $data LOAD $data * smp_wmb() (B) smp_mb() (D) * STORE ->data_head STORE ->data_tail * } So we assume that the HW fulfils its ordering requirements (B), and so we should use a complimentary rmb (C) to ensure that our read of its WRITE pointer is completed before we start accessing the data. The final mb (D) is implied by the uncached mmio we perform to inform the HW of our READ pointer. References: https://bugs.freedesktop.org/show_bug.cgi?id=105064 References: https://bugs.freedesktop.org/show_bug.cgi?id=105888 References: https://bugs.freedesktop.org/show_bug.cgi?id=106185 Fixes: 767a983ab255 ("drm/i915/execlists: Read the context-status HEAD from the HWSP") References: 61bf9719fa17 ("drm/i915/cnl: Use mmio access to context status buffer") Suggested-by: Mika Kuoppala Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Joonas Lahtinen Cc: Tvrtko Ursulin Cc: MichaÅ‚ Winiarski Cc: Rafael Antognolli Cc: Michel Thierry Cc: Timo Aaltonen Tested-by: Timo Aaltonen Acked-by: Michel Thierry Acked-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20180511121147.31915-1-chris@chris-wilson.co.uk (cherry picked from commit 77dfedb5be03779f9a5d83e323a1b36e32090105) Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/intel_lrc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index e3a5f673ff67..8704f7f8d072 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -884,6 +884,7 @@ static void execlists_submission_tasklet(unsigned long data) head = execlists->csb_head; tail = READ_ONCE(buf[write_idx]); + rmb(); /* Hopefully paired with a wmb() in HW */ } GEM_TRACE("%s cs-irq head=%d [%d%s], tail=%d [%d%s]\n", engine->name, -- cgit v1.2.3-59-g8ed1b From 90d617633368ab97a2c7571c6e66dad54f39228d Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 9 May 2018 09:13:58 +0200 Subject: mtd: rawnand: marvell: Fix read logic for layouts with ->nchunks > 2 The code is doing monolithic reads for all chunks except the last one which is wrong since a monolithic read will issue the READ0+ADDRS+READ_START sequence. It not only takes longer because it forces the NAND chip to reload the page content into its internal cache, but by doing that we also reset the column pointer to 0, which means we'll always read the first chunk instead of moving to the next one. Rework the code to do a monolithic read only for the first chunk, then switch to naked reads for all intermediate chunks and finally issue a last naked read for the last chunk. Fixes: 02f26ecf8c77 mtd: nand: add reworked Marvell NAND controller driver Cc: stable@vger.kernel.org Reported-by: Chris Packham Signed-off-by: Boris Brezillon Tested-by: Chris Packham Acked-by: Miquel Raynal --- drivers/mtd/nand/raw/marvell_nand.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index db5ec4e8bde9..ebb1d141b900 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -1194,11 +1194,13 @@ static void marvell_nfc_hw_ecc_bch_read_chunk(struct nand_chip *chip, int chunk, NDCB0_CMD2(NAND_CMD_READSTART); /* - * Trigger the naked read operation only on the last chunk. - * Otherwise, use monolithic read. + * Trigger the monolithic read on the first chunk, then naked read on + * intermediate chunks and finally a last naked read on the last chunk. */ - if (lt->nchunks == 1 || (chunk < lt->nchunks - 1)) + if (chunk == 0) nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_MONOLITHIC_RW); + else if (chunk < lt->nchunks - 1) + nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_NAKED_RW); else nfc_op.ndcb[0] |= NDCB0_CMD_XTYPE(XTYPE_LAST_NAKED_RW); -- cgit v1.2.3-59-g8ed1b From ebc3dd688cd988754a304147753b13e58de1b5a1 Mon Sep 17 00:00:00 2001 From: Daniel Glöckner Date: Mon, 14 May 2018 09:40:05 -0500 Subject: usb: musb: fix remote wakeup racing with suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It has been observed that writing 0xF2 to the power register while it reads as 0xF4 results in the register having the value 0xF0, i.e. clearing RESUME and setting SUSPENDM in one go does not work. It might also violate the USB spec to transition directly from resume to suspend, especially when not taking T_DRSMDN into account. But this is what happens when a remote wakeup occurs between SetPortFeature USB_PORT_FEAT_SUSPEND on the root hub and musb_bus_suspend being called. This commit returns -EBUSY when musb_bus_suspend is called while remote wakeup is signalled and thus avoids to reset the RESUME bit. Ignoring this error when musb_port_suspend is called from musb_hub_control is ok. Signed-off-by: Daniel Glöckner Signed-off-by: Bin Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_host.c | 5 ++++- drivers/usb/musb/musb_host.h | 7 +++++-- drivers/usb/musb/musb_virthub.c | 25 +++++++++++++++---------- 3 files changed, 24 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index e7f99d55922a..15a42cee0a9c 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2524,8 +2524,11 @@ static int musb_bus_suspend(struct usb_hcd *hcd) { struct musb *musb = hcd_to_musb(hcd); u8 devctl; + int ret; - musb_port_suspend(musb, true); + ret = musb_port_suspend(musb, true); + if (ret) + return ret; if (!is_host_active(musb)) return 0; diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h index 72392bbcd0a4..2999845632ce 100644 --- a/drivers/usb/musb/musb_host.h +++ b/drivers/usb/musb/musb_host.h @@ -67,7 +67,7 @@ extern void musb_host_rx(struct musb *, u8); extern void musb_root_disconnect(struct musb *musb); extern void musb_host_resume_root_hub(struct musb *musb); extern void musb_host_poke_root_hub(struct musb *musb); -extern void musb_port_suspend(struct musb *musb, bool do_suspend); +extern int musb_port_suspend(struct musb *musb, bool do_suspend); extern void musb_port_reset(struct musb *musb, bool do_reset); extern void musb_host_finish_resume(struct work_struct *work); #else @@ -99,7 +99,10 @@ static inline void musb_root_disconnect(struct musb *musb) {} static inline void musb_host_resume_root_hub(struct musb *musb) {} static inline void musb_host_poll_rh_status(struct musb *musb) {} static inline void musb_host_poke_root_hub(struct musb *musb) {} -static inline void musb_port_suspend(struct musb *musb, bool do_suspend) {} +static inline int musb_port_suspend(struct musb *musb, bool do_suspend) +{ + return 0; +} static inline void musb_port_reset(struct musb *musb, bool do_reset) {} static inline void musb_host_finish_resume(struct work_struct *work) {} #endif diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 5165d2b07ade..2f8dd9826e94 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -48,14 +48,14 @@ void musb_host_finish_resume(struct work_struct *work) spin_unlock_irqrestore(&musb->lock, flags); } -void musb_port_suspend(struct musb *musb, bool do_suspend) +int musb_port_suspend(struct musb *musb, bool do_suspend) { struct usb_otg *otg = musb->xceiv->otg; u8 power; void __iomem *mbase = musb->mregs; if (!is_host_active(musb)) - return; + return 0; /* NOTE: this doesn't necessarily put PHY into low power mode, * turning off its clock; that's a function of PHY integration and @@ -66,16 +66,20 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) if (do_suspend) { int retries = 10000; - power &= ~MUSB_POWER_RESUME; - power |= MUSB_POWER_SUSPENDM; - musb_writeb(mbase, MUSB_POWER, power); + if (power & MUSB_POWER_RESUME) + return -EBUSY; - /* Needed for OPT A tests */ - power = musb_readb(mbase, MUSB_POWER); - while (power & MUSB_POWER_SUSPENDM) { + if (!(power & MUSB_POWER_SUSPENDM)) { + power |= MUSB_POWER_SUSPENDM; + musb_writeb(mbase, MUSB_POWER, power); + + /* Needed for OPT A tests */ power = musb_readb(mbase, MUSB_POWER); - if (retries-- < 1) - break; + while (power & MUSB_POWER_SUSPENDM) { + power = musb_readb(mbase, MUSB_POWER); + if (retries-- < 1) + break; + } } musb_dbg(musb, "Root port suspended, power %02x", power); @@ -111,6 +115,7 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) schedule_delayed_work(&musb->finish_resume_work, msecs_to_jiffies(USB_RESUME_TIMEOUT)); } + return 0; } void musb_port_reset(struct musb *musb, bool do_reset) -- cgit v1.2.3-59-g8ed1b From b196d88aba8ac72b775137854121097f4c4c6862 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 11 May 2018 10:49:25 +0800 Subject: tun: fix use after free for ptr_ring We used to initialize ptr_ring during TUNSETIFF, this is because its size depends on the tx_queue_len of netdevice. And we try to clean it up when socket were detached from netdevice. A race were spotted when trying to do uninit during a read which will lead a use after free for pointer ring. Solving this by always initialize a zero size ptr_ring in open() and do resizing during TUNSETIFF, and then we can safely do cleanup during close(). With this, there's no need for the workaround that was introduced by commit 4df0bfc79904 ("tun: fix a memory leak for tfile->tx_array"). Reported-by: syzbot+e8b902c3c3fadf0a9dba@syzkaller.appspotmail.com Cc: Eric Dumazet Cc: Cong Wang Cc: Michael S. Tsirkin Fixes: 1576d9860599 ("tun: switch to use skb array for tx") Signed-off-by: Jason Wang Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/net/tun.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index ef33950a45d9..9fbbb328b95b 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -681,15 +681,6 @@ static void tun_queue_purge(struct tun_file *tfile) skb_queue_purge(&tfile->sk.sk_error_queue); } -static void tun_cleanup_tx_ring(struct tun_file *tfile) -{ - if (tfile->tx_ring.queue) { - ptr_ring_cleanup(&tfile->tx_ring, tun_ptr_free); - xdp_rxq_info_unreg(&tfile->xdp_rxq); - memset(&tfile->tx_ring, 0, sizeof(tfile->tx_ring)); - } -} - static void __tun_detach(struct tun_file *tfile, bool clean) { struct tun_file *ntfile; @@ -736,7 +727,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) tun->dev->reg_state == NETREG_REGISTERED) unregister_netdevice(tun->dev); } - tun_cleanup_tx_ring(tfile); + if (tun) + xdp_rxq_info_unreg(&tfile->xdp_rxq); sock_put(&tfile->sk); } } @@ -783,14 +775,14 @@ static void tun_detach_all(struct net_device *dev) tun_napi_del(tun, tfile); /* Drop read queue */ tun_queue_purge(tfile); + xdp_rxq_info_unreg(&tfile->xdp_rxq); sock_put(&tfile->sk); - tun_cleanup_tx_ring(tfile); } list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { tun_enable_queue(tfile); tun_queue_purge(tfile); + xdp_rxq_info_unreg(&tfile->xdp_rxq); sock_put(&tfile->sk); - tun_cleanup_tx_ring(tfile); } BUG_ON(tun->numdisabled != 0); @@ -834,7 +826,8 @@ static int tun_attach(struct tun_struct *tun, struct file *file, } if (!tfile->detached && - ptr_ring_init(&tfile->tx_ring, dev->tx_queue_len, GFP_KERNEL)) { + ptr_ring_resize(&tfile->tx_ring, dev->tx_queue_len, + GFP_KERNEL, tun_ptr_free)) { err = -ENOMEM; goto out; } @@ -3219,6 +3212,11 @@ static int tun_chr_open(struct inode *inode, struct file * file) &tun_proto, 0); if (!tfile) return -ENOMEM; + if (ptr_ring_init(&tfile->tx_ring, 0, GFP_KERNEL)) { + sk_free(&tfile->sk); + return -ENOMEM; + } + RCU_INIT_POINTER(tfile->tun, NULL); tfile->flags = 0; tfile->ifindex = 0; @@ -3239,8 +3237,6 @@ static int tun_chr_open(struct inode *inode, struct file * file) sock_set_flag(&tfile->sk, SOCK_ZEROCOPY); - memset(&tfile->tx_ring, 0, sizeof(tfile->tx_ring)); - return 0; } @@ -3249,6 +3245,7 @@ static int tun_chr_close(struct inode *inode, struct file *file) struct tun_file *tfile = file->private_data; tun_detach(tfile, true); + ptr_ring_cleanup(&tfile->tx_ring, tun_ptr_free); return 0; } -- cgit v1.2.3-59-g8ed1b From 7b34c0fb1b51a6377752fc971e57577eeb102d60 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 8 May 2018 14:06:15 -0700 Subject: ACPICA: Add deferred package support for the Load and loadTable operators Completes the support and fixes a regression introduced in version 20180209. The regression caused package objects that were loaded by the Load and loadTable operators. This created an error message like the following: [ 0.251922] ACPI Error: No pointer back to namespace node in package 00000000fd2a44cd (20180313/dsargs-303) Link: https://bugzilla.kernel.org/show_bug.cgi?id=199413 Fixes: 5a8361f7ecce (ACPICA: Integrate package handling with module-level code) Signed-off-by: Bob Moore Signed-off-by: Erik Schmauss Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acnamesp.h | 4 +++ drivers/acpi/acpica/exconfig.c | 14 ++++++++ drivers/acpi/acpica/nsinit.c | 76 +++++++++++++++++++++++++++++++----------- 3 files changed, 74 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 514aaf948ea9..3825df923480 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -56,6 +56,10 @@ acpi_status acpi_ns_initialize_objects(void); acpi_status acpi_ns_initialize_devices(u32 flags); +acpi_status +acpi_ns_init_one_package(acpi_handle obj_handle, + u32 level, void *context, void **return_value); + /* * nsload - Namespace loading */ diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 99d92cb32803..f85c6f3271f6 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -174,6 +174,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, return_ACPI_STATUS(status); } + /* Complete the initialization/resolution of package objects */ + + status = acpi_ns_walk_namespace(ACPI_TYPE_PACKAGE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, 0, + acpi_ns_init_one_package, NULL, NULL, + NULL); + /* Parameter Data (optional) */ if (parameter_node) { @@ -430,6 +437,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, return_ACPI_STATUS(status); } + /* Complete the initialization/resolution of package objects */ + + status = acpi_ns_walk_namespace(ACPI_TYPE_PACKAGE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, 0, + acpi_ns_init_one_package, NULL, NULL, + NULL); + /* Store the ddb_handle into the Target operand */ status = acpi_ex_store(ddb_handle, target, walk_state); diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 77f2b5f4948a..d77257d1c827 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -240,6 +240,58 @@ error_exit: return_ACPI_STATUS(status); } +/******************************************************************************* + * + * FUNCTION: acpi_ns_init_one_package + * + * PARAMETERS: obj_handle - Node + * level - Current nesting level + * context - Not used + * return_value - Not used + * + * RETURN: Status + * + * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every package + * within the namespace. Used during dynamic load of an SSDT. + * + ******************************************************************************/ + +acpi_status +acpi_ns_init_one_package(acpi_handle obj_handle, + u32 level, void *context, void **return_value) +{ + acpi_status status; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *node = + (struct acpi_namespace_node *)obj_handle; + + obj_desc = acpi_ns_get_attached_object(node); + if (!obj_desc) { + return (AE_OK); + } + + /* Exit if package is already initialized */ + + if (obj_desc->package.flags & AOPOBJ_DATA_VALID) { + return (AE_OK); + } + + status = acpi_ds_get_package_arguments(obj_desc); + if (ACPI_FAILURE(status)) { + return (AE_OK); + } + + status = + acpi_ut_walk_package_tree(obj_desc, NULL, + acpi_ds_init_package_element, NULL); + if (ACPI_FAILURE(status)) { + return (AE_OK); + } + + obj_desc->package.flags |= AOPOBJ_DATA_VALID; + return (AE_OK); +} + /******************************************************************************* * * FUNCTION: acpi_ns_init_one_object @@ -360,27 +412,11 @@ acpi_ns_init_one_object(acpi_handle obj_handle, case ACPI_TYPE_PACKAGE: - info->package_init++; - status = acpi_ds_get_package_arguments(obj_desc); - if (ACPI_FAILURE(status)) { - break; - } - - ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE, - "%s: Completing resolution of Package elements\n", - ACPI_GET_FUNCTION_NAME)); + /* Complete the initialization/resolution of the package object */ - /* - * Resolve all named references in package objects (and all - * sub-packages). This action has been deferred until the entire - * namespace has been loaded, in order to support external and - * forward references from individual package elements (05/2017). - */ - status = acpi_ut_walk_package_tree(obj_desc, NULL, - acpi_ds_init_package_element, - NULL); - - obj_desc->package.flags |= AOPOBJ_DATA_VALID; + info->package_init++; + status = + acpi_ns_init_one_package(obj_handle, level, NULL, NULL); break; default: -- cgit v1.2.3-59-g8ed1b From 0cf442c6bcf572e04f5690340d5b8e62afcee2ca Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 24 Apr 2018 17:45:06 +0200 Subject: cpufreq: armada-37xx: driver relies on cpufreq-dt Armada-37xx driver registers a cpufreq-dt driver. Not having CONFIG_CPUFREQ_DT selected leads to a silent abort during the probe. Prevent that situation by having the former depending on the latter. Fixes: 92ce45fb875d7 (cpufreq: Add DVFS support for Armada 37xx) Cc: 4.16+ # 4.16+ Signed-off-by: Miquel Raynal Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/Kconfig.arm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index de55c7d57438..96b35b8b3606 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -20,7 +20,7 @@ config ACPI_CPPC_CPUFREQ config ARM_ARMADA_37XX_CPUFREQ tristate "Armada 37xx CPUFreq support" - depends on ARCH_MVEBU + depends on ARCH_MVEBU && CPUFREQ_DT help This adds the CPUFreq driver support for Marvell Armada 37xx SoCs. The Armada 37xx PMU supports 4 frequency and VDD levels. -- cgit v1.2.3-59-g8ed1b From 57f6f99fdad9984801cde05c1db68fe39b474a10 Mon Sep 17 00:00:00 2001 From: Tarick Bedeir Date: Sun, 13 May 2018 16:38:45 -0700 Subject: net/mlx4_core: Fix error handling in mlx4_init_port_info. Avoid exiting the function with a lingering sysfs file (if the first call to device_create_file() fails while the second succeeds), and avoid calling devlink_port_unregister() twice. In other words, either mlx4_init_port_info() succeeds and returns zero, or it fails, returns non-zero, and requires no cleanup. Fixes: 096335b3f983 ("mlx4_core: Allow dynamic MTU configuration for IB ports") Signed-off-by: Tarick Bedeir Reviewed-by: Leon Romanovsky Reviewed-by: Tariq Toukan Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 211578ffc70d..60172a38c4a4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -2929,6 +2929,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) mlx4_err(dev, "Failed to create file for port %d\n", port); devlink_port_unregister(&info->devlink_port); info->port = -1; + return err; } sprintf(info->dev_mtu_name, "mlx4_port%d_mtu", port); @@ -2950,9 +2951,10 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) &info->port_attr); devlink_port_unregister(&info->devlink_port); info->port = -1; + return err; } - return err; + return 0; } static void mlx4_cleanup_port_info(struct mlx4_port_info *info) -- cgit v1.2.3-59-g8ed1b From 849a742c59a3d597473c0232f9c2506c69eeef14 Mon Sep 17 00:00:00 2001 From: Kumar Sanghvi Date: Mon, 14 May 2018 16:27:34 +0530 Subject: cxgb4: Correct ntuple mask validation for hash filters Earlier code of doing bitwise AND with field width bits was wrong. Instead, simplify code to calculate ntuple_mask based on supplied fields and then compare with mask configured in hw - which is the correct and simpler way to validate ntuple mask. Fixes: 3eb8b62d5a26 ("cxgb4: add support to create hash-filters via tc-flower offload") Signed-off-by: Kumar Sanghvi Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c | 88 ++++++++--------------- 1 file changed, 30 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c index db92f1858060..b76447baccaf 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c @@ -836,7 +836,7 @@ bool is_filter_exact_match(struct adapter *adap, { struct tp_params *tp = &adap->params.tp; u64 hash_filter_mask = tp->hash_filter_mask; - u32 mask; + u64 ntuple_mask = 0; if (!is_hashfilter(adap)) return false; @@ -865,73 +865,45 @@ bool is_filter_exact_match(struct adapter *adap, if (!fs->val.fport || fs->mask.fport != 0xffff) return false; - if (tp->fcoe_shift >= 0) { - mask = (hash_filter_mask >> tp->fcoe_shift) & FT_FCOE_W; - if (mask && !fs->mask.fcoe) - return false; - } + /* calculate tuple mask and compare with mask configured in hw */ + if (tp->fcoe_shift >= 0) + ntuple_mask |= (u64)fs->mask.fcoe << tp->fcoe_shift; - if (tp->port_shift >= 0) { - mask = (hash_filter_mask >> tp->port_shift) & FT_PORT_W; - if (mask && !fs->mask.iport) - return false; - } + if (tp->port_shift >= 0) + ntuple_mask |= (u64)fs->mask.iport << tp->port_shift; if (tp->vnic_shift >= 0) { - mask = (hash_filter_mask >> tp->vnic_shift) & FT_VNIC_ID_W; - - if ((adap->params.tp.ingress_config & VNIC_F)) { - if (mask && !fs->mask.pfvf_vld) - return false; - } else { - if (mask && !fs->mask.ovlan_vld) - return false; - } + if ((adap->params.tp.ingress_config & VNIC_F)) + ntuple_mask |= (u64)fs->mask.pfvf_vld << tp->vnic_shift; + else + ntuple_mask |= (u64)fs->mask.ovlan_vld << + tp->vnic_shift; } - if (tp->vlan_shift >= 0) { - mask = (hash_filter_mask >> tp->vlan_shift) & FT_VLAN_W; - if (mask && !fs->mask.ivlan) - return false; - } + if (tp->vlan_shift >= 0) + ntuple_mask |= (u64)fs->mask.ivlan << tp->vlan_shift; - if (tp->tos_shift >= 0) { - mask = (hash_filter_mask >> tp->tos_shift) & FT_TOS_W; - if (mask && !fs->mask.tos) - return false; - } + if (tp->tos_shift >= 0) + ntuple_mask |= (u64)fs->mask.tos << tp->tos_shift; - if (tp->protocol_shift >= 0) { - mask = (hash_filter_mask >> tp->protocol_shift) & FT_PROTOCOL_W; - if (mask && !fs->mask.proto) - return false; - } + if (tp->protocol_shift >= 0) + ntuple_mask |= (u64)fs->mask.proto << tp->protocol_shift; - if (tp->ethertype_shift >= 0) { - mask = (hash_filter_mask >> tp->ethertype_shift) & - FT_ETHERTYPE_W; - if (mask && !fs->mask.ethtype) - return false; - } + if (tp->ethertype_shift >= 0) + ntuple_mask |= (u64)fs->mask.ethtype << tp->ethertype_shift; - if (tp->macmatch_shift >= 0) { - mask = (hash_filter_mask >> tp->macmatch_shift) & FT_MACMATCH_W; - if (mask && !fs->mask.macidx) - return false; - } + if (tp->macmatch_shift >= 0) + ntuple_mask |= (u64)fs->mask.macidx << tp->macmatch_shift; + + if (tp->matchtype_shift >= 0) + ntuple_mask |= (u64)fs->mask.matchtype << tp->matchtype_shift; + + if (tp->frag_shift >= 0) + ntuple_mask |= (u64)fs->mask.frag << tp->frag_shift; + + if (ntuple_mask != hash_filter_mask) + return false; - if (tp->matchtype_shift >= 0) { - mask = (hash_filter_mask >> tp->matchtype_shift) & - FT_MPSHITTYPE_W; - if (mask && !fs->mask.matchtype) - return false; - } - if (tp->frag_shift >= 0) { - mask = (hash_filter_mask >> tp->frag_shift) & - FT_FRAGMENTATION_W; - if (mask && !fs->mask.frag) - return false; - } return true; } -- cgit v1.2.3-59-g8ed1b From 61aeecea40afb2b89933e27cd4adb10fc2e75cfd Mon Sep 17 00:00:00 2001 From: "hpreg@vmware.com" Date: Mon, 14 May 2018 08:14:34 -0400 Subject: vmxnet3: set the DMA mask before the first DMA map operation The DMA mask must be set before, not after, the first DMA map operation, or the first DMA map operation could in theory fail on some systems. Fixes: b0eb57cb97e78 ("VMXNET3: Add support for virtual IOMMU") Signed-off-by: Regis Duchesne Acked-by: Ronak Doshi Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 50 +++++++++++++++++++-------------------- drivers/net/vmxnet3/vmxnet3_int.h | 8 ++++--- 2 files changed, 30 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 9ebe2a689966..ed58685c353f 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2688,7 +2688,7 @@ vmxnet3_set_mac_addr(struct net_device *netdev, void *p) /* ==================== initialization and cleanup routines ============ */ static int -vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64) +vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter) { int err; unsigned long mmio_start, mmio_len; @@ -2700,30 +2700,12 @@ vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64) return err; } - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) { - if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) { - dev_err(&pdev->dev, - "pci_set_consistent_dma_mask failed\n"); - err = -EIO; - goto err_set_mask; - } - *dma64 = true; - } else { - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) { - dev_err(&pdev->dev, - "pci_set_dma_mask failed\n"); - err = -EIO; - goto err_set_mask; - } - *dma64 = false; - } - err = pci_request_selected_regions(pdev, (1 << 2) - 1, vmxnet3_driver_name); if (err) { dev_err(&pdev->dev, "Failed to request region for adapter: error %d\n", err); - goto err_set_mask; + goto err_enable_device; } pci_set_master(pdev); @@ -2751,7 +2733,7 @@ err_bar1: iounmap(adapter->hw_addr0); err_ioremap: pci_release_selected_regions(pdev, (1 << 2) - 1); -err_set_mask: +err_enable_device: pci_disable_device(pdev); return err; } @@ -3254,7 +3236,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, #endif }; int err; - bool dma64 = false; /* stupid gcc */ + bool dma64; u32 ver; struct net_device *netdev; struct vmxnet3_adapter *adapter; @@ -3300,6 +3282,24 @@ vmxnet3_probe_device(struct pci_dev *pdev, adapter->rx_ring_size = VMXNET3_DEF_RX_RING_SIZE; adapter->rx_ring2_size = VMXNET3_DEF_RX_RING2_SIZE; + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) { + if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) { + dev_err(&pdev->dev, + "pci_set_consistent_dma_mask failed\n"); + err = -EIO; + goto err_set_mask; + } + dma64 = true; + } else { + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) { + dev_err(&pdev->dev, + "pci_set_dma_mask failed\n"); + err = -EIO; + goto err_set_mask; + } + dma64 = false; + } + spin_lock_init(&adapter->cmd_lock); adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter, sizeof(struct vmxnet3_adapter), @@ -3307,7 +3307,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) { dev_err(&pdev->dev, "Failed to map dma\n"); err = -EFAULT; - goto err_dma_map; + goto err_set_mask; } adapter->shared = dma_alloc_coherent( &adapter->pdev->dev, @@ -3358,7 +3358,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, } #endif /* VMXNET3_RSS */ - err = vmxnet3_alloc_pci_resources(adapter, &dma64); + err = vmxnet3_alloc_pci_resources(adapter); if (err < 0) goto err_alloc_pci; @@ -3504,7 +3504,7 @@ err_alloc_queue_desc: err_alloc_shared: dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa, sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE); -err_dma_map: +err_set_mask: free_netdev(netdev); return err; } diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index a3326463b71f..b379bed5f51d 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -69,10 +69,12 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.4.14.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.4.15.0-k" -/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01040e00 +/* Each byte of this 32-bit integer encodes a version number in + * VMXNET3_DRIVER_VERSION_STRING. + */ +#define VMXNET3_DRIVER_VERSION_NUM 0x01040f00 #if defined(CONFIG_PCI_MSI) /* RSS only makes sense if MSI-X is supported. */ -- cgit v1.2.3-59-g8ed1b From f3002c1374fb2367c9d8dbb28852791ef90d2bac Mon Sep 17 00:00:00 2001 From: "hpreg@vmware.com" Date: Mon, 14 May 2018 08:14:49 -0400 Subject: vmxnet3: use DMA memory barriers where required The gen bits must be read first from (resp. written last to) DMA memory. The proper way to enforce this on Linux is to call dma_rmb() (resp. dma_wmb()). Signed-off-by: Regis Duchesne Acked-by: Ronak Doshi Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 22 ++++++++++++++++++++++ drivers/net/vmxnet3/vmxnet3_int.h | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index ed58685c353f..27a9bb8c9611 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -369,6 +369,11 @@ vmxnet3_tq_tx_complete(struct vmxnet3_tx_queue *tq, gdesc = tq->comp_ring.base + tq->comp_ring.next2proc; while (VMXNET3_TCD_GET_GEN(&gdesc->tcd) == tq->comp_ring.gen) { + /* Prevent any &gdesc->tcd field from being (speculatively) + * read before (&gdesc->tcd)->gen is read. + */ + dma_rmb(); + completed += vmxnet3_unmap_pkt(VMXNET3_TCD_GET_TXIDX( &gdesc->tcd), tq, adapter->pdev, adapter); @@ -1103,6 +1108,11 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, gdesc->txd.tci = skb_vlan_tag_get(skb); } + /* Ensure that the write to (&gdesc->txd)->gen will be observed after + * all other writes to &gdesc->txd. + */ + dma_wmb(); + /* finally flips the GEN bit of the SOP desc. */ gdesc->dword[2] = cpu_to_le32(le32_to_cpu(gdesc->dword[2]) ^ VMXNET3_TXD_GEN); @@ -1298,6 +1308,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, */ break; } + + /* Prevent any rcd field from being (speculatively) read before + * rcd->gen is read. + */ + dma_rmb(); + BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2 && rcd->rqID != rq->dataRingQid); idx = rcd->rxdIdx; @@ -1528,6 +1544,12 @@ rcd_done: ring->next2comp = idx; num_to_alloc = vmxnet3_cmd_ring_desc_avail(ring); ring = rq->rx_ring + ring_idx; + + /* Ensure that the writes to rxd->gen bits will be observed + * after all other writes to rxd objects. + */ + dma_wmb(); + while (num_to_alloc) { vmxnet3_getRxDesc(rxd, &ring->base[ring->next2fill].rxd, &rxCmdDesc); diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index b379bed5f51d..a2c554f8a61b 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -69,12 +69,12 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.4.15.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.4.16.0-k" /* Each byte of this 32-bit integer encodes a version number in * VMXNET3_DRIVER_VERSION_STRING. */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01040f00 +#define VMXNET3_DRIVER_VERSION_NUM 0x01041000 #if defined(CONFIG_PCI_MSI) /* RSS only makes sense if MSI-X is supported. */ -- cgit v1.2.3-59-g8ed1b From 76ef6b28ea4f81c3d511866a9b31392caa833126 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 15 May 2018 13:38:15 +1000 Subject: drm: set FMODE_UNSIGNED_OFFSET for drm files Since we have the ttm and gem vma managers using a subset of the file address space for objects, and these start at 0x100000000 they will overflow the new mmap checks. I've checked all the mmap routines I could see for any bad behaviour but overall most people use GEM/TTM VMA managers even the legacy drivers have a hashtable. Reported-and-Tested-by: Arthur Marsh (amarsh04 on #radeon) Fixes: be83bbf8068 (mmap: introduce sane default mmap limits) Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_file.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index e394799979a6..6d9b9453707c 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -212,6 +212,7 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) return -ENOMEM; filp->private_data = priv; + filp->f_mode |= FMODE_UNSIGNED_OFFSET; priv->filp = filp; priv->pid = get_pid(task_pid(current)); priv->minor = minor; -- cgit v1.2.3-59-g8ed1b From e521813468f786271a87e78e8644243bead48fad Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Wed, 2 May 2018 08:48:43 +0200 Subject: s390/qdio: fix access to uninitialized qdio_q fields Ever since CQ/QAOB support was added, calling qdio_free() straight after qdio_alloc() results in qdio_release_memory() accessing uninitialized memory (ie. q->u.out.use_cq and q->u.out.aobs). Followed by a kmem_cache_free() on the random AOB addresses. For older kernels that don't have 6e30c549f6ca, the same applies if qdio_establish() fails in the DEV_STATE_ONLINE check. While initializing q->u.out.use_cq would be enough to fix this particular bug, the more future-proof change is to just zero-alloc the whole struct. Fixes: 104ea556ee7f ("qdio: support asynchronous delivery of storage blocks") Cc: #v3.2+ Signed-off-by: Julian Wiedmann Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 439991d71b14..22ddb49e0f50 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -141,7 +141,7 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues) int i; for (i = 0; i < nr_queues; i++) { - q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); + q = kmem_cache_zalloc(qdio_q_cache, GFP_KERNEL); if (!q) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 2e68adcd2fb21b7188ba449f0fab3bee2910e500 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Wed, 2 May 2018 08:28:34 +0200 Subject: s390/qdio: don't release memory in qdio_setup_irq() Calling qdio_release_memory() on error is just plain wrong. It frees the main qdio_irq struct, when following code still uses it. Also, no other error path in qdio_establish() does this. So trust callers to clean up via qdio_free() if some step of the QDIO initialization fails. Fixes: 779e6e1c724d ("[S390] qdio: new qdio driver.") Cc: #v2.6.27+ Signed-off-by: Julian Wiedmann Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio_setup.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 22ddb49e0f50..4c14ce428e92 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -456,7 +456,6 @@ int qdio_setup_irq(struct qdio_initialize *init_data) { struct ciw *ciw; struct qdio_irq *irq_ptr = init_data->cdev->private->qdio_data; - int rc; memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib)); memset(&irq_ptr->siga_flag, 0, sizeof(irq_ptr->siga_flag)); @@ -493,16 +492,14 @@ int qdio_setup_irq(struct qdio_initialize *init_data) ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_EQUEUE); if (!ciw) { DBF_ERROR("%4x NO EQ", irq_ptr->schid.sch_no); - rc = -EINVAL; - goto out_err; + return -EINVAL; } irq_ptr->equeue = *ciw; ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_AQUEUE); if (!ciw) { DBF_ERROR("%4x NO AQ", irq_ptr->schid.sch_no); - rc = -EINVAL; - goto out_err; + return -EINVAL; } irq_ptr->aqueue = *ciw; @@ -512,9 +509,6 @@ int qdio_setup_irq(struct qdio_initialize *init_data) init_data->cdev->handler = qdio_int_handler; spin_unlock_irq(get_ccwdev_lock(irq_ptr->cdev)); return 0; -out_err: - qdio_release_memory(irq_ptr); - return rc; } void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, -- cgit v1.2.3-59-g8ed1b From de9a8634f1cb4560a35696d472cc7f1383d9b866 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 9 May 2018 21:46:29 +0200 Subject: i2c: pmcmsp: return message count on master_xfer success Returning zero is wrong in this case. Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang Fixes: 1b144df1d7d6 ("i2c: New PMC MSP71xx TWI bus driver") --- drivers/i2c/busses/i2c-pmcmsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index 2aa0e83174c5..ec27e27e8d06 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c @@ -567,7 +567,7 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap, return -1; } - return 0; + return num; } static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter) -- cgit v1.2.3-59-g8ed1b From 12d9bbc5a7f347eaa65ff2a9d34995cadc05eb1b Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 9 May 2018 21:46:30 +0200 Subject: i2c: pmcmsp: fix error return from master_xfer Returning -1 (-EPERM) is not appropriate here, go with -EIO. Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang Fixes: 1b144df1d7d6 ("i2c: New PMC MSP71xx TWI bus driver") --- drivers/i2c/busses/i2c-pmcmsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index ec27e27e8d06..dae8ac618a52 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c @@ -564,7 +564,7 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap, * TODO: We could potentially loop and retry in the case * of MSP_TWI_XFER_TIMEOUT. */ - return -1; + return -EIO; } return num; -- cgit v1.2.3-59-g8ed1b From 35cd67a0caf767aba472452865dcb4471fcce2b1 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 9 May 2018 21:47:48 +0200 Subject: i2c: viperboard: return message count on master_xfer success Returning zero is wrong in this case. Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang Fixes: 174a13aa8669 ("i2c: Add viperboard i2c master driver") --- drivers/i2c/busses/i2c-viperboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c index e4be86b3de9a..7235c7302bb7 100644 --- a/drivers/i2c/busses/i2c-viperboard.c +++ b/drivers/i2c/busses/i2c-viperboard.c @@ -337,7 +337,7 @@ static int vprbrd_i2c_xfer(struct i2c_adapter *i2c, struct i2c_msg *msgs, } mutex_unlock(&vb->lock); } - return 0; + return num; error: mutex_unlock(&vb->lock); return error; -- cgit v1.2.3-59-g8ed1b From 28b68acc4a88dcf91fd1dcf2577371dc9bf574cc Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 11 Apr 2018 18:13:30 -0600 Subject: usbip: usbip_host: refine probe and disconnect debug msgs to be useful Refine probe and disconnect debug msgs to be useful and say what is in progress. Signed-off-by: Shuah Khan Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/stub_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index dd8ef36ab10e..7813c1862941 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -302,7 +302,7 @@ static int stub_probe(struct usb_device *udev) struct bus_id_priv *busid_priv; int rc; - dev_dbg(&udev->dev, "Enter\n"); + dev_dbg(&udev->dev, "Enter probe\n"); /* check we should claim or not by busid_table */ busid_priv = get_busid_priv(udev_busid); @@ -404,7 +404,7 @@ static void stub_disconnect(struct usb_device *udev) struct bus_id_priv *busid_priv; int rc; - dev_dbg(&udev->dev, "Enter\n"); + dev_dbg(&udev->dev, "Enter disconnect\n"); busid_priv = get_busid_priv(udev_busid); if (!busid_priv) { -- cgit v1.2.3-59-g8ed1b From 1e180f167d4e413afccbbb4a421b48b2de832549 Mon Sep 17 00:00:00 2001 From: "Shuah Khan (Samsung OSG)" Date: Mon, 30 Apr 2018 16:17:19 -0600 Subject: usbip: usbip_host: delete device from busid_table after rebind Device is left in the busid_table after unbind and rebind. Rebind initiates usb bus scan and the original driver claims the device. After rescan the device should be deleted from the busid_table as it no longer belongs to usbip_host. Fix it to delete the device after device_attach() succeeds. Signed-off-by: Shuah Khan (Samsung OSG) Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/stub_main.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index d41d0cdeec0f..fb46bd62d538 100644 --- a/drivers/usb/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c @@ -186,6 +186,9 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf, if (!bid) return -ENODEV; + /* mark the device for deletion so probe ignores it during rescan */ + bid->status = STUB_BUSID_OTHER; + /* device_attach() callers should hold parent lock for USB */ if (bid->udev->dev.parent) device_lock(bid->udev->dev.parent); @@ -197,6 +200,9 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf, return ret; } + /* delete device from busid_table */ + del_match_busid((char *) buf); + return count; } -- cgit v1.2.3-59-g8ed1b From 7510df3f29d44685bab7b1918b61a8ccd57126a9 Mon Sep 17 00:00:00 2001 From: "Shuah Khan (Samsung OSG)" Date: Mon, 30 Apr 2018 16:17:20 -0600 Subject: usbip: usbip_host: run rebind from exit when module is removed After removing usbip_host module, devices it releases are left without a driver. For example, when a keyboard or a mass storage device are bound to usbip_host when it is removed, these devices are no longer bound to any driver. Fix it to run device_attach() from the module exit routine to restore the devices to their original drivers. This includes cleanup changes and moving device_attach() code to a common routine to be called from rebind_store() and usbip_host_exit(). Signed-off-by: Shuah Khan (Samsung OSG) Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/stub_dev.c | 6 +---- drivers/usb/usbip/stub_main.c | 60 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index 7813c1862941..9d0425113c4b 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -448,12 +448,8 @@ static void stub_disconnect(struct usb_device *udev) busid_priv->sdev = NULL; stub_device_free(sdev); - if (busid_priv->status == STUB_BUSID_ALLOC) { + if (busid_priv->status == STUB_BUSID_ALLOC) busid_priv->status = STUB_BUSID_ADDED; - } else { - busid_priv->status = STUB_BUSID_OTHER; - del_match_busid((char *)udev_busid); - } } #ifdef CONFIG_PM diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index fb46bd62d538..587b9bc10042 100644 --- a/drivers/usb/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c @@ -14,6 +14,7 @@ #define DRIVER_DESC "USB/IP Host Driver" struct kmem_cache *stub_priv_cache; + /* * busid_tables defines matching busids that usbip can grab. A user can change * dynamically what device is locally used and what device is exported to a @@ -169,6 +170,51 @@ static ssize_t match_busid_store(struct device_driver *dev, const char *buf, } static DRIVER_ATTR_RW(match_busid); +static int do_rebind(char *busid, struct bus_id_priv *busid_priv) +{ + int ret; + + /* device_attach() callers should hold parent lock for USB */ + if (busid_priv->udev->dev.parent) + device_lock(busid_priv->udev->dev.parent); + ret = device_attach(&busid_priv->udev->dev); + if (busid_priv->udev->dev.parent) + device_unlock(busid_priv->udev->dev.parent); + if (ret < 0) { + dev_err(&busid_priv->udev->dev, "rebind failed\n"); + return ret; + } + return 0; +} + +static void stub_device_rebind(void) +{ +#if IS_MODULE(CONFIG_USBIP_HOST) + struct bus_id_priv *busid_priv; + int i; + + /* update status to STUB_BUSID_OTHER so probe ignores the device */ + spin_lock(&busid_table_lock); + for (i = 0; i < MAX_BUSID; i++) { + if (busid_table[i].name[0] && + busid_table[i].shutdown_busid) { + busid_priv = &(busid_table[i]); + busid_priv->status = STUB_BUSID_OTHER; + } + } + spin_unlock(&busid_table_lock); + + /* now run rebind */ + for (i = 0; i < MAX_BUSID; i++) { + if (busid_table[i].name[0] && + busid_table[i].shutdown_busid) { + busid_priv = &(busid_table[i]); + do_rebind(busid_table[i].name, busid_priv); + } + } +#endif +} + static ssize_t rebind_store(struct device_driver *dev, const char *buf, size_t count) { @@ -189,16 +235,9 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf, /* mark the device for deletion so probe ignores it during rescan */ bid->status = STUB_BUSID_OTHER; - /* device_attach() callers should hold parent lock for USB */ - if (bid->udev->dev.parent) - device_lock(bid->udev->dev.parent); - ret = device_attach(&bid->udev->dev); - if (bid->udev->dev.parent) - device_unlock(bid->udev->dev.parent); - if (ret < 0) { - dev_err(&bid->udev->dev, "rebind failed\n"); + ret = do_rebind((char *) buf, bid); + if (ret < 0) return ret; - } /* delete device from busid_table */ del_match_busid((char *) buf); @@ -323,6 +362,9 @@ static void __exit usbip_host_exit(void) */ usb_deregister_device_driver(&stub_driver); + /* initiate scan to attach devices */ + stub_device_rebind(); + kmem_cache_destroy(stub_priv_cache); } -- cgit v1.2.3-59-g8ed1b From 22076557b07c12086eeb16b8ce2b0b735f7a27e7 Mon Sep 17 00:00:00 2001 From: "Shuah Khan (Samsung OSG)" Date: Mon, 14 May 2018 20:49:58 -0600 Subject: usbip: usbip_host: fix NULL-ptr deref and use-after-free errors usbip_host updates device status without holding lock from stub probe, disconnect and rebind code paths. When multiple requests to import a device are received, these unprotected code paths step all over each other and drive fails with NULL-ptr deref and use-after-free errors. The driver uses a table lock to protect the busid array for adding and deleting busids to the table. However, the probe, disconnect and rebind paths get the busid table entry and update the status without holding the busid table lock. Add a new finer grain lock to protect the busid entry. This new lock will be held to search and update the busid entry fields from get_busid_idx(), add_match_busid() and del_match_busid(). match_busid_show() does the same to access the busid entry fields. get_busid_priv() changed to return the pointer to the busid entry holding the busid lock. stub_probe(), stub_disconnect() and stub_device_rebind() call put_busid_priv() to release the busid lock before returning. This changes fixes the unprotected code paths eliminating the race conditions in updating the busid entries. Reported-by: Jakub Jirasek Signed-off-by: Shuah Khan (Samsung OSG) Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/stub.h | 2 ++ drivers/usb/usbip/stub_dev.c | 33 +++++++++++++++++++++++---------- drivers/usb/usbip/stub_main.c | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 60 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/usbip/stub.h b/drivers/usb/usbip/stub.h index 14a72357800a..35618ceb2791 100644 --- a/drivers/usb/usbip/stub.h +++ b/drivers/usb/usbip/stub.h @@ -73,6 +73,7 @@ struct bus_id_priv { struct stub_device *sdev; struct usb_device *udev; char shutdown_busid; + spinlock_t busid_lock; }; /* stub_priv is allocated from stub_priv_cache */ @@ -83,6 +84,7 @@ extern struct usb_device_driver stub_driver; /* stub_main.c */ struct bus_id_priv *get_busid_priv(const char *busid); +void put_busid_priv(struct bus_id_priv *bid); int del_match_busid(char *busid); void stub_device_cleanup_urbs(struct stub_device *sdev); diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index 9d0425113c4b..c0d6ff1baa72 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -300,7 +300,7 @@ static int stub_probe(struct usb_device *udev) struct stub_device *sdev = NULL; const char *udev_busid = dev_name(&udev->dev); struct bus_id_priv *busid_priv; - int rc; + int rc = 0; dev_dbg(&udev->dev, "Enter probe\n"); @@ -317,13 +317,15 @@ static int stub_probe(struct usb_device *udev) * other matched drivers by the driver core. * See driver_probe_device() in driver/base/dd.c */ - return -ENODEV; + rc = -ENODEV; + goto call_put_busid_priv; } if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) { dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n", udev_busid); - return -ENODEV; + rc = -ENODEV; + goto call_put_busid_priv; } if (!strcmp(udev->bus->bus_name, "vhci_hcd")) { @@ -331,13 +333,16 @@ static int stub_probe(struct usb_device *udev) "%s is attached on vhci_hcd... skip!\n", udev_busid); - return -ENODEV; + rc = -ENODEV; + goto call_put_busid_priv; } /* ok, this is my device */ sdev = stub_device_alloc(udev); - if (!sdev) - return -ENOMEM; + if (!sdev) { + rc = -ENOMEM; + goto call_put_busid_priv; + } dev_info(&udev->dev, "usbip-host: register new device (bus %u dev %u)\n", @@ -369,7 +374,9 @@ static int stub_probe(struct usb_device *udev) } busid_priv->status = STUB_BUSID_ALLOC; - return 0; + rc = 0; + goto call_put_busid_priv; + err_files: usb_hub_release_port(udev->parent, udev->portnum, (struct usb_dev_state *) udev); @@ -379,6 +386,9 @@ err_port: busid_priv->sdev = NULL; stub_device_free(sdev); + +call_put_busid_priv: + put_busid_priv(busid_priv); return rc; } @@ -417,7 +427,7 @@ static void stub_disconnect(struct usb_device *udev) /* get stub_device */ if (!sdev) { dev_err(&udev->dev, "could not get device"); - return; + goto call_put_busid_priv; } dev_set_drvdata(&udev->dev, NULL); @@ -432,12 +442,12 @@ static void stub_disconnect(struct usb_device *udev) (struct usb_dev_state *) udev); if (rc) { dev_dbg(&udev->dev, "unable to release port\n"); - return; + goto call_put_busid_priv; } /* If usb reset is called from event handler */ if (usbip_in_eh(current)) - return; + goto call_put_busid_priv; /* shutdown the current connection */ shutdown_busid(busid_priv); @@ -450,6 +460,9 @@ static void stub_disconnect(struct usb_device *udev) if (busid_priv->status == STUB_BUSID_ALLOC) busid_priv->status = STUB_BUSID_ADDED; + +call_put_busid_priv: + put_busid_priv(busid_priv); } #ifdef CONFIG_PM diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index 587b9bc10042..41c7b9de2a92 100644 --- a/drivers/usb/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c @@ -26,6 +26,8 @@ static spinlock_t busid_table_lock; static void init_busid_table(void) { + int i; + /* * This also sets the bus_table[i].status to * STUB_BUSID_OTHER, which is 0. @@ -33,6 +35,9 @@ static void init_busid_table(void) memset(busid_table, 0, sizeof(busid_table)); spin_lock_init(&busid_table_lock); + + for (i = 0; i < MAX_BUSID; i++) + spin_lock_init(&busid_table[i].busid_lock); } /* @@ -44,15 +49,20 @@ static int get_busid_idx(const char *busid) int i; int idx = -1; - for (i = 0; i < MAX_BUSID; i++) + for (i = 0; i < MAX_BUSID; i++) { + spin_lock(&busid_table[i].busid_lock); if (busid_table[i].name[0]) if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { idx = i; + spin_unlock(&busid_table[i].busid_lock); break; } + spin_unlock(&busid_table[i].busid_lock); + } return idx; } +/* Returns holding busid_lock. Should call put_busid_priv() to unlock */ struct bus_id_priv *get_busid_priv(const char *busid) { int idx; @@ -60,13 +70,21 @@ struct bus_id_priv *get_busid_priv(const char *busid) spin_lock(&busid_table_lock); idx = get_busid_idx(busid); - if (idx >= 0) + if (idx >= 0) { bid = &(busid_table[idx]); + /* get busid_lock before returning */ + spin_lock(&bid->busid_lock); + } spin_unlock(&busid_table_lock); return bid; } +void put_busid_priv(struct bus_id_priv *bid) +{ + spin_unlock(&bid->busid_lock); +} + static int add_match_busid(char *busid) { int i; @@ -79,15 +97,19 @@ static int add_match_busid(char *busid) goto out; } - for (i = 0; i < MAX_BUSID; i++) + for (i = 0; i < MAX_BUSID; i++) { + spin_lock(&busid_table[i].busid_lock); if (!busid_table[i].name[0]) { strlcpy(busid_table[i].name, busid, BUSID_SIZE); if ((busid_table[i].status != STUB_BUSID_ALLOC) && (busid_table[i].status != STUB_BUSID_REMOV)) busid_table[i].status = STUB_BUSID_ADDED; ret = 0; + spin_unlock(&busid_table[i].busid_lock); break; } + spin_unlock(&busid_table[i].busid_lock); + } out: spin_unlock(&busid_table_lock); @@ -108,6 +130,8 @@ int del_match_busid(char *busid) /* found */ ret = 0; + spin_lock(&busid_table[idx].busid_lock); + if (busid_table[idx].status == STUB_BUSID_OTHER) memset(busid_table[idx].name, 0, BUSID_SIZE); @@ -115,6 +139,7 @@ int del_match_busid(char *busid) (busid_table[idx].status != STUB_BUSID_ADDED)) busid_table[idx].status = STUB_BUSID_REMOV; + spin_unlock(&busid_table[idx].busid_lock); out: spin_unlock(&busid_table_lock); @@ -127,9 +152,12 @@ static ssize_t match_busid_show(struct device_driver *drv, char *buf) char *out = buf; spin_lock(&busid_table_lock); - for (i = 0; i < MAX_BUSID; i++) + for (i = 0; i < MAX_BUSID; i++) { + spin_lock(&busid_table[i].busid_lock); if (busid_table[i].name[0]) out += sprintf(out, "%s ", busid_table[i].name); + spin_unlock(&busid_table[i].busid_lock); + } spin_unlock(&busid_table_lock); out += sprintf(out, "\n"); @@ -204,7 +232,7 @@ static void stub_device_rebind(void) } spin_unlock(&busid_table_lock); - /* now run rebind */ + /* now run rebind - no need to hold locks. driver files are removed */ for (i = 0; i < MAX_BUSID; i++) { if (busid_table[i].name[0] && busid_table[i].shutdown_busid) { @@ -234,6 +262,8 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf, /* mark the device for deletion so probe ignores it during rescan */ bid->status = STUB_BUSID_OTHER; + /* release the busid lock */ + put_busid_priv(bid); ret = do_rebind((char *) buf, bid); if (ret < 0) -- cgit v1.2.3-59-g8ed1b From 72cb0d893343cd33e6ab62cf26f2625d5d3532c9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 9 Apr 2018 13:58:13 -0700 Subject: drm/vc4: Fix leak of the file_priv that stored the perfmon. Signed-off-by: Eric Anholt Fixes: 65101d8c9108 ("drm/vc4: Expose performance counters to userspace") Link: https://patchwork.freedesktop.org/patch/msgid/20180409205813.7077-1-eric@anholt.net Reviewed-by: Boris Brezillon Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/vc4/vc4_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 94b99c90425a..7c95ed5c5cac 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -130,6 +130,7 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file) struct vc4_file *vc4file = file->driver_priv; vc4_perfmon_close_file(vc4file); + kfree(vc4file); } static const struct vm_operations_struct vc4_vm_ops = { -- cgit v1.2.3-59-g8ed1b From 401dca8cbd14fc4b32d93499dcd12a1711a73ecc Mon Sep 17 00:00:00 2001 From: Philippe Bergheaud Date: Mon, 14 May 2018 10:27:35 +0200 Subject: cxl: Set the PBCQ Tunnel BAR register when enabling capi mode Skiboot used to set the default Tunnel BAR register value when capi mode was enabled. This approach was ok for the cxl driver, but prevented other drivers from choosing different values. Skiboot versions > 5.11 will not set the default value any longer. This patch modifies the cxl driver to set/reset the Tunnel BAR register when entering/exiting the cxl mode, with pnv_pci_set_tunnel_bar(). That should work with old skiboot (since we are re-writing the value already set) and new skiboot. mpe: The tunnel support was only merged into Linux recently, in commit d6a90bb83b50 ("powerpc/powernv: Enable tunneled operations") (v4.17-rc1), so with new skiboot kernels between that commit and this will not work correctly. Fixes: d6a90bb83b50 ("powerpc/powernv: Enable tunneled operations") Signed-off-by: Philippe Bergheaud Reviewed-by: Christophe Lombard Acked-by: Frederic Barrat Signed-off-by: Michael Ellerman --- drivers/misc/cxl/pci.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 83f1d08058fc..4eb893284af2 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -1742,6 +1742,10 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev) /* Required for devices using CAPP DMA mode, harmless for others */ pci_set_master(dev); + if (cxl_is_power9()) + if (pnv_pci_set_tunnel_bar(dev, 0x00020000E0000000ull, 1)) + dev_info(&dev->dev, "Tunneled operations unsupported\n"); + if ((rc = pnv_phb_to_cxl_mode(dev, adapter->native->sl_ops->capi_mode))) goto err; @@ -1768,6 +1772,9 @@ static void cxl_deconfigure_adapter(struct cxl *adapter) { struct pci_dev *pdev = to_pci_dev(adapter->dev.parent); + if (cxl_is_power9()) + pnv_pci_set_tunnel_bar(pdev, 0x00020000E0000000ull, 0); + cxl_native_release_psl_err_irq(adapter); cxl_unmap_adapter_regs(adapter); -- cgit v1.2.3-59-g8ed1b From 497a0790e2c604366b9e35dcb41310319e9bca13 Mon Sep 17 00:00:00 2001 From: Philippe Bergheaud Date: Mon, 14 May 2018 10:27:36 +0200 Subject: cxl: Report the tunneled operations status Failure to synchronize the tunneled operations does not prevent the initialization of the cxl card. This patch reports the tunneled operations status via /sys. Signed-off-by: Philippe Bergheaud Signed-off-by: Michael Ellerman --- Documentation/ABI/testing/sysfs-class-cxl | 8 ++++++++ drivers/misc/cxl/cxl.h | 1 + drivers/misc/cxl/pci.c | 7 ++++++- drivers/misc/cxl/sysfs.c | 10 ++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index 640f65e79ef1..8e69345c37cc 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl @@ -244,3 +244,11 @@ Description: read only Returns 1 if the psl timebase register is synchronized with the core timebase register, 0 otherwise. Users: https://github.com/ibm-capi/libcxl + +What: /sys/class/cxl//tunneled_ops_supported +Date: May 2018 +Contact: linuxppc-dev@lists.ozlabs.org +Description: read only + Returns 1 if tunneled operations are supported in capi mode, + 0 otherwise. +Users: https://github.com/ibm-capi/libcxl diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index a4c9c8297a6d..918d4fb742d1 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -717,6 +717,7 @@ struct cxl { bool perst_select_user; bool perst_same_image; bool psl_timebase_synced; + bool tunneled_ops_supported; /* * number of contexts mapped on to this card. Possible values are: diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 4eb893284af2..4d6736f9d463 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -1742,9 +1742,14 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev) /* Required for devices using CAPP DMA mode, harmless for others */ pci_set_master(dev); - if (cxl_is_power9()) + adapter->tunneled_ops_supported = false; + + if (cxl_is_power9()) { if (pnv_pci_set_tunnel_bar(dev, 0x00020000E0000000ull, 1)) dev_info(&dev->dev, "Tunneled operations unsupported\n"); + else + adapter->tunneled_ops_supported = true; + } if ((rc = pnv_phb_to_cxl_mode(dev, adapter->native->sl_ops->capi_mode))) goto err; diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c index 95285b7f636f..4b5a4c5d3c01 100644 --- a/drivers/misc/cxl/sysfs.c +++ b/drivers/misc/cxl/sysfs.c @@ -78,6 +78,15 @@ static ssize_t psl_timebase_synced_show(struct device *device, return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_timebase_synced); } +static ssize_t tunneled_ops_supported_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct cxl *adapter = to_cxl_adapter(device); + + return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->tunneled_ops_supported); +} + static ssize_t reset_adapter_store(struct device *device, struct device_attribute *attr, const char *buf, size_t count) @@ -183,6 +192,7 @@ static struct device_attribute adapter_attrs[] = { __ATTR_RO(base_image), __ATTR_RO(image_loaded), __ATTR_RO(psl_timebase_synced), + __ATTR_RO(tunneled_ops_supported), __ATTR_RW(load_image_on_perst), __ATTR_RW(perst_reloads_same_image), __ATTR(reset, S_IWUSR, NULL, reset_adapter_store), -- cgit v1.2.3-59-g8ed1b From 2e5be528ab0182ad4b42b9feea3b80f85f37179b Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 18 Apr 2018 14:49:08 +0200 Subject: clk: imx6ull: use OSC clock during AXI rate change On i.MX6 ULL using PLL3 seems to cause a freeze when setting the parent to IMX6UL_CLK_PLL3_USB_OTG. This only seems to appear since commit 6f9575e55632 ("clk: imx: Add CLK_IS_CRITICAL flag for busy divider and busy mux"), probably because the clock is now forced to be on. Fixes: 6f9575e55632("clk: imx: Add CLK_IS_CRITICAL flag for busy divider and busy mux") Signed-off-by: Stefan Agner Signed-off-by: Stephen Boyd --- drivers/clk/imx/clk-imx6ul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 114ecbb94ec5..12320118f8de 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -464,7 +464,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000); /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */ - clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]); + clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_OSC]); clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]); clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]); clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]); -- cgit v1.2.3-59-g8ed1b From 9a160601f3fb6ffa196b87d1b5643646be486405 Mon Sep 17 00:00:00 2001 From: Gabriel Fernandez Date: Thu, 3 May 2018 08:40:09 +0200 Subject: clk: stm32: fix: stm32 clock drivers are not compiled by default Clock driver is mandatory if the machine is selected. Then don't use 'bool' and 'depends on' commands, but 'def_bool' with the machine(s). Fixes: da32d3539fca ("clk: stm32: add configuration flags for each of the stm32 drivers") Signed-off-by: Gabriel Fernandez Acked-by: Alexandre TORGUE Signed-off-by: Stephen Boyd --- drivers/clk/Kconfig | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 41492e980ef4..34968a381d0f 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -266,15 +266,13 @@ config COMMON_CLK_STM32MP157 Support for stm32mp157 SoC family clocks config COMMON_CLK_STM32F - bool "Clock driver for stm32f4 and stm32f7 SoC families" - depends on MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746 + def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746) help ---help--- Support for stm32f4 and stm32f7 SoC families clocks config COMMON_CLK_STM32H7 - bool "Clock driver for stm32h7 SoC family" - depends on MACH_STM32H743 + def_bool COMMON_CLK && MACH_STM32H743 help ---help--- Support for stm32h7 SoC family clocks -- cgit v1.2.3-59-g8ed1b From 91ba9f28a3de97761c2b5fd5df5d88421268e507 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Tue, 15 May 2018 15:39:09 +0200 Subject: drm/vmwgfx: Set dmabuf_size when vmw_dmabuf_init is successful SOU primary plane prepare_fb hook depends upon dmabuf_size to pin up BO (and not call a new vmw_dmabuf_init) when a new fb size is same as current fb. This was changed in a recent commit which is causing page_flip to fail on VM with low display memory and multi-mon failure when cycle monitors from secondary display. Cc: # 4.14, 4.16 Fixes: 20fb5a635a0c ("drm/vmwgfx: Unpin the screen object backup buffer when not used") Signed-off-by: Deepak Rawat Reviewed-by: Sinclair Yeh Signed-off-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 648f8127f65a..3d667e903beb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -482,6 +482,8 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, return ret; } + vps->dmabuf_size = size; + /* * TTM already thinks the buffer is pinned, but make sure the * pin_count is upped. -- cgit v1.2.3-59-g8ed1b From b579f924a90f42fa561afd8201514fc216b71949 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Mon, 14 May 2018 09:54:45 -0700 Subject: drm/i915/gen9: Add WaClearHIZ_WM_CHICKEN3 for bxt and glk Factor in clear values wherever required while updating destination min/max. References: HSDES#1604444184 Signed-off-by: Michel Thierry Cc: mesa-dev@lists.freedesktop.org Cc: Mika Kuoppala Cc: Oscar Mateo Reviewed-by: Mika Kuoppala Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20180510200708.18097-1-michel.thierry@intel.com Cc: stable@vger.kernel.org Cc: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20180514165445.9198-1-michel.thierry@intel.com (backported from commit 0c79f9cb77eae28d48a4f9fc1b3341aacbbd260c) Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_engine_cs.c | 4 ++++ 2 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e6a8c0ee7df1..8a69a9275e28 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7326,6 +7326,9 @@ enum { #define SLICE_ECO_CHICKEN0 _MMIO(0x7308) #define PIXEL_MASK_CAMMING_DISABLE (1 << 14) +#define GEN9_WM_CHICKEN3 _MMIO(0x5588) +#define GEN9_FACTOR_IN_CLR_VAL_HIZ (1 << 9) + /* WaCatErrorRejectionIssue */ #define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG _MMIO(0x9030) #define GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB (1<<11) diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 4ba139c27fba..f7c25828d3bb 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1149,6 +1149,10 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK, GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); + /* WaClearHIZ_WM_CHICKEN3:bxt,glk */ + if (IS_GEN9_LP(dev_priv)) + WA_SET_BIT_MASKED(GEN9_WM_CHICKEN3, GEN9_FACTOR_IN_CLR_VAL_HIZ); + /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */ ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG); if (ret) -- cgit v1.2.3-59-g8ed1b From 2b6207291b7b277a5df9d1aab44b56815a292dba Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 16 May 2018 17:00:26 +0300 Subject: drm/dumb-buffers: Integer overflow in drm_mode_create_ioctl() There is a comment here which says that DIV_ROUND_UP() and that's where the problem comes from. Say you pick: args->bpp = UINT_MAX - 7; args->width = 4; args->height = 1; The integer overflow in DIV_ROUND_UP() means "cpp" is UINT_MAX / 8 and because of how we picked args->width that means cpp < UINT_MAX / 4. I've fixed it by preventing the integer overflow in DIV_ROUND_UP(). I removed the check for !cpp because it's not possible after this change. I also changed all the 0xffffffffU references to U32_MAX. Signed-off-by: Dan Carpenter Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180516140026.GA19340@mwanda --- drivers/gpu/drm/drm_dumb_buffers.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c index 39ac15ce4702..9e2ae02f31e0 100644 --- a/drivers/gpu/drm/drm_dumb_buffers.c +++ b/drivers/gpu/drm/drm_dumb_buffers.c @@ -65,12 +65,13 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, return -EINVAL; /* overflow checks for 32bit size calculations */ - /* NOTE: DIV_ROUND_UP() can overflow */ + if (args->bpp > U32_MAX - 8) + return -EINVAL; cpp = DIV_ROUND_UP(args->bpp, 8); - if (!cpp || cpp > 0xffffffffU / args->width) + if (cpp > U32_MAX / args->width) return -EINVAL; stride = cpp * args->width; - if (args->height > 0xffffffffU / stride) + if (args->height > U32_MAX / stride) return -EINVAL; /* test for wrap-around */ -- cgit v1.2.3-59-g8ed1b From ab452c3ce7bacb27ffe2fc0144aecd0c399e1e24 Mon Sep 17 00:00:00 2001 From: Keefe Liu Date: Mon, 14 May 2018 19:38:09 +0800 Subject: ipvlan: call netdevice notifier when master mac address changed When master device's mac has been changed, the commit 32c10bbfe914 ("ipvlan: always use the current L2 addr of the master") makes the IPVlan devices's mac changed also, but it doesn't do related works such as flush the IPVlan devices's arp table. Signed-off-by: Keefe Liu Signed-off-by: David S. Miller --- drivers/net/ipvlan/ipvlan_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 450eec264a5e..4377c26f714d 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -792,8 +792,10 @@ static int ipvlan_device_event(struct notifier_block *unused, break; case NETDEV_CHANGEADDR: - list_for_each_entry(ipvlan, &port->ipvlans, pnode) + list_for_each_entry(ipvlan, &port->ipvlans, pnode) { ether_addr_copy(ipvlan->dev->dev_addr, dev->dev_addr); + call_netdevice_notifiers(NETDEV_CHANGEADDR, ipvlan->dev); + } break; case NETDEV_PRE_TYPE_CHANGE: -- cgit v1.2.3-59-g8ed1b From e1b505a60366399d735312ca38b0a6753a684123 Mon Sep 17 00:00:00 2001 From: Markus Niebel Date: Tue, 15 May 2018 10:18:56 +0200 Subject: net: phy: micrel: add 125MHz reference clock workaround The micrel KSZ9031 phy has a optional clock pin (CLK125_NDO) which can be used as reference clock for the MAC unit. The clock signal must meet the RGMII requirements to ensure the correct data transmission between the MAC and the PHY. The KSZ9031 phy does not fulfill the duty cycle requirement if the phy is configured as slave. For a complete describtion look at the errata sheets: DS80000691D or DS80000692D. The errata sheet recommends to force the phy into master mode whenever there is a 1000Base-T link-up as work around. Only set the "micrel,force-master" property if you use the phy reference clock provided by CLK125_NDO pin as MAC reference clock in your application. Attenation, this workaround is only usable if the link partner can be configured to slave mode for 1000Base-T. Signed-off-by: Markus Niebel [m.felsch@pengutronix.de: fix dt-binding documentation] [m.felsch@pengutronix.de: use already existing result var for read/write] [m.felsch@pengutronix.de: add error handling] [m.felsch@pengutronix.de: add more comments] Signed-off-by: Marco Felsch Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- .../devicetree/bindings/net/micrel-ksz90x1.txt | 7 +++++ drivers/net/phy/micrel.c | 31 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt b/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt index 42a248301615..e22d8cfea687 100644 --- a/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt +++ b/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt @@ -57,6 +57,13 @@ KSZ9031: - txd2-skew-ps : Skew control of TX data 2 pad - txd3-skew-ps : Skew control of TX data 3 pad + - micrel,force-master: + Boolean, force phy to master mode. Only set this option if the phy + reference clock provided at CLK125_NDO pin is used as MAC reference + clock because the clock jitter in slave mode is to high (errata#2). + Attention: The link partner must be configurable as slave otherwise + no link will be established. + Examples: mdio { diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index f41b224a9cdb..ab195f0916d6 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -573,9 +573,40 @@ static int ksz9031_config_init(struct phy_device *phydev) ksz9031_of_load_skew_values(phydev, of_node, MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4, tx_data_skews, 4); + + /* Silicon Errata Sheet (DS80000691D or DS80000692D): + * When the device links in the 1000BASE-T slave mode only, + * the optional 125MHz reference output clock (CLK125_NDO) + * has wide duty cycle variation. + * + * The optional CLK125_NDO clock does not meet the RGMII + * 45/55 percent (min/max) duty cycle requirement and therefore + * cannot be used directly by the MAC side for clocking + * applications that have setup/hold time requirements on + * rising and falling clock edges. + * + * Workaround: + * Force the phy to be the master to receive a stable clock + * which meets the duty cycle requirement. + */ + if (of_property_read_bool(of_node, "micrel,force-master")) { + result = phy_read(phydev, MII_CTRL1000); + if (result < 0) + goto err_force_master; + + /* enable master mode, config & prefer master */ + result |= CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER; + result = phy_write(phydev, MII_CTRL1000, result); + if (result < 0) + goto err_force_master; + } } return ksz9031_center_flp_timing(phydev); + +err_force_master: + phydev_err(phydev, "failed to force the phy to master mode\n"); + return result; } #define KSZ8873MLL_GLOBAL_CONTROL_4 0x06 -- cgit v1.2.3-59-g8ed1b From c171654caa875919be3c533d3518da8be5be966e Mon Sep 17 00:00:00 2001 From: "Shuah Khan (Samsung OSG)" Date: Tue, 15 May 2018 17:57:23 -0600 Subject: usbip: usbip_host: fix bad unlock balance during stub_probe() stub_probe() calls put_busid_priv() in an error path when device isn't found in the busid_table. Fix it by making put_busid_priv() safe to be called with null struct bus_id_priv pointer. This problem happens when "usbip bind" is run without loading usbip_host driver and then running modprobe. The first failed bind attempt unbinds the device from the original driver and when usbip_host is modprobed, stub_probe() runs and doesn't find the device in its busid table and calls put_busid_priv(0 with null bus_id_priv pointer. usbip-host 3-10.2: 3-10.2 is not in match_busid table... skip! [ 367.359679] ===================================== [ 367.359681] WARNING: bad unlock balance detected! [ 367.359683] 4.17.0-rc4+ #5 Not tainted [ 367.359685] ------------------------------------- [ 367.359688] modprobe/2768 is trying to release lock ( [ 367.359689] ================================================================== [ 367.359696] BUG: KASAN: null-ptr-deref in print_unlock_imbalance_bug+0x99/0x110 [ 367.359699] Read of size 8 at addr 0000000000000058 by task modprobe/2768 [ 367.359705] CPU: 4 PID: 2768 Comm: modprobe Not tainted 4.17.0-rc4+ #5 Fixes: 22076557b07c ("usbip: usbip_host: fix NULL-ptr deref and use-after-free errors") in usb-linus Signed-off-by: Shuah Khan (Samsung OSG) Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/stub_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index 41c7b9de2a92..bf8a5feb0ee9 100644 --- a/drivers/usb/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c @@ -82,7 +82,8 @@ struct bus_id_priv *get_busid_priv(const char *busid) void put_busid_priv(struct bus_id_priv *bid) { - spin_unlock(&bid->busid_lock); + if (bid) + spin_unlock(&bid->busid_lock); } static int add_match_busid(char *busid) -- cgit v1.2.3-59-g8ed1b From 43a5e00f38fe8933a1c716bfe5b30e97f749d94b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 15 May 2018 16:01:23 -0700 Subject: net: dsa: bcm_sf2: Fix RX_CLS_LOC_ANY overwrite for last rule When we let the kernel pick up a rule location with RX_CLS_LOC_ANY, we would be able to overwrite the last rules because of a number of issues. The IPv4 code path would not be checking that rule_index is within bounds, and it would also only be allowed to pick up rules from range 0..126 instead of the full 0..127 range. This would lead us to allow overwriting the last rule when we let the kernel pick-up the location. Fixes: 3306145866b6 ("net: dsa: bcm_sf2: Move IPv4 CFP processing to specific functions") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/dsa/bcm_sf2_cfp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c index 23b45da784cb..9e04786e3139 100644 --- a/drivers/net/dsa/bcm_sf2_cfp.c +++ b/drivers/net/dsa/bcm_sf2_cfp.c @@ -354,10 +354,13 @@ static int bcm_sf2_cfp_ipv4_rule_set(struct bcm_sf2_priv *priv, int port, /* Locate the first rule available */ if (fs->location == RX_CLS_LOC_ANY) rule_index = find_first_zero_bit(priv->cfp.used, - bcm_sf2_cfp_rule_size(priv)); + priv->num_cfp_rules); else rule_index = fs->location; + if (rule_index > bcm_sf2_cfp_rule_size(priv)) + return -ENOSPC; + layout = &udf_tcpip4_layout; /* We only use one UDF slice for now */ slice_num = bcm_sf2_get_slice_number(layout, 0); -- cgit v1.2.3-59-g8ed1b From 6c05561c541843b2bec2189f680bed6d20afc25b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 15 May 2018 16:01:24 -0700 Subject: net: dsa: bcm_sf2: Fix IPv6 rules and chain ID We had several issues that would make the programming of IPv6 rules both inconsistent and error prone: - the chain ID that we would be asking the hardware to put in the packet's Broadcom tag would be off by one, it would return one of the two indexes, but not the one user-space specified - when an user specified a particular location to insert a CFP rule at, we would not be returning the same index, which would be confusing if nothing else - finally, like IPv4, it would be possible to overflow the last entry by re-programming it Fix this by swapping the usage of rule_index[0] and rule_index[1] where relevant in order to return a consistent and correct user-space experience. Fixes: ba0696c22e7c ("net: dsa: bcm_sf2: Add support for IPv6 CFP rules") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/dsa/bcm_sf2_cfp.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c index 9e04786e3139..6fd0f8a12cc2 100644 --- a/drivers/net/dsa/bcm_sf2_cfp.c +++ b/drivers/net/dsa/bcm_sf2_cfp.c @@ -565,19 +565,21 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port, * first half because the HW search is by incrementing addresses. */ if (fs->location == RX_CLS_LOC_ANY) - rule_index[0] = find_first_zero_bit(priv->cfp.used, - bcm_sf2_cfp_rule_size(priv)); + rule_index[1] = find_first_zero_bit(priv->cfp.used, + priv->num_cfp_rules); else - rule_index[0] = fs->location; + rule_index[1] = fs->location; + if (rule_index[1] > bcm_sf2_cfp_rule_size(priv)) + return -ENOSPC; /* Flag it as used (cleared on error path) such that we can immediately * obtain a second one to chain from. */ - set_bit(rule_index[0], priv->cfp.used); + set_bit(rule_index[1], priv->cfp.used); - rule_index[1] = find_first_zero_bit(priv->cfp.used, - bcm_sf2_cfp_rule_size(priv)); - if (rule_index[1] > bcm_sf2_cfp_rule_size(priv)) { + rule_index[0] = find_first_zero_bit(priv->cfp.used, + priv->num_cfp_rules); + if (rule_index[0] > bcm_sf2_cfp_rule_size(priv)) { ret = -ENOSPC; goto out_err; } @@ -715,14 +717,14 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port, /* Flag the second half rule as being used now, return it as the * location, and flag it as unique while dumping rules */ - set_bit(rule_index[1], priv->cfp.used); + set_bit(rule_index[0], priv->cfp.used); set_bit(rule_index[1], priv->cfp.unique); fs->location = rule_index[1]; return ret; out_err: - clear_bit(rule_index[0], priv->cfp.used); + clear_bit(rule_index[1], priv->cfp.used); return ret; } -- cgit v1.2.3-59-g8ed1b From 1942adf64214df370350aa46954ba27654456f68 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 15 May 2018 16:01:25 -0700 Subject: net: dsa: bcm_sf2: Fix IPv6 rule half deletion It was possible to delete only one half of an IPv6, which would leave the second half still programmed and possibly in use. Instead of checking for the unused bitmap, we need to check the unique bitmap, and refuse any deletion that does not match that criteria. We also need to move that check from bcm_sf2_cfp_rule_del_one() into its caller: bcm_sf2_cfp_rule_del() otherwise we would not be able to delete second halves anymore that would not pass the first test. Fixes: ba0696c22e7c ("net: dsa: bcm_sf2: Add support for IPv6 CFP rules") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/dsa/bcm_sf2_cfp.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c index 6fd0f8a12cc2..b89acaee12d4 100644 --- a/drivers/net/dsa/bcm_sf2_cfp.c +++ b/drivers/net/dsa/bcm_sf2_cfp.c @@ -790,10 +790,6 @@ static int bcm_sf2_cfp_rule_del_one(struct bcm_sf2_priv *priv, int port, int ret; u32 reg; - /* Refuse deletion of unused rules, and the default reserved rule */ - if (!test_bit(loc, priv->cfp.used) || loc == 0) - return -EINVAL; - /* Indicate which rule we want to read */ bcm_sf2_cfp_rule_addr_set(priv, loc); @@ -831,6 +827,13 @@ static int bcm_sf2_cfp_rule_del(struct bcm_sf2_priv *priv, int port, u32 next_loc = 0; int ret; + /* Refuse deleting unused rules, and those that are not unique since + * that could leave IPv6 rules with one of the chained rule in the + * table. + */ + if (!test_bit(loc, priv->cfp.unique) || loc == 0) + return -EINVAL; + ret = bcm_sf2_cfp_rule_del_one(priv, port, loc, &next_loc); if (ret) return ret; -- cgit v1.2.3-59-g8ed1b From e49ac9679eeb30abeb462cb459cc3ea8c81fbd1f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 16 May 2018 11:18:01 +0200 Subject: net: 8390: ne: Fix accidentally removed RBTX4927 support The configuration settings for RBTX4927 were accidentally removed, leading to a silently broken network interface. Re-add the missing settings to fix this. Fixes: 8eb97ff5a4ec941d ("net: 8390: remove m32r specific bits") Signed-off-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ethernet/8390/ne.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c index ac99d089ac72..1c97e39b478e 100644 --- a/drivers/net/ethernet/8390/ne.c +++ b/drivers/net/ethernet/8390/ne.c @@ -164,7 +164,9 @@ bad_clone_list[] __initdata = { #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ -#if defined(CONFIG_ATARI) /* 8-bit mode on Atari, normal on Q40 */ +#if defined(CONFIG_MACH_TX49XX) +# define DCR_VAL 0x48 /* 8-bit mode */ +#elif defined(CONFIG_ATARI) /* 8-bit mode on Atari, normal on Q40 */ # define DCR_VAL (MACH_IS_ATARI ? 0x48 : 0x49) #else # define DCR_VAL 0x49 -- cgit v1.2.3-59-g8ed1b From f9bcd60274a565751abef622f9018badd01a17c8 Mon Sep 17 00:00:00 2001 From: Michal Kalderon Date: Wed, 16 May 2018 14:44:38 +0300 Subject: qed: LL2 flush isles when connection is closed Driver should free all pending isles once it gets a FLUSH cqe from FW. Part of iSCSI out of order flow. Fixes: 1d6cff4fca4366 ("qed: Add iSCSI out of order packet handling") Signed-off-by: Ariel Elior Signed-off-by: Michal Kalderon Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_ll2.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c index 38502815d681..b5918bdabf23 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c @@ -591,6 +591,27 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle) } } +static bool +qed_ll2_lb_rxq_handler_slowpath(struct qed_hwfn *p_hwfn, + struct core_rx_slow_path_cqe *p_cqe) +{ + struct ooo_opaque *iscsi_ooo; + u32 cid; + + if (p_cqe->ramrod_cmd_id != CORE_RAMROD_RX_QUEUE_FLUSH) + return false; + + iscsi_ooo = (struct ooo_opaque *)&p_cqe->opaque_data; + if (iscsi_ooo->ooo_opcode != TCP_EVENT_DELETE_ISLES) + return false; + + /* Need to make a flush */ + cid = le32_to_cpu(iscsi_ooo->cid); + qed_ooo_release_connection_isles(p_hwfn, p_hwfn->p_ooo_info, cid); + + return true; +} + static int qed_ll2_lb_rxq_handler(struct qed_hwfn *p_hwfn, struct qed_ll2_info *p_ll2_conn) { @@ -617,6 +638,11 @@ static int qed_ll2_lb_rxq_handler(struct qed_hwfn *p_hwfn, cq_old_idx = qed_chain_get_cons_idx(&p_rx->rcq_chain); cqe_type = cqe->rx_cqe_sp.type; + if (cqe_type == CORE_RX_CQE_TYPE_SLOW_PATH) + if (qed_ll2_lb_rxq_handler_slowpath(p_hwfn, + &cqe->rx_cqe_sp)) + continue; + if (cqe_type != CORE_RX_CQE_TYPE_REGULAR) { DP_NOTICE(p_hwfn, "Got a non-regular LB LL2 completion [type 0x%02x]\n", -- cgit v1.2.3-59-g8ed1b From ffd2c0d12752a69e480366031ec7a7d723dd2510 Mon Sep 17 00:00:00 2001 From: Michal Kalderon Date: Wed, 16 May 2018 14:44:39 +0300 Subject: qed: Fix possibility of list corruption during rmmod flows The ll2 flows of flushing the txq/rxq need to be synchronized with the regular fp processing. Caused list corruption during load/unload stress tests. Fixes: 0a7fb11c23c0f ("qed: Add Light L2 support") Signed-off-by: Ariel Elior Signed-off-by: Michal Kalderon Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_ll2.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c index b5918bdabf23..851561fb8224 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c @@ -292,6 +292,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle) struct qed_ll2_tx_packet *p_pkt = NULL; struct qed_ll2_info *p_ll2_conn; struct qed_ll2_tx_queue *p_tx; + unsigned long flags = 0; dma_addr_t tx_frag; p_ll2_conn = qed_ll2_handle_sanity_inactive(p_hwfn, connection_handle); @@ -300,6 +301,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle) p_tx = &p_ll2_conn->tx_queue; + spin_lock_irqsave(&p_tx->lock, flags); while (!list_empty(&p_tx->active_descq)) { p_pkt = list_first_entry(&p_tx->active_descq, struct qed_ll2_tx_packet, list_entry); @@ -309,6 +311,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle) list_del(&p_pkt->list_entry); b_last_packet = list_empty(&p_tx->active_descq); list_add_tail(&p_pkt->list_entry, &p_tx->free_descq); + spin_unlock_irqrestore(&p_tx->lock, flags); if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_OOO) { struct qed_ooo_buffer *p_buffer; @@ -328,7 +331,9 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle) b_last_frag, b_last_packet); } + spin_lock_irqsave(&p_tx->lock, flags); } + spin_unlock_irqrestore(&p_tx->lock, flags); } static int qed_ll2_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) @@ -556,6 +561,7 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle) struct qed_ll2_info *p_ll2_conn = NULL; struct qed_ll2_rx_packet *p_pkt = NULL; struct qed_ll2_rx_queue *p_rx; + unsigned long flags = 0; p_ll2_conn = qed_ll2_handle_sanity_inactive(p_hwfn, connection_handle); if (!p_ll2_conn) @@ -563,13 +569,14 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle) p_rx = &p_ll2_conn->rx_queue; + spin_lock_irqsave(&p_rx->lock, flags); while (!list_empty(&p_rx->active_descq)) { p_pkt = list_first_entry(&p_rx->active_descq, struct qed_ll2_rx_packet, list_entry); if (!p_pkt) break; - list_move_tail(&p_pkt->list_entry, &p_rx->free_descq); + spin_unlock_irqrestore(&p_rx->lock, flags); if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_OOO) { struct qed_ooo_buffer *p_buffer; @@ -588,7 +595,9 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle) cookie, rx_buf_addr, b_last); } + spin_lock_irqsave(&p_rx->lock, flags); } + spin_unlock_irqrestore(&p_rx->lock, flags); } static bool -- cgit v1.2.3-59-g8ed1b From 490068deaef0c76e47bf89c457de899b7d3995c7 Mon Sep 17 00:00:00 2001 From: Michal Kalderon Date: Wed, 16 May 2018 14:44:40 +0300 Subject: qed: Fix LL2 race during connection terminate Stress on qedi/qedr load unload lead to list_del corruption. This is due to ll2 connection terminate freeing resources without verifying that no more ll2 processing will occur. This patch unregisters the ll2 status block before terminating the connection to assure this race does not occur. Fixes: 1d6cff4fca4366 ("qed: Add iSCSI out of order packet handling") Signed-off-by: Ariel Elior Signed-off-by: Michal Kalderon Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_ll2.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c index 851561fb8224..468c59d2e491 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c @@ -829,6 +829,9 @@ static int qed_ll2_lb_rxq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) struct qed_ll2_info *p_ll2_conn = (struct qed_ll2_info *)p_cookie; int rc; + if (!QED_LL2_RX_REGISTERED(p_ll2_conn)) + return 0; + rc = qed_ll2_lb_rxq_handler(p_hwfn, p_ll2_conn); if (rc) return rc; @@ -849,6 +852,9 @@ static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) u16 new_idx = 0, num_bds = 0; int rc; + if (!QED_LL2_TX_REGISTERED(p_ll2_conn)) + return 0; + new_idx = le16_to_cpu(*p_tx->p_fw_cons); num_bds = ((s16)new_idx - (s16)p_tx->bds_idx); @@ -1902,17 +1908,25 @@ int qed_ll2_terminate_connection(void *cxt, u8 connection_handle) /* Stop Tx & Rx of connection, if needed */ if (QED_LL2_TX_REGISTERED(p_ll2_conn)) { + p_ll2_conn->tx_queue.b_cb_registred = false; + smp_wmb(); /* Make sure this is seen by ll2_lb_rxq_completion */ rc = qed_sp_ll2_tx_queue_stop(p_hwfn, p_ll2_conn); if (rc) goto out; + qed_ll2_txq_flush(p_hwfn, connection_handle); + qed_int_unregister_cb(p_hwfn, p_ll2_conn->tx_queue.tx_sb_index); } if (QED_LL2_RX_REGISTERED(p_ll2_conn)) { + p_ll2_conn->rx_queue.b_cb_registred = false; + smp_wmb(); /* Make sure this is seen by ll2_lb_rxq_completion */ rc = qed_sp_ll2_rx_queue_stop(p_hwfn, p_ll2_conn); if (rc) goto out; + qed_ll2_rxq_flush(p_hwfn, connection_handle); + qed_int_unregister_cb(p_hwfn, p_ll2_conn->rx_queue.rx_sb_index); } if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_OOO) @@ -1960,16 +1974,6 @@ void qed_ll2_release_connection(void *cxt, u8 connection_handle) if (!p_ll2_conn) return; - if (QED_LL2_RX_REGISTERED(p_ll2_conn)) { - p_ll2_conn->rx_queue.b_cb_registred = false; - qed_int_unregister_cb(p_hwfn, p_ll2_conn->rx_queue.rx_sb_index); - } - - if (QED_LL2_TX_REGISTERED(p_ll2_conn)) { - p_ll2_conn->tx_queue.b_cb_registred = false; - qed_int_unregister_cb(p_hwfn, p_ll2_conn->tx_queue.tx_sb_index); - } - kfree(p_ll2_conn->tx_queue.descq_mem); qed_chain_free(p_hwfn->cdev, &p_ll2_conn->tx_queue.txq_chain); -- cgit v1.2.3-59-g8ed1b From 7063efd33bb15abc0160347f89eb5aba6b7d000e Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Wed, 16 May 2018 20:39:33 +0800 Subject: tuntap: fix use after free during release After commit b196d88aba8a ("tun: fix use after free for ptr_ring") we need clean up tx ring during release(). But unfortunately, it tries to do the cleanup blindly after socket were destroyed which will lead another use-after-free. Fix this by doing the cleanup before dropping the last reference of the socket in __tun_detach(). Reported-by: Andrei Vagin Acked-by: Andrei Vagin Fixes: b196d88aba8a ("tun: fix use after free for ptr_ring") Signed-off-by: Jason Wang Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 9fbbb328b95b..d45ac37e1287 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -729,6 +729,7 @@ static void __tun_detach(struct tun_file *tfile, bool clean) } if (tun) xdp_rxq_info_unreg(&tfile->xdp_rxq); + ptr_ring_cleanup(&tfile->tx_ring, tun_ptr_free); sock_put(&tfile->sk); } } @@ -3245,7 +3246,6 @@ static int tun_chr_close(struct inode *inode, struct file *file) struct tun_file *tfile = file->private_data; tun_detach(tfile, true); - ptr_ring_cleanup(&tfile->tx_ring, tun_ptr_free); return 0; } -- cgit v1.2.3-59-g8ed1b From dbad41e7bb5f4b9949ff5ea1d76c20711f326308 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 17 May 2018 10:42:32 +0100 Subject: dmaengine: qcom: bam_dma: check if the runtime pm enabled Disabling pm runtime at probe is not sufficient to get BAM working on remotely controller instances. pm_runtime_get_sync() would return -EACCES in such cases. So check if runtime pm is enabled before returning error from bam functions. Fixes: 5b4a68952a89 ("dmaengine: qcom: bam_dma: disable runtime pm on remote controlled") Signed-off-by: Srinivas Kandagatla Signed-off-by: Vinod Koul --- drivers/dma/qcom/bam_dma.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index d29275b97e84..4a828c18099a 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -524,6 +524,14 @@ static int bam_alloc_chan(struct dma_chan *chan) return 0; } +static int bam_pm_runtime_get_sync(struct device *dev) +{ + if (pm_runtime_enabled(dev)) + return pm_runtime_get_sync(dev); + + return 0; +} + /** * bam_free_chan - Frees dma resources associated with specific channel * @chan: specified channel @@ -539,7 +547,7 @@ static void bam_free_chan(struct dma_chan *chan) unsigned long flags; int ret; - ret = pm_runtime_get_sync(bdev->dev); + ret = bam_pm_runtime_get_sync(bdev->dev); if (ret < 0) return; @@ -720,7 +728,7 @@ static int bam_pause(struct dma_chan *chan) unsigned long flag; int ret; - ret = pm_runtime_get_sync(bdev->dev); + ret = bam_pm_runtime_get_sync(bdev->dev); if (ret < 0) return ret; @@ -746,7 +754,7 @@ static int bam_resume(struct dma_chan *chan) unsigned long flag; int ret; - ret = pm_runtime_get_sync(bdev->dev); + ret = bam_pm_runtime_get_sync(bdev->dev); if (ret < 0) return ret; @@ -852,7 +860,7 @@ static irqreturn_t bam_dma_irq(int irq, void *data) if (srcs & P_IRQ) tasklet_schedule(&bdev->task); - ret = pm_runtime_get_sync(bdev->dev); + ret = bam_pm_runtime_get_sync(bdev->dev); if (ret < 0) return ret; @@ -969,7 +977,7 @@ static void bam_start_dma(struct bam_chan *bchan) if (!vd) return; - ret = pm_runtime_get_sync(bdev->dev); + ret = bam_pm_runtime_get_sync(bdev->dev); if (ret < 0) return; -- cgit v1.2.3-59-g8ed1b From 1c1a2ee1b53b006754073eefc65d2b2cedb5264b Mon Sep 17 00:00:00 2001 From: Coly Li Date: Thu, 17 May 2018 23:33:26 +0800 Subject: bcache: return 0 from bch_debug_init() if CONFIG_DEBUG_FS=n Commit 539d39eb2708 ("bcache: fix wrong return value in bch_debug_init()") returns the return value of debugfs_create_dir() to bcache_init(). When CONFIG_DEBUG_FS=n, bch_debug_init() always returns 1 and makes bcache_init() failedi. This patch makes bch_debug_init() always returns 0 if CONFIG_DEBUG_FS=n, so bcache can continue to work for the kernels which don't have debugfs enanbled. Changelog: v4: Add Acked-by from Kent Overstreet. v3: Use IS_ENABLED(CONFIG_DEBUG_FS) to replace #ifdef DEBUG_FS. v2: Remove a warning information v1: Initial version. Fixes: Commit 539d39eb2708 ("bcache: fix wrong return value in bch_debug_init()") Cc: stable@vger.kernel.org Signed-off-by: Coly Li Reported-by: Massimo B. Reported-by: Kai Krakow Tested-by: Kai Krakow Acked-by: Kent Overstreet Signed-off-by: Jens Axboe --- drivers/md/bcache/debug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c index 4e63c6f6c04d..d030ce3025a6 100644 --- a/drivers/md/bcache/debug.c +++ b/drivers/md/bcache/debug.c @@ -250,7 +250,9 @@ void bch_debug_exit(void) int __init bch_debug_init(struct kobject *kobj) { - bcache_debug = debugfs_create_dir("bcache", NULL); + if (!IS_ENABLED(CONFIG_DEBUG_FS)) + return 0; + bcache_debug = debugfs_create_dir("bcache", NULL); return IS_ERR_OR_NULL(bcache_debug); } -- cgit v1.2.3-59-g8ed1b From 4cf2ddf3e329d4ec1e3edda3465a202b5665be0e Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Wed, 16 May 2018 15:49:03 -0500 Subject: ibmvnic: Free coherent DMA memory if FW map failed If the firmware map fails for whatever reason, remember to free up the memory after. Signed-off-by: Thomas Falcon Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 6e8d6a6f6aaf..9e08917cda1f 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -192,6 +192,7 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter, if (adapter->fw_done_rc) { dev_err(dev, "Couldn't map long term buffer,rc = %d\n", adapter->fw_done_rc); + dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); return -1; } return 0; -- cgit v1.2.3-59-g8ed1b From 134bbe7f21f4455c8be64f945b8b67094f768de0 Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Wed, 16 May 2018 15:49:04 -0500 Subject: ibmvnic: Fix non-fatal firmware error reset It is not necessary to disable interrupt lines here during a reset to handle a non-fatal firmware error. Move that call within the code block that handles the other cases that do require interrupts to be disabled and re-enabled. Signed-off-by: Thomas Falcon Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 9e08917cda1f..1b9c22f28fbf 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1822,9 +1822,8 @@ static int do_reset(struct ibmvnic_adapter *adapter, if (rc) return rc; } + ibmvnic_disable_irqs(adapter); } - - ibmvnic_disable_irqs(adapter); adapter->state = VNIC_CLOSED; if (reset_state == VNIC_CLOSED) -- cgit v1.2.3-59-g8ed1b From 0718421389da3d4352f4538449e83316fbed4389 Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Wed, 16 May 2018 15:49:05 -0500 Subject: ibmvnic: Fix statistics buffers memory leak Move initialization of statistics buffers from ibmvnic_init function into ibmvnic_probe. In the current state, ibmvnic_init will be called again during a device reset, resulting in the allocation of new buffers without freeing the old ones. Signed-off-by: Thomas Falcon Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 1b9c22f28fbf..4bb4646a5f92 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -4586,14 +4586,6 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter) release_crq_queue(adapter); } - rc = init_stats_buffers(adapter); - if (rc) - return rc; - - rc = init_stats_token(adapter); - if (rc) - return rc; - return rc; } @@ -4662,13 +4654,21 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) goto ibmvnic_init_fail; } while (rc == EAGAIN); + rc = init_stats_buffers(adapter); + if (rc) + goto ibmvnic_init_fail; + + rc = init_stats_token(adapter); + if (rc) + goto ibmvnic_stats_fail; + netdev->mtu = adapter->req_mtu - ETH_HLEN; netdev->min_mtu = adapter->min_mtu - ETH_HLEN; netdev->max_mtu = adapter->max_mtu - ETH_HLEN; rc = device_create_file(&dev->dev, &dev_attr_failover); if (rc) - goto ibmvnic_init_fail; + goto ibmvnic_dev_file_err; netif_carrier_off(netdev); rc = register_netdev(netdev); @@ -4687,6 +4687,12 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) ibmvnic_register_fail: device_remove_file(&dev->dev, &dev_attr_failover); +ibmvnic_dev_file_err: + release_stats_token(adapter); + +ibmvnic_stats_fail: + release_stats_buffers(adapter); + ibmvnic_init_fail: release_sub_crqs(adapter, 1); release_crq_queue(adapter); -- cgit v1.2.3-59-g8ed1b From 8a922814ccfed70d35a725f47c0bf12b50fd223c Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 18 May 2018 16:16:34 +0200 Subject: parisc: Move ccio_cujo20_fixup() into init section ccio_cujo20_fixup() is called by dino_probe() only, which is in init section already. Signed-off-by: Helge Deller --- drivers/parisc/ccio-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 126cf19e869b..297599fcbc32 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -1195,7 +1195,7 @@ void * ccio_get_iommu(const struct parisc_device *dev) * to/from certain pages. To avoid this happening, we mark these pages * as `used', and ensure that nothing will try to allocate from them. */ -void ccio_cujo20_fixup(struct parisc_device *cujo, u32 iovp) +void __init ccio_cujo20_fixup(struct parisc_device *cujo, u32 iovp) { unsigned int idx; struct parisc_device *dev = parisc_parent(cujo); -- cgit v1.2.3-59-g8ed1b From b16a960ddbf0d4fd6aaabee42d7ec4c4c3ec836d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 18 May 2018 12:52:51 +0200 Subject: sh_eth: Change platform check to CONFIG_ARCH_RENESAS Since commit 9b5ba0df4ea4f940 ("ARM: shmobile: Introduce ARCH_RENESAS") is CONFIG_ARCH_RENESAS a more appropriate platform check than the legacy CONFIG_ARCH_SHMOBILE, hence use the former. Renesas SuperH SH-Mobile SoCs are still covered by the CONFIG_CPU_SH4 check. This will allow to drop ARCH_SHMOBILE on ARM and ARM64 in the near future. Signed-off-by: Geert Uytterhoeven Acked-by: Arnd Bergmann Acked-by: Sergei Shtylyov Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index a5b792ce2ae7..1bf930d4a1e5 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -163,7 +163,7 @@ enum { }; /* Driver's parameters */ -#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) +#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_RENESAS) #define SH_ETH_RX_ALIGN 32 #else #define SH_ETH_RX_ALIGN 2 -- cgit v1.2.3-59-g8ed1b From d775f26b295a0a303f7a73d7da46e04296484fe7 Mon Sep 17 00:00:00 2001 From: Rahul Lakkireddy Date: Fri, 18 May 2018 19:13:37 +0530 Subject: cxgb4: fix offset in collecting TX rate limit info Correct the indirect register offsets in collecting TX rate limit info in UP CIM logs. Also, T5 doesn't support these indirect register offsets, so remove them from collection logic. Fixes: be6e36d916b1 ("cxgb4: collect TX rate limit info in UP CIM logs") Signed-off-by: Rahul Lakkireddy Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h | 28 ++++++++--------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h b/drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h index b57acb8dc35b..dc25066c59a1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h @@ -419,15 +419,15 @@ static const u32 t6_up_cim_reg_array[][IREG_NUM_ELEM + 1] = { {0x7b50, 0x7b54, 0x280, 0x20, 0}, /* up_cim_280_to_2fc */ {0x7b50, 0x7b54, 0x300, 0x20, 0}, /* up_cim_300_to_37c */ {0x7b50, 0x7b54, 0x380, 0x14, 0}, /* up_cim_380_to_3cc */ - {0x7b50, 0x7b54, 0x2900, 0x4, 0x4}, /* up_cim_2900_to_3d40 */ - {0x7b50, 0x7b54, 0x2904, 0x4, 0x4}, /* up_cim_2904_to_3d44 */ - {0x7b50, 0x7b54, 0x2908, 0x4, 0x4}, /* up_cim_2908_to_3d48 */ - {0x7b50, 0x7b54, 0x2910, 0x4, 0x4}, /* up_cim_2910_to_3d4c */ - {0x7b50, 0x7b54, 0x2914, 0x4, 0x4}, /* up_cim_2914_to_3d50 */ - {0x7b50, 0x7b54, 0x2920, 0x10, 0x10}, /* up_cim_2920_to_2a10 */ - {0x7b50, 0x7b54, 0x2924, 0x10, 0x10}, /* up_cim_2924_to_2a14 */ - {0x7b50, 0x7b54, 0x2928, 0x10, 0x10}, /* up_cim_2928_to_2a18 */ - {0x7b50, 0x7b54, 0x292c, 0x10, 0x10}, /* up_cim_292c_to_2a1c */ + {0x7b50, 0x7b54, 0x4900, 0x4, 0x4}, /* up_cim_4900_to_4c60 */ + {0x7b50, 0x7b54, 0x4904, 0x4, 0x4}, /* up_cim_4904_to_4c64 */ + {0x7b50, 0x7b54, 0x4908, 0x4, 0x4}, /* up_cim_4908_to_4c68 */ + {0x7b50, 0x7b54, 0x4910, 0x4, 0x4}, /* up_cim_4910_to_4c70 */ + {0x7b50, 0x7b54, 0x4914, 0x4, 0x4}, /* up_cim_4914_to_4c74 */ + {0x7b50, 0x7b54, 0x4920, 0x10, 0x10}, /* up_cim_4920_to_4a10 */ + {0x7b50, 0x7b54, 0x4924, 0x10, 0x10}, /* up_cim_4924_to_4a14 */ + {0x7b50, 0x7b54, 0x4928, 0x10, 0x10}, /* up_cim_4928_to_4a18 */ + {0x7b50, 0x7b54, 0x492c, 0x10, 0x10}, /* up_cim_492c_to_4a1c */ }; static const u32 t5_up_cim_reg_array[][IREG_NUM_ELEM + 1] = { @@ -444,16 +444,6 @@ static const u32 t5_up_cim_reg_array[][IREG_NUM_ELEM + 1] = { {0x7b50, 0x7b54, 0x280, 0x20, 0}, /* up_cim_280_to_2fc */ {0x7b50, 0x7b54, 0x300, 0x20, 0}, /* up_cim_300_to_37c */ {0x7b50, 0x7b54, 0x380, 0x14, 0}, /* up_cim_380_to_3cc */ - {0x7b50, 0x7b54, 0x2900, 0x4, 0x4}, /* up_cim_2900_to_3d40 */ - {0x7b50, 0x7b54, 0x2904, 0x4, 0x4}, /* up_cim_2904_to_3d44 */ - {0x7b50, 0x7b54, 0x2908, 0x4, 0x4}, /* up_cim_2908_to_3d48 */ - {0x7b50, 0x7b54, 0x2910, 0x4, 0x4}, /* up_cim_2910_to_3d4c */ - {0x7b50, 0x7b54, 0x2914, 0x4, 0x4}, /* up_cim_2914_to_3d50 */ - {0x7b50, 0x7b54, 0x2918, 0x4, 0x4}, /* up_cim_2918_to_3d54 */ - {0x7b50, 0x7b54, 0x291c, 0x4, 0x4}, /* up_cim_291c_to_3d58 */ - {0x7b50, 0x7b54, 0x2924, 0x10, 0x10}, /* up_cim_2924_to_2914 */ - {0x7b50, 0x7b54, 0x2928, 0x10, 0x10}, /* up_cim_2928_to_2a18 */ - {0x7b50, 0x7b54, 0x292c, 0x10, 0x10}, /* up_cim_292c_to_2a1c */ }; static const u32 t6_hma_ireg_array[][IREG_NUM_ELEM] = { -- cgit v1.2.3-59-g8ed1b From 54940fa60ad3728c592f62dadb558165495a6938 Mon Sep 17 00:00:00 2001 From: Darren Hart Date: Sat, 12 May 2018 12:10:07 -0700 Subject: platform/x86: DELL_WMI use depends on instead of select for DELL_SMBIOS If DELL_WMI "select"s DELL_SMBIOS, the DELL_SMBIOS dependencies are ignored and it is still possible to end up with unmet direct dependencies. Change the select to a depends on. Tested-by: Randy Dunlap Signed-off-by: Darren Hart (VMware) --- drivers/platform/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index bc309c5327ff..566644bb496a 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -168,8 +168,8 @@ config DELL_WMI depends on DMI depends on INPUT depends on ACPI_VIDEO || ACPI_VIDEO = n + depends on DELL_SMBIOS select DELL_WMI_DESCRIPTOR - select DELL_SMBIOS select INPUT_SPARSEKMAP ---help--- Say Y here if you want to support WMI-based hotkeys on Dell laptops. -- cgit v1.2.3-59-g8ed1b From 4f74d72aa7067e75af92fbab077e6d7d0210be66 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Fri, 18 May 2018 16:08:41 +0200 Subject: efi/libstub/arm64: Handle randomized TEXT_OFFSET When CONFIG_RANDOMIZE_TEXT_OFFSET=y, TEXT_OFFSET is an arbitrary multiple of PAGE_SIZE in the interval [0, 2MB). The EFI stub does not account for the potential misalignment of TEXT_OFFSET relative to EFI_KIMG_ALIGN, and produces a randomized physical offset which is always a round multiple of EFI_KIMG_ALIGN. This may result in statically allocated objects whose alignment exceeds PAGE_SIZE to appear misaligned in memory. This has been observed to result in spurious stack overflow reports and failure to make use of the IRQ stacks, and theoretically could result in a number of other issues. We can OR in the low bits of TEXT_OFFSET to ensure that we have the necessary offset (and hence preserve the misalignment of TEXT_OFFSET relative to EFI_KIMG_ALIGN), so let's do that. Reported-by: Kim Phillips Tested-by: Kim Phillips [ardb: clarify comment and commit log, drop unneeded parens] Signed-off-by: Mark Rutland Signed-off-by: Ard Biesheuvel Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Fixes: 6f26b3671184c36d ("arm64: kaslr: increase randomization granularity") Link: http://lkml.kernel.org/r/20180518140841.9731-2-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/libstub/arm64-stub.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index b9bd827caa22..1b4d465cc5d9 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c @@ -97,6 +97,16 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg, u32 offset = !IS_ENABLED(CONFIG_DEBUG_ALIGN_RODATA) ? (phys_seed >> 32) & mask : TEXT_OFFSET; + /* + * With CONFIG_RANDOMIZE_TEXT_OFFSET=y, TEXT_OFFSET may not + * be a multiple of EFI_KIMG_ALIGN, and we must ensure that + * we preserve the misalignment of 'offset' relative to + * EFI_KIMG_ALIGN so that statically allocated objects whose + * alignment exceeds PAGE_SIZE appear correctly aligned in + * memory. + */ + offset |= TEXT_OFFSET % EFI_KIMG_ALIGN; + /* * If KASLR is enabled, and we have some randomness available, * locate the kernel at a randomized offset in physical memory. -- cgit v1.2.3-59-g8ed1b