From 4e63ed6b90803eeb400c392e9ff493200d926b06 Mon Sep 17 00:00:00 2001 From: Tomer Maimon Date: Sun, 7 Apr 2019 11:19:28 +0300 Subject: iio: adc: modify NPCM ADC read reference voltage Checking if regulator is valid before reading NPCM ADC regulator voltage to avoid system crash in a case the regulator is not valid. Signed-off-by: Tomer Maimon Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/npcm_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c index 9e25bbec9c70..193b3b81de4d 100644 --- a/drivers/iio/adc/npcm_adc.c +++ b/drivers/iio/adc/npcm_adc.c @@ -149,7 +149,7 @@ static int npcm_adc_read_raw(struct iio_dev *indio_dev, } return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - if (info->vref) { + if (!IS_ERR(info->vref)) { vref_uv = regulator_get_voltage(info->vref); *val = vref_uv / 1000; } else { -- cgit v1.2.3 From 0db8aa49a97e7f40852a64fd35abcc1292a7c365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Sun, 31 Mar 2019 20:54:23 +0200 Subject: iio: adc: ads124: avoid buffer overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When initializing the priv->data array starting from index 1, there is one less element to consider than when initializing the full array. Fixes: e717f8c6dfec8f76 ("iio: adc: Add the TI ads124s08 ADC code") Signed-off-by: Vincent Stehlé Reviewed-by: Mukesh Ojha Reviewed-by: Dan Murphy Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads124s08.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c index 53f17e4f2f23..552c2be8d87a 100644 --- a/drivers/iio/adc/ti-ads124s08.c +++ b/drivers/iio/adc/ti-ads124s08.c @@ -202,7 +202,7 @@ static int ads124s_read(struct iio_dev *indio_dev, unsigned int chan) }; priv->data[0] = ADS124S08_CMD_RDATA; - memset(&priv->data[1], ADS124S08_CMD_NOP, sizeof(priv->data)); + memset(&priv->data[1], ADS124S08_CMD_NOP, sizeof(priv->data) - 1); ret = spi_sync_transfer(priv->spi, t, ARRAY_SIZE(t)); if (ret < 0) -- cgit v1.2.3 From 1615fe41a1959a2ee2814ba62736b2bb54e9802a Mon Sep 17 00:00:00 2001 From: Steve Moskovchenko Date: Tue, 2 Apr 2019 23:28:56 -0700 Subject: iio: imu: mpu6050: Fix FIFO layout for ICM20602 The MPU6050 driver has recently gained support for the ICM20602 IMU, which is very similar to MPU6xxx. However, the ICM20602's FIFO data specifically includes temperature readings, which were not present on MPU6xxx parts. As a result, the driver will under-read the ICM20602's FIFO register, causing the same (partial) sample to be returned for all reads, until the FIFO overflows. Fix this by adding a table of scan elements specifically for the ICM20602, which takes the extra temperature data into consideration. While we're at it, fix the temperature offset and scaling on ICM20602, since it uses different scale/offset constants than the rest of the MPU6xxx devices. Signed-off-by: Steve Moskovchenko Fixes: 22904bdff978 ("iio: imu: mpu6050: Add support for the ICM 20602 IMU") Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 46 +++++++++++++++++++++++++++--- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 20 ++++++++++++- drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 3 ++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 650de0fefb7b..385f14a4d5a7 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -471,7 +471,10 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: *val = 0; - *val2 = INV_MPU6050_TEMP_SCALE; + if (st->chip_type == INV_ICM20602) + *val2 = INV_ICM20602_TEMP_SCALE; + else + *val2 = INV_MPU6050_TEMP_SCALE; return IIO_VAL_INT_PLUS_MICRO; default: @@ -480,7 +483,10 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_OFFSET: switch (chan->type) { case IIO_TEMP: - *val = INV_MPU6050_TEMP_OFFSET; + if (st->chip_type == INV_ICM20602) + *val = INV_ICM20602_TEMP_OFFSET; + else + *val = INV_MPU6050_TEMP_OFFSET; return IIO_VAL_INT; default: @@ -845,6 +851,32 @@ static const struct iio_chan_spec inv_mpu_channels[] = { INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z), }; +static const struct iio_chan_spec inv_icm20602_channels[] = { + IIO_CHAN_SOFT_TIMESTAMP(INV_ICM20602_SCAN_TIMESTAMP), + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) + | BIT(IIO_CHAN_INFO_OFFSET) + | BIT(IIO_CHAN_INFO_SCALE), + .scan_index = INV_ICM20602_SCAN_TEMP, + .scan_type = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + .shift = 0, + .endianness = IIO_BE, + }, + }, + + INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_ICM20602_SCAN_GYRO_X), + INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_ICM20602_SCAN_GYRO_Y), + INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_ICM20602_SCAN_GYRO_Z), + + INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_ICM20602_SCAN_ACCL_Y), + INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_ICM20602_SCAN_ACCL_X), + INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_ICM20602_SCAN_ACCL_Z), +}; + /* * The user can choose any frequency between INV_MPU6050_MIN_FIFO_RATE and * INV_MPU6050_MAX_FIFO_RATE, but only these frequencies are matched by the @@ -1100,8 +1132,14 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, indio_dev->name = name; else indio_dev->name = dev_name(dev); - indio_dev->channels = inv_mpu_channels; - indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); + + if (chip_type == INV_ICM20602) { + indio_dev->channels = inv_icm20602_channels; + indio_dev->num_channels = ARRAY_SIZE(inv_icm20602_channels); + } else { + indio_dev->channels = inv_mpu_channels; + indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); + } indio_dev->info = &mpu_info; indio_dev->modes = INDIO_BUFFER_TRIGGERED; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index 325afd9f5f61..3d5fe4474378 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -208,6 +208,9 @@ struct inv_mpu6050_state { #define INV_MPU6050_BYTES_PER_3AXIS_SENSOR 6 #define INV_MPU6050_FIFO_COUNT_BYTE 2 +/* ICM20602 FIFO samples include temperature readings */ +#define INV_ICM20602_BYTES_PER_TEMP_SENSOR 2 + /* mpu6500 registers */ #define INV_MPU6500_REG_ACCEL_CONFIG_2 0x1D #define INV_MPU6500_REG_ACCEL_OFFSET 0x77 @@ -229,6 +232,9 @@ struct inv_mpu6050_state { #define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT 3 #define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT 3 +#define INV_ICM20602_TEMP_OFFSET 8170 +#define INV_ICM20602_TEMP_SCALE 3060 + /* 6 + 6 round up and plus 8 */ #define INV_MPU6050_OUTPUT_DATA_SIZE 24 @@ -270,7 +276,7 @@ struct inv_mpu6050_state { #define INV_ICM20608_WHOAMI_VALUE 0xAF #define INV_ICM20602_WHOAMI_VALUE 0x12 -/* scan element definition */ +/* scan element definition for generic MPU6xxx devices */ enum inv_mpu6050_scan { INV_MPU6050_SCAN_ACCL_X, INV_MPU6050_SCAN_ACCL_Y, @@ -281,6 +287,18 @@ enum inv_mpu6050_scan { INV_MPU6050_SCAN_TIMESTAMP, }; +/* scan element definition for ICM20602, which includes temperature */ +enum inv_icm20602_scan { + INV_ICM20602_SCAN_ACCL_X, + INV_ICM20602_SCAN_ACCL_Y, + INV_ICM20602_SCAN_ACCL_Z, + INV_ICM20602_SCAN_TEMP, + INV_ICM20602_SCAN_GYRO_X, + INV_ICM20602_SCAN_GYRO_Y, + INV_ICM20602_SCAN_GYRO_Z, + INV_ICM20602_SCAN_TIMESTAMP, +}; + enum inv_mpu6050_filter_e { INV_MPU6050_FILTER_256HZ_NOLPF2 = 0, INV_MPU6050_FILTER_188HZ, diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index 548e042f7b5b..57bd11bde56b 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -207,6 +207,9 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) if (st->chip_config.gyro_fifo_enable) bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR; + if (st->chip_type == INV_ICM20602) + bytes_per_datum += INV_ICM20602_BYTES_PER_TEMP_SENSOR; + /* * read fifo_count register to know how many bytes are inside the FIFO * right now -- cgit v1.2.3 From 60f2208699ec08ff9fdf1f97639a661a92a18f1c Mon Sep 17 00:00:00 2001 From: Ruslan Babayev Date: Sun, 5 May 2019 12:24:37 -0700 Subject: iio: dac: ds4422/ds4424 fix chip verification The ds4424_get_value function takes channel number as it's 3rd argument and translates it internally into I2C address using DS4424_DAC_ADDR macro. The caller ds4424_verify_chip was passing an already translated I2C address as its last argument. Signed-off-by: Ruslan Babayev Cc: xe-linux-external@cisco.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ds4424.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c index 883a47562055..714a97f91319 100644 --- a/drivers/iio/dac/ds4424.c +++ b/drivers/iio/dac/ds4424.c @@ -166,7 +166,7 @@ static int ds4424_verify_chip(struct iio_dev *indio_dev) { int ret, val; - ret = ds4424_get_value(indio_dev, &val, DS4424_DAC_ADDR(0)); + ret = ds4424_get_value(indio_dev, &val, 0); if (ret < 0) dev_err(&indio_dev->dev, "%s failed. ret: %d\n", __func__, ret); -- cgit v1.2.3 From e6d12298310fa1dc11f1d747e05b168016057fdd Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Tue, 7 May 2019 10:23:04 +0200 Subject: iio: adc: ti-ads8688: fix timestamp is not updated in buffer When using the hrtimer iio trigger timestamp isn't updated. If we use iio_get_time_ns it is updated correctly. Fixes: 2a86487786b5c ("iio: adc: ti-ads8688: add trigger and buffer support") Signed-off-by: Sean Nyekjaer Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads8688.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 8b4568edd5cb..7f16c77b99fb 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c @@ -397,7 +397,7 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p) } iio_push_to_buffers_with_timestamp(indio_dev, buffer, - pf->timestamp); + iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig); -- cgit v1.2.3 From 7eaf51a2e094229b75cc0c315f1cbbe2f3960058 Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Fri, 17 May 2019 14:51:17 -0400 Subject: stacktrace: Unbreak stack_trace_save_tsk_reliable() Miroslav reported that the livepatch self-tests were failing, specifically a case in which the consistency model ensures that a current executing function is not allowed to be patched, "TEST: busy target module". Recent renovations of stack_trace_save_tsk_reliable() left it returning only an -ERRNO success indication in some configuration combinations: klp_check_stack() ret = stack_trace_save_tsk_reliable() #ifdef CONFIG_ARCH_STACKWALK && CONFIG_HAVE_RELIABLE_STACKTRACE stack_trace_save_tsk_reliable() ret = arch_stack_walk_reliable() return 0 return -EINVAL ... return ret; ... if (ret < 0) /* stack_trace_save_tsk_reliable error */ nr_entries = ret; << 0 Previously (and currently for !CONFIG_ARCH_STACKWALK && CONFIG_HAVE_RELIABLE_STACKTRACE) stack_trace_save_tsk_reliable() returned the number of entries that it consumed in the passed storage array. In the case of the above config and trace, be sure to return the stacktrace_cookie.len on stack_trace_save_tsk_reliable() success. Fixes: 25e39e32b0a3f ("livepatch: Simplify stack trace retrieval") Reported-by: Miroslav Benes Signed-off-by: Joe Lawrence Signed-off-by: Thomas Gleixner Reviewed-by: Kamalesh Babulal Acked-by: Josh Poimboeuf Cc: live-patching@vger.kernel.org Cc: jikos@kernel.org Cc: pmladek@suse.com Link: https://lkml.kernel.org/r/20190517185117.24642-1-joe.lawrence@redhat.com --- kernel/stacktrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/stacktrace.c b/kernel/stacktrace.c index 27bafc1e271e..90d3e0bf0302 100644 --- a/kernel/stacktrace.c +++ b/kernel/stacktrace.c @@ -206,7 +206,7 @@ int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store, ret = arch_stack_walk_reliable(consume_entry, &c, tsk); put_task_stack(tsk); - return ret; + return ret ? ret : c.len; } #endif -- cgit v1.2.3 From 558b523d46289f111d53d7c42211069063be5985 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 23 Apr 2019 17:48:07 -0500 Subject: x86/ima: Check EFI_RUNTIME_SERVICES before using Checking efi_enabled(EFI_BOOT) is not sufficient to ensure that EFI runtime services are available, e.g. if efi=noruntime is used. Without this, I get an oops on a PREEMPT_RT kernel where efi=noruntime is the default. Fixes: 399574c64eaf94e8 ("x86/ima: retry detecting secure boot mode") Cc: stable@vger.kernel.org (linux-5.0) Signed-off-by: Scott Wood Signed-off-by: Mimi Zohar --- arch/x86/kernel/ima_arch.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/kernel/ima_arch.c b/arch/x86/kernel/ima_arch.c index 85de790583f9..64b973f0e985 100644 --- a/arch/x86/kernel/ima_arch.c +++ b/arch/x86/kernel/ima_arch.c @@ -18,6 +18,11 @@ static enum efi_secureboot_mode get_sb_mode(void) size = sizeof(secboot); + if (!efi_enabled(EFI_RUNTIME_SERVICES)) { + pr_info("ima: secureboot mode unknown, no efi\n"); + return efi_secureboot_mode_unknown; + } + /* Get variable contents into buffer */ status = efi.get_variable(efi_SecureBoot_name, &efi_variable_guid, NULL, &size, &secboot); -- cgit v1.2.3 From f40019475bbbe9b455e7fd4385fcf13896c492ca Mon Sep 17 00:00:00 2001 From: Petr Vorel Date: Wed, 15 May 2019 08:18:07 +0200 Subject: ima: fix wrong signed policy requirement when not appraising Kernel booted just with ima_policy=tcb (not with ima_policy=appraise_tcb) shouldn't require signed policy. Regression found with LTP test ima_policy.sh. Fixes: c52657d93b05 ("ima: refactor ima_init_policy()") Cc: stable@vger.kernel.org (linux-5.0) Signed-off-by: Petr Vorel Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_policy.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index e0cc323f948f..0f6fe53cef09 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -498,10 +498,11 @@ static void add_rules(struct ima_rule_entry *entries, int count, list_add_tail(&entry->list, &ima_policy_rules); } - if (entries[i].action == APPRAISE) + if (entries[i].action == APPRAISE) { temp_ima_appraise |= ima_appraise_flag(entries[i].func); - if (entries[i].func == POLICY_CHECK) - temp_ima_appraise |= IMA_APPRAISE_POLICY; + if (entries[i].func == POLICY_CHECK) + temp_ima_appraise |= IMA_APPRAISE_POLICY; + } } } -- cgit v1.2.3 From f2dcb8841e6b155da098edae09125859ef7e853d Mon Sep 17 00:00:00 2001 From: Chengguang Xu Date: Mon, 6 May 2019 19:01:02 +0800 Subject: staging: erofs: set sb->s_root to NULL when failing from __getname() Set sb->s_root to NULL when failing from __getname(), so that we can avoid double dput and unnecessary operations in generic_shutdown_super(). Signed-off-by: Chengguang Xu Reviewed-by: Chao Yu Reviewed-by: Gao Xiang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/erofs/super.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/erofs/super.c b/drivers/staging/erofs/super.c index 399847d21146..f580d4ef77a1 100644 --- a/drivers/staging/erofs/super.c +++ b/drivers/staging/erofs/super.c @@ -457,6 +457,7 @@ static int erofs_read_super(struct super_block *sb, */ err_devname: dput(sb->s_root); + sb->s_root = NULL; err_iget: #ifdef EROFS_FS_HAS_MANAGED_CACHE iput(sbi->managed_cache); -- cgit v1.2.3 From e00839f38823e7e4a38d2e2703c624a16f08dac8 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 8 May 2019 13:55:13 -0700 Subject: staging: kpc2000: fix build error on xtensa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kpc2000/kpc_dma/fileops.c includes asm/uaccess.h instead of linux/uaccess.h, which results in the following build error on xtensa architecture: In file included from drivers/staging/kpc2000/kpc_dma/fileops.c:11: arch/xtensa/include/asm/uaccess.h: In function ‘clear_user’: arch/xtensa/include/asm/uaccess.h:40:22: error: implicit declaration of function ‘uaccess_kernel’; ... #define __kernel_ok (uaccess_kernel()) ^~~~~~~~~~~~~~ Include linux/uaccess.h to fix that. Signed-off-by: Max Filippov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/kpc2000/kpc_dma/fileops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c index 5741d2b49a7d..0886ad408b0e 100644 --- a/drivers/staging/kpc2000/kpc_dma/fileops.c +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c @@ -8,7 +8,7 @@ #include /* error codes */ #include /* size_t */ #include -#include /* copy_*_user */ +#include /* copy_*_user */ #include /* aio stuff */ #include #include -- cgit v1.2.3 From d4c596ebf62760b89ec3d0a2cbc94e2632395eec Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Fri, 10 May 2019 21:47:24 +0800 Subject: staging: kpc2000: Fix build error without CONFIG_UIO Fix gcc build error while CONFIG_UIO is not set ERROR: "uio_unregister_device" [drivers/staging/kpc2000/kpc2000/kpc2000.ko] undefined! ERROR: "__uio_register_device" [drivers/staging/kpc2000/kpc2000/kpc2000.ko] undefined! Add UIO Kconfig dependency to fix this. Reported-by: Hulk Robot Reported-by: kbuild test robot Fixes: 7dc7967fc39a ("staging: kpc2000: add initial set of Daktronics drivers") Signed-off-by: YueHaibing Signed-off-by: Greg Kroah-Hartman --- drivers/staging/kpc2000/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/kpc2000/Kconfig b/drivers/staging/kpc2000/Kconfig index fb5922928f47..febe4f8b30e5 100644 --- a/drivers/staging/kpc2000/Kconfig +++ b/drivers/staging/kpc2000/Kconfig @@ -3,6 +3,7 @@ config KPC2000 bool "Daktronics KPC Device support" depends on PCI + depends on UIO help Select this if you wish to use the Daktronics KPC PCI devices -- cgit v1.2.3 From c85aa326f5c5cc73bad4381498fd2bda1bb41c27 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 May 2019 12:52:46 +0300 Subject: staging: kpc2000: double unlock in error handling in kpc_dma_transfer() The goto err_descr_too_many; calls unlock_engine() so this unlocks twice. Fixes: 7df95299b94a ("staging: kpc2000: Add DMA driver") Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/kpc2000/kpc_dma/fileops.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c index 0886ad408b0e..616658709bd9 100644 --- a/drivers/staging/kpc2000/kpc_dma/fileops.c +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c @@ -116,13 +116,11 @@ int kpc_dma_transfer(struct dev_private_data *priv, struct kiocb *kcb, unsigned if (desc_needed >= ldev->desc_pool_cnt){ dev_warn(&priv->ldev->pldev->dev, " mapped_entry_count = %d num_descrs_needed = %d num_descrs_avail = %d TOO MANY to ever complete!\n", acd->mapped_entry_count, desc_needed, num_descrs_avail); rv = -EAGAIN; - unlock_engine(ldev); goto err_descr_too_many; } if (desc_needed > num_descrs_avail){ dev_warn(&priv->ldev->pldev->dev, " mapped_entry_count = %d num_descrs_needed = %d num_descrs_avail = %d Too many to complete right now.\n", acd->mapped_entry_count, desc_needed, num_descrs_avail); rv = -EMSGSIZE; - unlock_engine(ldev); goto err_descr_too_many; } -- cgit v1.2.3 From a67fedd788182764dc8ed59037c604b7e60349f1 Mon Sep 17 00:00:00 2001 From: Tim Collier Date: Sat, 11 May 2019 18:40:46 +0100 Subject: staging: wlan-ng: fix adapter initialization failure Commit e895f00a8496 ("Staging: wlan-ng: hfa384x_usb.c Fixed too long code line warnings.") moved the retrieval of the transfer buffer from the URB from the top of function hfa384x_usbin_callback to a point after reposting of the URB via a call to submit_rx_urb. The reposting of the URB allocates a new transfer buffer so the new buffer is retrieved instead of the buffer containing the response passed into the callback. This results in failure to initialize the adapter with an error reported in the system log (something like "CTLX[1] error: state(Request failed)"). This change moves the retrieval to just before the point where the URB is reposted so that the correct transfer buffer is retrieved and initialization of the device succeeds. Signed-off-by: Tim Collier Fixes: e895f00a8496 ("Staging: wlan-ng: hfa384x_usb.c Fixed too long code line warnings.") Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/hfa384x_usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 6fde75d4f064..ab734534093b 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -3119,7 +3119,9 @@ static void hfa384x_usbin_callback(struct urb *urb) break; } + /* Save values from the RX URB before reposting overwrites it. */ urb_status = urb->status; + usbin = (union hfa384x_usbin *)urb->transfer_buffer; if (action != ABORT) { /* Repost the RX URB */ @@ -3136,7 +3138,6 @@ static void hfa384x_usbin_callback(struct urb *urb) /* Note: the check of the sw_support field, the type field doesn't * have bit 12 set like the docs suggest. */ - usbin = (union hfa384x_usbin *)urb->transfer_buffer; type = le16_to_cpu(usbin->type); if (HFA384x_USB_ISRXFRM(type)) { if (action == HANDLE) { -- cgit v1.2.3 From ca4e4efbefbbdde0a7bb3023ea08d491f4daf9b9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 13 May 2019 14:07:18 +0300 Subject: Staging: vc04_services: Fix a couple error codes These are accidentally returning positive EINVAL instead of negative -EINVAL. Some of the callers treat positive values as success. Fixes: 7b3ad5abf027 ("staging: Import the BCM2835 MMAL-based V4L2 camera driver.") Signed-off-by: Dan Carpenter Acked-by: Stefan Wahren Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vc04_services/bcm2835-camera/controls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c index 9841c30450ce..dade79738a29 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/controls.c +++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c @@ -572,7 +572,7 @@ exit: dev->colourfx.enable ? "true" : "false", dev->colourfx.u, dev->colourfx.v, ret, (ret == 0 ? 0 : -EINVAL)); - return (ret == 0 ? 0 : EINVAL); + return (ret == 0 ? 0 : -EINVAL); } static int ctrl_set_colfx(struct bm2835_mmal_dev *dev, @@ -596,7 +596,7 @@ static int ctrl_set_colfx(struct bm2835_mmal_dev *dev, "%s: After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n", __func__, mmal_ctrl, ctrl->id, ctrl->val, ret, (ret == 0 ? 0 : -EINVAL)); - return (ret == 0 ? 0 : EINVAL); + return (ret == 0 ? 0 : -EINVAL); } static int ctrl_set_bitrate(struct bm2835_mmal_dev *dev, -- cgit v1.2.3 From ca641bae6da977d638458e78cd1487b6160a2718 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 May 2019 12:38:33 +0300 Subject: staging: vc04_services: prevent integer overflow in create_pagelist() The create_pagelist() "count" parameter comes from the user in vchiq_ioctl() and it could overflow. If you look at how create_page() is called in vchiq_prepare_bulk_data(), then the "size" variable is an int so it doesn't make sense to allow negatives or larger than INT_MAX. I don't know this code terribly well, but I believe that typical values of "count" are typically quite low and I don't think this check will affect normal valid uses at all. The "pagelist_size" calculation can also overflow on 32 bit systems, but not on 64 bit systems. I have added an integer overflow check for that as well. The Raspberry PI doesn't offer the same level of memory protection that x86 does so these sorts of bugs are probably not super critical to fix. Fixes: 71bad7f08641 ("staging: add bcm2708 vchiq driver") Signed-off-by: Dan Carpenter Cc: stable Signed-off-by: Greg Kroah-Hartman --- .../staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index a9a22917ecdb..c557c9953724 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -368,9 +368,18 @@ create_pagelist(char __user *buf, size_t count, unsigned short type) int dma_buffers; dma_addr_t dma_addr; + if (count >= INT_MAX - PAGE_SIZE) + return NULL; + offset = ((unsigned int)(unsigned long)buf & (PAGE_SIZE - 1)); num_pages = DIV_ROUND_UP(count + offset, PAGE_SIZE); + if (num_pages > (SIZE_MAX - sizeof(struct pagelist) - + sizeof(struct vchiq_pagelist_info)) / + (sizeof(u32) + sizeof(pages[0]) + + sizeof(struct scatterlist))) + return NULL; + pagelist_size = sizeof(struct pagelist) + (num_pages * sizeof(u32)) + (num_pages * sizeof(pages[0]) + -- cgit v1.2.3 From fea69916360468e364a4988db25a5afa835f3406 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 May 2019 12:52:23 +0300 Subject: staging: wilc1000: Fix some double unlock bugs in wilc_wlan_cleanup() If ->hif_read_reg() or ->hif_write_reg() fail then the code unlocks and keeps executing. It should just return. Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver") Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wilc1000/wilc_wlan.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 0a713409ea98..95eaf8fdf4f2 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1076,13 +1076,17 @@ void wilc_wlan_cleanup(struct net_device *dev) acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP); ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, ®); - if (!ret) + if (!ret) { release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); + return; + } ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0, (reg | ABORT_INT)); - if (!ret) + if (!ret) { release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); + return; + } release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP); wilc->hif_func->hif_deinit(NULL); -- cgit v1.2.3 From 7a95aab57b79b2d5b83b4ac7abceb14c91da0d36 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Wed, 15 May 2019 08:41:22 +0300 Subject: parisc: Kconfig: remove ARCH_DISCARD_MEMBLOCK Since commit 350e88bad496 ("mm: memblock: make keeping memblock memory opt-in rather than opt-out") the default behaviour is to discard memblock data after init and the ARCH_DISCARD_MEMBLOCK is obsolete. Remove it. Signed-off-by: Mike Rapoport Signed-off-by: Helge Deller --- arch/parisc/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 09407ed1aacd..13b9512527c7 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -36,7 +36,6 @@ config PARISC select GENERIC_STRNCPY_FROM_USER select SYSCTL_ARCH_UNALIGN_ALLOW select SYSCTL_EXCEPTION_TRACE - select ARCH_DISCARD_MEMBLOCK select HAVE_MOD_ARCH_SPECIFIC select VIRT_TO_BUS select MODULES_USE_ELF_RELA -- cgit v1.2.3 From 200036a8e802dee09103031eeeaea91dd212ec99 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 14 May 2019 21:40:53 +0200 Subject: parisc: Allow building 64-bit kernel without -mlong-calls compiler option A 64-bit kernel built without CONFIG_MLONGCALLS (-mlong-calls compiler option) usually fails to link because of unreachable functions. Try to work around that linking issue by moving the *.init and *.exit text segments closer to the main text segment. With that change those segments now don't get freed at runtime any longer, but since we in most cases run with huge-page enabled, we ignore the lost memory in preference of better performance. This change will not guarantee that every kernel config will now sucessfully build with short calls and without linking issues. Signed-off-by: Helge Deller --- arch/parisc/Kconfig | 3 ++- arch/parisc/kernel/vmlinux.lds.S | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 13b9512527c7..4860efa91d7b 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -194,7 +194,8 @@ config PREFETCH config MLONGCALLS bool "Enable the -mlong-calls compiler option for big kernels" - default y + default y if !MODULES || UBSAN || FTRACE + default n depends on PA8X00 help If you configure the kernel to include many drivers built-in instead diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index c3b1b9c24ede..cd33b4feacb1 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -35,6 +35,15 @@ OUTPUT_FORMAT("elf64-hppa-linux") OUTPUT_ARCH(hppa:hppa2.0w) #endif +#define EXIT_TEXT_SECTIONS() .exit.text : { EXIT_TEXT } +#if !defined(CONFIG_64BIT) || defined(CONFIG_MLONGCALLS) +#define MLONGCALL_KEEP(x) +#define MLONGCALL_DISCARD(x) x +#else +#define MLONGCALL_KEEP(x) x +#define MLONGCALL_DISCARD(x) +#endif + ENTRY(parisc_kernel_start) #ifndef CONFIG_64BIT jiffies = jiffies_64 + 4; @@ -47,15 +56,11 @@ SECTIONS __init_begin = .; HEAD_TEXT_SECTION - INIT_TEXT_SECTION(8) + MLONGCALL_DISCARD(INIT_TEXT_SECTION(8)) . = ALIGN(PAGE_SIZE); INIT_DATA_SECTION(PAGE_SIZE) - /* we have to discard exit text and such at runtime, not link time */ - .exit.text : - { - EXIT_TEXT - } + MLONGCALL_DISCARD(EXIT_TEXT_SECTIONS()) .exit.data : { EXIT_DATA @@ -73,11 +78,12 @@ SECTIONS _text = .; /* Text and read-only data */ _stext = .; + MLONGCALL_KEEP(INIT_TEXT_SECTION(8)) .text ALIGN(PAGE_SIZE) : { TEXT_TEXT + LOCK_TEXT SCHED_TEXT CPUIDLE_TEXT - LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT SOFTIRQENTRY_TEXT @@ -92,6 +98,7 @@ SECTIONS *(.lock.text) /* out-of-line lock text */ *(.gnu.warning) } + MLONGCALL_KEEP(EXIT_TEXT_SECTIONS()) . = ALIGN(PAGE_SIZE); _etext = .; /* End of text section */ -- cgit v1.2.3 From 89c92142f75eb80064f5b9f1111484b1b4d81790 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Tue, 7 May 2019 10:45:24 -0700 Subject: ARC: fix build warnings | arch/arc/mm/tlb.c:914:2: warning: variable length array 'pd0' is used [-Wvla] | arch/arc/include/asm/cmpxchg.h:95:29: warning: value computed is not used [-Wunused-value] Signed-off-by: Vineet Gupta --- arch/arc/include/asm/cmpxchg.h | 14 ++++++++++---- arch/arc/mm/tlb.c | 13 ++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h index d819de1c5d10..3ea4112c8302 100644 --- a/arch/arc/include/asm/cmpxchg.h +++ b/arch/arc/include/asm/cmpxchg.h @@ -92,8 +92,11 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) #endif /* CONFIG_ARC_HAS_LLSC */ -#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \ - (unsigned long)(o), (unsigned long)(n))) +#define cmpxchg(ptr, o, n) ({ \ + (typeof(*(ptr)))__cmpxchg((ptr), \ + (unsigned long)(o), \ + (unsigned long)(n)); \ +}) /* * atomic_cmpxchg is same as cmpxchg @@ -198,8 +201,11 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr, return __xchg_bad_pointer(); } -#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \ - sizeof(*(ptr)))) +#define xchg(ptr, with) ({ \ + (typeof(*(ptr)))__xchg((unsigned long)(with), \ + (ptr), \ + sizeof(*(ptr))); \ +}) #endif /* CONFIG_ARC_PLAT_EZNPS */ diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index 4097764fea23..fa18c00b0cfd 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c @@ -911,9 +911,11 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, struct pt_regs *regs) { struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; - unsigned int pd0[mmu->ways]; unsigned long flags; - int set; + int set, n_ways = mmu->ways; + + n_ways = min(n_ways, 4); + BUG_ON(mmu->ways > 4); local_irq_save(flags); @@ -921,9 +923,10 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, for (set = 0; set < mmu->sets; set++) { int is_valid, way; + unsigned int pd0[4]; /* read out all the ways of current set */ - for (way = 0, is_valid = 0; way < mmu->ways; way++) { + for (way = 0, is_valid = 0; way < n_ways; way++) { write_aux_reg(ARC_REG_TLBINDEX, SET_WAY_TO_IDX(mmu, set, way)); write_aux_reg(ARC_REG_TLBCOMMAND, TLBRead); @@ -937,14 +940,14 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, continue; /* Scan the set for duplicate ways: needs a nested loop */ - for (way = 0; way < mmu->ways - 1; way++) { + for (way = 0; way < n_ways - 1; way++) { int n; if (!pd0[way]) continue; - for (n = way + 1; n < mmu->ways; n++) { + for (n = way + 1; n < n_ways; n++) { if (pd0[way] != pd0[n]) continue; -- cgit v1.2.3 From a8c715b4dd73c26a81a9cc8dc792aa715d8b4bb2 Mon Sep 17 00:00:00 2001 From: Eugeniy Paltsev Date: Mon, 13 May 2019 20:28:00 +0300 Subject: ARC: mm: SIGSEGV userspace trying to access kernel virtual memory As of today if userspace process tries to access a kernel virtual addres (0x7000_0000 to 0x7ffff_ffff) such that a legit kernel mapping already exists, that process hangs instead of being killed with SIGSEGV Fix that by ensuring that do_page_fault() handles kenrel vaddr only if in kernel mode. And given this, we can also simplify the code a bit. Now a vmalloc fault implies kernel mode so its failure (for some reason) can reuse the @no_context label and we can remove @bad_area_nosemaphore. Reproduce user test for original problem: ------------------------>8----------------- #include #include int main(int argc, char *argv[]) { volatile uint32_t temp; temp = *(uint32_t *)(0x70000000); } ------------------------>8----------------- Cc: Signed-off-by: Eugeniy Paltsev Signed-off-by: Vineet Gupta --- arch/arc/mm/fault.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c index 8df1638259f3..6836095251ed 100644 --- a/arch/arc/mm/fault.c +++ b/arch/arc/mm/fault.c @@ -66,7 +66,7 @@ void do_page_fault(unsigned long address, struct pt_regs *regs) struct vm_area_struct *vma = NULL; struct task_struct *tsk = current; struct mm_struct *mm = tsk->mm; - int si_code = 0; + int si_code = SEGV_MAPERR; int ret; vm_fault_t fault; int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */ @@ -81,16 +81,14 @@ void do_page_fault(unsigned long address, struct pt_regs *regs) * only copy the information from the master page table, * nothing more. */ - if (address >= VMALLOC_START) { + if (address >= VMALLOC_START && !user_mode(regs)) { ret = handle_kernel_vaddr_fault(address); if (unlikely(ret)) - goto bad_area_nosemaphore; + goto no_context; else return; } - si_code = SEGV_MAPERR; - /* * If we're in an interrupt or have no user * context, we must not take the fault.. @@ -198,7 +196,6 @@ good_area: bad_area: up_read(&mm->mmap_sem); -bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (user_mode(regs)) { tsk->thread.fault_address = address; -- cgit v1.2.3 From 7210e060155b9cf557fb13128353c3e494fa5ed3 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 20 May 2019 11:50:42 -0700 Subject: gcc-plugins: Fix build failures under Darwin host The gcc-common.h file did not take into account certain macros that might have already been defined in the build environment. This updates the header to avoid redefining the macros, as seen on a Darwin host using gcc 4.9.2: HOSTCXX -fPIC scripts/gcc-plugins/arm_ssp_per_task_plugin.o - due to: scripts/gcc-plugins/gcc-common.h In file included from scripts/gcc-plugins/arm_ssp_per_task_plugin.c:3:0: scripts/gcc-plugins/gcc-common.h:153:0: warning: "__unused" redefined ^ In file included from /usr/include/stdio.h:64:0, from /Users/hns/Documents/Projects/QuantumSTEP/System/Library/Frameworks/System.framework/Versions-jessie/x86_64-apple-darwin15.0.0/gcc/arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabi/4.9.2/plugin/include/system.h:40, from /Users/hns/Documents/Projects/QuantumSTEP/System/Library/Frameworks/System.framework/Versions-jessie/x86_64-apple-darwin15.0.0/gcc/arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabi/4.9.2/plugin/include/gcc-plugin.h:28, from /Users/hns/Documents/Projects/QuantumSTEP/System/Library/Frameworks/System.framework/Versions-jessie/x86_64-apple-darwin15.0.0/gcc/arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabi/4.9.2/plugin/include/plugin.h:23, from scripts/gcc-plugins/gcc-common.h:9, from scripts/gcc-plugins/arm_ssp_per_task_plugin.c:3: /usr/include/sys/cdefs.h:161:0: note: this is the location of the previous definition ^ Reported-and-tested-by: "H. Nikolaus Schaller" Fixes: 189af4657186 ("ARM: smp: add support for per-task stack canaries") Cc: stable@vger.kernel.org Signed-off-by: Kees Cook --- scripts/gcc-plugins/gcc-common.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h index 552d5efd7cb7..17f06079a712 100644 --- a/scripts/gcc-plugins/gcc-common.h +++ b/scripts/gcc-plugins/gcc-common.h @@ -150,8 +150,12 @@ void print_gimple_expr(FILE *, gimple, int, int); void dump_gimple_stmt(pretty_printer *, gimple, int, int); #endif +#ifndef __unused #define __unused __attribute__((__unused__)) +#endif +#ifndef __visible #define __visible __attribute__((visibility("default"))) +#endif #define DECL_NAME_POINTER(node) IDENTIFIER_POINTER(DECL_NAME(node)) #define DECL_NAME_LENGTH(node) IDENTIFIER_LENGTH(DECL_NAME(node)) -- cgit v1.2.3 From a03ff54460817c76105f81f3aa8ef655759ccc9a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 13 May 2019 13:14:29 -0400 Subject: USB: Fix slab-out-of-bounds write in usb_get_bos_descriptor The syzkaller USB fuzzer found a slab-out-of-bounds write bug in the USB core, caused by a failure to check the actual size of a BOS descriptor. This patch adds a check to make sure the descriptor is at least as large as it is supposed to be, so that the code doesn't inadvertently access memory beyond the end of the allocated region when assigning to dev->bos->desc->bNumDeviceCaps later on. Signed-off-by: Alan Stern Reported-and-tested-by: syzbot+71f1e64501a309fcc012@syzkaller.appspotmail.com CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 20ff036b4c22..9d6cb709ca7b 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -932,8 +932,8 @@ int usb_get_bos_descriptor(struct usb_device *dev) /* Get BOS descriptor */ ret = usb_get_descriptor(dev, USB_DT_BOS, 0, bos, USB_DT_BOS_SIZE); - if (ret < USB_DT_BOS_SIZE) { - dev_err(ddev, "unable to get BOS descriptor\n"); + if (ret < USB_DT_BOS_SIZE || bos->bLength < USB_DT_BOS_SIZE) { + dev_err(ddev, "unable to get BOS descriptor or descriptor too short\n"); if (ret >= 0) ret = -ENOMSG; kfree(bos); -- cgit v1.2.3 From 9610450ea31eb061b9914de2bf6ced424956182d Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Sun, 5 May 2019 14:02:49 +0800 Subject: usb: mtu3: fix up undefined reference to usb_debug_root When CONFIG_USB is not set, and CONFIG_USB_GADGET is set, there is an issue: ld: drivers/usb/mtu3/mtu3_debugfs.o: in function 'ssusb_debugfs_create_root': mtu3_debugfs.c:(.text+0xba3): undefined reference to 'usb_debug_root' usb_debug_root is only built when CONFIG_USB is enabled, so here drop it and use NULL instead. Reported-by: Randy Dunlap Signed-off-by: Chunfeng Yun Acked-by: Randy Dunlap # build-tested Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mtu3/mtu3_debugfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/mtu3/mtu3_debugfs.c b/drivers/usb/mtu3/mtu3_debugfs.c index 62c57ddc554e..b7c86ccd50b4 100644 --- a/drivers/usb/mtu3/mtu3_debugfs.c +++ b/drivers/usb/mtu3/mtu3_debugfs.c @@ -528,8 +528,7 @@ void ssusb_dr_debugfs_init(struct ssusb_mtk *ssusb) void ssusb_debugfs_create_root(struct ssusb_mtk *ssusb) { - ssusb->dbgfs_root = - debugfs_create_dir(dev_name(ssusb->dev), usb_debug_root); + ssusb->dbgfs_root = debugfs_create_dir(dev_name(ssusb->dev), NULL); } void ssusb_debugfs_remove_root(struct ssusb_mtk *ssusb) -- cgit v1.2.3 From 31e0456de5be379b10fea0fa94a681057114a96e Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 7 May 2019 12:39:47 -0400 Subject: media: usb: siano: Fix general protection fault in smsusb The syzkaller USB fuzzer found a general-protection-fault bug in the smsusb part of the Siano DVB driver. The fault occurs during probe because the driver assumes without checking that the device has both IN and OUT endpoints and the IN endpoint is ep1. By slightly rearranging the driver's initialization code, we can make the appropriate checks early on and thus avoid the problem. If the expected endpoints aren't present, the new code safely returns -ENODEV from the probe routine. Signed-off-by: Alan Stern Reported-and-tested-by: syzbot+53f029db71c19a47325a@syzkaller.appspotmail.com CC: Reviewed-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/siano/smsusb.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 4fc03ec8a4f1..27ad14a3f831 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -400,6 +400,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) struct smsusb_device_t *dev; void *mdev; int i, rc; + int in_maxp; /* create device object */ dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); @@ -411,6 +412,24 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) dev->udev = interface_to_usbdev(intf); dev->state = SMSUSB_DISCONNECTED; + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { + struct usb_endpoint_descriptor *desc = + &intf->cur_altsetting->endpoint[i].desc; + + if (desc->bEndpointAddress & USB_DIR_IN) { + dev->in_ep = desc->bEndpointAddress; + in_maxp = usb_endpoint_maxp(desc); + } else { + dev->out_ep = desc->bEndpointAddress; + } + } + + pr_debug("in_ep = %02x, out_ep = %02x\n", dev->in_ep, dev->out_ep); + if (!dev->in_ep || !dev->out_ep) { /* Missing endpoints? */ + smsusb_term_device(intf); + return -ENODEV; + } + params.device_type = sms_get_board(board_id)->type; switch (params.device_type) { @@ -425,24 +444,12 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) /* fall-thru */ default: dev->buffer_size = USB2_BUFFER_SIZE; - dev->response_alignment = - le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) - - sizeof(struct sms_msg_hdr); + dev->response_alignment = in_maxp - sizeof(struct sms_msg_hdr); params.flags |= SMS_DEVICE_FAMILY2; break; } - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { - if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN) - dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress; - else - dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress; - } - - pr_debug("in_ep = %02x, out_ep = %02x\n", - dev->in_ep, dev->out_ep); - params.device = &dev->udev->dev; params.usb_device = dev->udev; params.buffer_size = dev->buffer_size; -- cgit v1.2.3 From ea261113385ac0a71c2838185f39e8452d54b152 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Thu, 16 May 2019 17:08:31 +0200 Subject: USB: Add LPM quirk for Surface Dock GigE adapter Without USB_QUIRK_NO_LPM ethernet will not work and rtl8152 will complain with r8152 : Stop submitting intr, status -71 Adding the quirk resolves this. As the dock is externally powered, this should not have any drawbacks. Signed-off-by: Maximilian Luz Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 8bc35d53408b..6082b008969b 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -209,6 +209,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* Microsoft LifeCam-VX700 v2.0 */ { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Microsoft Surface Dock Ethernet (RTL8153 GigE) */ + { USB_DEVICE(0x045e, 0x07c6), .driver_info = USB_QUIRK_NO_LPM }, + /* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */ { USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME }, -- cgit v1.2.3 From 9a5729f68d3a82786aea110b1bfe610be318f80a Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 9 May 2019 14:41:50 +0200 Subject: USB: sisusbvga: fix oops in error path of sisusb_probe The pointer used to log a failure of usb_register_dev() must be set before the error is logged. v2: fix that minor is not available before registration Signed-off-by: oliver Neukum Reported-by: syzbot+a0cbdbd6d169020c8959@syzkaller.appspotmail.com Fixes: 7b5cd5fefbe02 ("USB: SisUSB2VGA: Convert printk to dev_* macros") Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/sisusbvga/sisusb.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 9560fde621ee..ea06f1fed6fa 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -3029,6 +3029,13 @@ static int sisusb_probe(struct usb_interface *intf, mutex_init(&(sisusb->lock)); + sisusb->sisusb_dev = dev; + sisusb->vrambase = SISUSB_PCI_MEMBASE; + sisusb->mmiobase = SISUSB_PCI_MMIOBASE; + sisusb->mmiosize = SISUSB_PCI_MMIOSIZE; + sisusb->ioportbase = SISUSB_PCI_IOPORTBASE; + /* Everything else is zero */ + /* Register device */ retval = usb_register_dev(intf, &usb_sisusb_class); if (retval) { @@ -3039,13 +3046,7 @@ static int sisusb_probe(struct usb_interface *intf, goto error_1; } - sisusb->sisusb_dev = dev; - sisusb->minor = intf->minor; - sisusb->vrambase = SISUSB_PCI_MEMBASE; - sisusb->mmiobase = SISUSB_PCI_MMIOBASE; - sisusb->mmiosize = SISUSB_PCI_MMIOSIZE; - sisusb->ioportbase = SISUSB_PCI_IOPORTBASE; - /* Everything else is zero */ + sisusb->minor = intf->minor; /* Allocate buffers */ sisusb->ibufsize = SISUSB_IBUF_SIZE; -- cgit v1.2.3 From 0c9e8b3cad654bfc499c10b652fbf8f0b890af8f Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 2 May 2019 13:47:02 -0600 Subject: usbip: usbip_host: fix BUG: sleeping function called from invalid context stub_probe() and stub_disconnect() call functions which could call sleeping function in invalid context whil holding busid_lock. Fix the problem by refining the lock holds to short critical sections to change the busid_priv fields. This fix restructures the code to limit the lock holds in stub_probe() and stub_disconnect(). stub_probe(): [15217.927028] BUG: sleeping function called from invalid context at mm/slab.h:418 [15217.927038] in_atomic(): 1, irqs_disabled(): 0, pid: 29087, name: usbip [15217.927044] 5 locks held by usbip/29087: [15217.927047] #0: 0000000091647f28 (sb_writers#6){....}, at: vfs_write+0x191/0x1c0 [15217.927062] #1: 000000008f9ba75b (&of->mutex){....}, at: kernfs_fop_write+0xf7/0x1b0 [15217.927072] #2: 00000000872e5b4b (&dev->mutex){....}, at: __device_driver_lock+0x3b/0x50 [15217.927082] #3: 00000000e74ececc (&dev->mutex){....}, at: __device_driver_lock+0x46/0x50 [15217.927090] #4: 00000000b20abbe0 (&(&busid_table[i].busid_lock)->rlock){....}, at: get_busid_priv+0x48/0x60 [usbip_host] [15217.927103] CPU: 3 PID: 29087 Comm: usbip Tainted: G W 5.1.0-rc6+ #40 [15217.927106] Hardware name: Dell Inc. OptiPlex 790/0HY9JP, BIOS A18 09/24/2013 [15217.927109] Call Trace: [15217.927118] dump_stack+0x63/0x85 [15217.927127] ___might_sleep+0xff/0x120 [15217.927133] __might_sleep+0x4a/0x80 [15217.927143] kmem_cache_alloc_trace+0x1aa/0x210 [15217.927156] stub_probe+0xe8/0x440 [usbip_host] [15217.927171] usb_probe_device+0x34/0x70 stub_disconnect(): [15279.182478] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:908 [15279.182487] in_atomic(): 1, irqs_disabled(): 0, pid: 29114, name: usbip [15279.182492] 5 locks held by usbip/29114: [15279.182494] #0: 0000000091647f28 (sb_writers#6){....}, at: vfs_write+0x191/0x1c0 [15279.182506] #1: 00000000702cf0f3 (&of->mutex){....}, at: kernfs_fop_write+0xf7/0x1b0 [15279.182514] #2: 00000000872e5b4b (&dev->mutex){....}, at: __device_driver_lock+0x3b/0x50 [15279.182522] #3: 00000000e74ececc (&dev->mutex){....}, at: __device_driver_lock+0x46/0x50 [15279.182529] #4: 00000000b20abbe0 (&(&busid_table[i].busid_lock)->rlock){....}, at: get_busid_priv+0x48/0x60 [usbip_host] [15279.182541] CPU: 0 PID: 29114 Comm: usbip Tainted: G W 5.1.0-rc6+ #40 [15279.182543] Hardware name: Dell Inc. OptiPlex 790/0HY9JP, BIOS A18 09/24/2013 [15279.182546] Call Trace: [15279.182554] dump_stack+0x63/0x85 [15279.182561] ___might_sleep+0xff/0x120 [15279.182566] __might_sleep+0x4a/0x80 [15279.182574] __mutex_lock+0x55/0x950 [15279.182582] ? get_busid_priv+0x48/0x60 [usbip_host] [15279.182587] ? reacquire_held_locks+0xec/0x1a0 [15279.182591] ? get_busid_priv+0x48/0x60 [usbip_host] [15279.182597] ? find_held_lock+0x94/0xa0 [15279.182609] mutex_lock_nested+0x1b/0x20 [15279.182614] ? mutex_lock_nested+0x1b/0x20 [15279.182618] kernfs_remove_by_name_ns+0x2a/0x90 [15279.182625] sysfs_remove_file_ns+0x15/0x20 [15279.182629] device_remove_file+0x19/0x20 [15279.182634] stub_disconnect+0x6d/0x180 [usbip_host] [15279.182643] usb_unbind_device+0x27/0x60 Signed-off-by: Shuah Khan Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/stub_dev.c | 65 +++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index c0d6ff1baa72..d094c96643d2 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -301,9 +301,17 @@ static int stub_probe(struct usb_device *udev) const char *udev_busid = dev_name(&udev->dev); struct bus_id_priv *busid_priv; int rc = 0; + char save_status; dev_dbg(&udev->dev, "Enter probe\n"); + /* Not sure if this is our device. Allocate here to avoid + * calling alloc while holding busid_table lock. + */ + sdev = stub_device_alloc(udev); + if (!sdev) + return -ENOMEM; + /* check we should claim or not by busid_table */ busid_priv = get_busid_priv(udev_busid); if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) || @@ -318,14 +326,14 @@ static int stub_probe(struct usb_device *udev) * See driver_probe_device() in driver/base/dd.c */ rc = -ENODEV; - goto call_put_busid_priv; + goto sdev_free; } if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) { dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n", udev_busid); rc = -ENODEV; - goto call_put_busid_priv; + goto sdev_free; } if (!strcmp(udev->bus->bus_name, "vhci_hcd")) { @@ -334,15 +342,9 @@ static int stub_probe(struct usb_device *udev) udev_busid); rc = -ENODEV; - goto call_put_busid_priv; + goto sdev_free; } - /* ok, this is my device */ - sdev = stub_device_alloc(udev); - if (!sdev) { - rc = -ENOMEM; - goto call_put_busid_priv; - } dev_info(&udev->dev, "usbip-host: register new device (bus %u dev %u)\n", @@ -352,9 +354,13 @@ static int stub_probe(struct usb_device *udev) /* set private data to usb_device */ dev_set_drvdata(&udev->dev, sdev); + busid_priv->sdev = sdev; busid_priv->udev = udev; + save_status = busid_priv->status; + busid_priv->status = STUB_BUSID_ALLOC; + /* * Claim this hub port. * It doesn't matter what value we pass as owner @@ -367,15 +373,16 @@ static int stub_probe(struct usb_device *udev) goto err_port; } + /* release the busid_lock */ + put_busid_priv(busid_priv); + rc = stub_add_files(&udev->dev); if (rc) { dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid); goto err_files; } - busid_priv->status = STUB_BUSID_ALLOC; - rc = 0; - goto call_put_busid_priv; + return 0; err_files: usb_hub_release_port(udev->parent, udev->portnum, @@ -384,23 +391,24 @@ err_port: dev_set_drvdata(&udev->dev, NULL); usb_put_dev(udev); + /* we already have busid_priv, just lock busid_lock */ + spin_lock(&busid_priv->busid_lock); busid_priv->sdev = NULL; + busid_priv->status = save_status; +sdev_free: stub_device_free(sdev); - -call_put_busid_priv: + /* release the busid_lock */ put_busid_priv(busid_priv); + return rc; } static void shutdown_busid(struct bus_id_priv *busid_priv) { - if (busid_priv->sdev && !busid_priv->shutdown_busid) { - busid_priv->shutdown_busid = 1; - usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED); + usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED); - /* wait for the stop of the event handler */ - usbip_stop_eh(&busid_priv->sdev->ud); - } + /* wait for the stop of the event handler */ + usbip_stop_eh(&busid_priv->sdev->ud); } /* @@ -432,6 +440,9 @@ static void stub_disconnect(struct usb_device *udev) dev_set_drvdata(&udev->dev, NULL); + /* release busid_lock before call to remove device files */ + put_busid_priv(busid_priv); + /* * NOTE: rx/tx threads are invoked for each usb_device. */ @@ -442,18 +453,27 @@ static void stub_disconnect(struct usb_device *udev) (struct usb_dev_state *) udev); if (rc) { dev_dbg(&udev->dev, "unable to release port\n"); - goto call_put_busid_priv; + return; } /* If usb reset is called from event handler */ if (usbip_in_eh(current)) - goto call_put_busid_priv; + return; + + /* we already have busid_priv, just lock busid_lock */ + spin_lock(&busid_priv->busid_lock); + if (!busid_priv->shutdown_busid) + busid_priv->shutdown_busid = 1; + /* release busid_lock */ + put_busid_priv(busid_priv); /* shutdown the current connection */ shutdown_busid(busid_priv); usb_put_dev(sdev->udev); + /* we already have busid_priv, just lock busid_lock */ + spin_lock(&busid_priv->busid_lock); /* free sdev */ busid_priv->sdev = NULL; stub_device_free(sdev); @@ -462,6 +482,7 @@ static void stub_disconnect(struct usb_device *udev) busid_priv->status = STUB_BUSID_ADDED; call_put_busid_priv: + /* release busid_lock */ put_busid_priv(busid_priv); } -- cgit v1.2.3 From 3864d33943b4a76c6e64616280e98d2410b1190f Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 9 May 2019 11:30:58 +0200 Subject: USB: rio500: refuse more than one device at a time This driver is using a global variable. It cannot handle more than one device at a time. The issue has been existing since the dawn of the driver. Signed-off-by: Oliver Neukum Reported-by: syzbot+35f04d136fc975a70da4@syzkaller.appspotmail.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/rio500.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 7b9adeb3e7aa..1d397d93d127 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -447,15 +447,23 @@ static int probe_rio(struct usb_interface *intf, { struct usb_device *dev = interface_to_usbdev(intf); struct rio_usb_data *rio = &rio_instance; - int retval; + int retval = 0; - dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum); + mutex_lock(&rio500_mutex); + if (rio->present) { + dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum); + retval = -EBUSY; + goto bail_out; + } else { + dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum); + } retval = usb_register_dev(intf, &usb_rio_class); if (retval) { dev_err(&dev->dev, "Not able to get a minor for this device.\n"); - return -ENOMEM; + retval = -ENOMEM; + goto bail_out; } rio->rio_dev = dev; @@ -464,7 +472,8 @@ static int probe_rio(struct usb_interface *intf, dev_err(&dev->dev, "probe_rio: Not enough memory for the output buffer\n"); usb_deregister_dev(intf, &usb_rio_class); - return -ENOMEM; + retval = -ENOMEM; + goto bail_out; } dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf); @@ -473,7 +482,8 @@ static int probe_rio(struct usb_interface *intf, "probe_rio: Not enough memory for the input buffer\n"); usb_deregister_dev(intf, &usb_rio_class); kfree(rio->obuf); - return -ENOMEM; + retval = -ENOMEM; + goto bail_out; } dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf); @@ -481,8 +491,10 @@ static int probe_rio(struct usb_interface *intf, usb_set_intfdata (intf, rio); rio->present = 1; +bail_out: + mutex_unlock(&rio500_mutex); - return 0; + return retval; } static void disconnect_rio(struct usb_interface *intf) -- cgit v1.2.3 From e0feb73428b69322dd5caae90b0207de369b5575 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 9 May 2019 11:30:59 +0200 Subject: USB: rio500: fix memory leak in close after disconnect If a disconnected device is closed, rio_close() must free the buffers. Signed-off-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/rio500.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 1d397d93d127..a32d61a79ab8 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -86,9 +86,22 @@ static int close_rio(struct inode *inode, struct file *file) { struct rio_usb_data *rio = &rio_instance; - rio->isopen = 0; + /* against disconnect() */ + mutex_lock(&rio500_mutex); + mutex_lock(&(rio->lock)); - dev_info(&rio->rio_dev->dev, "Rio closed.\n"); + rio->isopen = 0; + if (!rio->present) { + /* cleanup has been delayed */ + kfree(rio->ibuf); + kfree(rio->obuf); + rio->ibuf = NULL; + rio->obuf = NULL; + } else { + dev_info(&rio->rio_dev->dev, "Rio closed.\n"); + } + mutex_unlock(&(rio->lock)); + mutex_unlock(&rio500_mutex); return 0; } -- cgit v1.2.3 From d710734b06770814de2bfa2819420fb5df7f3a81 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 9 May 2019 11:31:00 +0200 Subject: USB: rio500: simplify locking Admitting that there can be only one device allows us to drop any pretense about locking one device or a table of devices. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/rio500.c | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index a32d61a79ab8..27e9c78a791e 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -51,7 +51,6 @@ struct rio_usb_data { char *obuf, *ibuf; /* transfer buffers */ char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ wait_queue_head_t wait_q; /* for timeouts */ - struct mutex lock; /* general race avoidance */ }; static DEFINE_MUTEX(rio500_mutex); @@ -63,10 +62,8 @@ static int open_rio(struct inode *inode, struct file *file) /* against disconnect() */ mutex_lock(&rio500_mutex); - mutex_lock(&(rio->lock)); if (rio->isopen || !rio->present) { - mutex_unlock(&(rio->lock)); mutex_unlock(&rio500_mutex); return -EBUSY; } @@ -74,7 +71,6 @@ static int open_rio(struct inode *inode, struct file *file) init_waitqueue_head(&rio->wait_q); - mutex_unlock(&(rio->lock)); dev_info(&rio->rio_dev->dev, "Rio opened.\n"); mutex_unlock(&rio500_mutex); @@ -88,7 +84,6 @@ static int close_rio(struct inode *inode, struct file *file) /* against disconnect() */ mutex_lock(&rio500_mutex); - mutex_lock(&(rio->lock)); rio->isopen = 0; if (!rio->present) { @@ -100,7 +95,6 @@ static int close_rio(struct inode *inode, struct file *file) } else { dev_info(&rio->rio_dev->dev, "Rio closed.\n"); } - mutex_unlock(&(rio->lock)); mutex_unlock(&rio500_mutex); return 0; } @@ -115,7 +109,7 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) int retries; int retval=0; - mutex_lock(&(rio->lock)); + mutex_lock(&rio500_mutex); /* Sanity check to make sure rio is connected, powered, etc */ if (rio->present == 0 || rio->rio_dev == NULL) { retval = -ENODEV; @@ -259,7 +253,7 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) err_out: - mutex_unlock(&(rio->lock)); + mutex_unlock(&rio500_mutex); return retval;